[GRASS-dev] Using a dynamic text in module header for parser

Blumentrath, Stefan Stefan.Blumentrath at nina.no
Mon Oct 19 02:47:49 PDT 2015


Hi Anna and Michel,

Thanks for looking into this and sorry for my late response.

Anna, I assume you refer to this ticket:
https://trac.osgeo.org/grass/ticket/1982
Also in my case os.chdir() did the trick.

I had both environment variables (GRASS_ADDON_PATH and GRASS_ADDON_BASE) defined, and that did not help (though I have to admit that I cannot tell for sure if the environment is passed to the execution of the "inner" python script properly. I also tried writing out an additional batch script on windows, but that did not change anything either...

Unfortunately, Michels script did not work for me on Windows (line script=file(module,'r').read() threw an error (plus some more further down the road)).

The script below works on Windows (at least my installation), though it gives me a pop-up window asking for the proper program to execute the specified file in the command. The pop-up can be closed and then the script continues as desired...

I hope you don`t mind that I open an enhancement request for this. I saw that the "checker" structure member in the parser executes a routine (see: https://grass.osgeo.org/programming7/gislib_cmdline_parsing.html#Complete_Structure_Members_Table). This is actually what I was thinking about here (If I don`t misunderstand how It works), so I hope the "checker"  solution could be re-purposed in this direction...?

Kind regards
Stefan

Windows solution:

#!/usr/bin/env python
# -*- coding: utf-8 -*- import os
import stat
import tempfile
import subprocess
import grass.script as grass
from os import getenv


answer = grass.mapsets(search_path = True)
available_mapsets = grass.mapsets()

#print str(','.join(grass.mapsets()))
#print str(','.join(answer))

with tempfile.NamedTemporaryFile(dir=os.path.join(getenv('GRASS_ADDON_BASE'), 'scripts'), suffix='.py', delete = False) as s:
    s.write('''#!/usr/bin/env python
# -*- coding: utf-8 -*-
############################################################################
#
# MODULE:    g.searchpath
# AUTHOR(S):    Stefan Blumentrath
#
# PURPOSE:    Graphically modify search path of the current mapset.
#           The search path is a list of other mapsets which will be searched
#           for maps by default)
# COPYRIGHT:    (C) 2011-2014, Stefan Blumentrath and the GRASS Development Team
#
#        This program is free software under the GNU General Public
#        License (version 2). Read the file COPYING that comes with GRASS
#        for details.
#
#############################################################################

#%module
#% description: Graphically modify search path of the current mapset.
#% keyword: mapset access management
#% keyword: general
#%end

#%option
#% key: mapset
#% type: string
#% description: Check a mapset to make it accessible, uncheck it to hide it
#% required: no
#% multiple: yes
#% options: ''' + str(','.join(grass.mapsets())) + '''
#% answer: ''' + str(','.join(answer)) + '''
#%end

import grass.script as grass

def main():

    # Get the options
    input = options["mapset"]

    grass.run_command('g.mapsets', mapset = input, operation = 'set')

if __name__ == "__main__":
    options, flags = grass.parser()
    main()
''')

os.chdir(os.path.join(getenv('GRASS_ADDON_BASE'), 'scripts'))

startcmd = 'python ' + s.name + ' --ui'

# set permissions
os.chmod(s.name, os.stat(s.name).st_mode | stat.S_IEXEC)

subprocess.call(startcmd)
os.remove(s.name)


From: grass-dev [mailto:grass-dev-bounces at lists.osgeo.org] On Behalf Of Anna Petrášová
Sent: 13. oktober 2015 15:51
To: Michel Wortmann <wortmann at pik-potsdam.de>
Cc: GRASS-dev <grass-dev at lists.osgeo.org>
Subject: Re: [GRASS-dev] Using a dynamic text in module header for parser

Hi,

you can look how Layer manager launches scripts:
https://trac.osgeo.org/grass/browser/grass/trunk/gui/wxpython/lmgr/frame.py#L841, I think it requires setting the GRASS_ADDON_PATH

I remember this problem, maybe it's in parser. There might be a ticket already, but I am not sure. If you can't find anything related, please create a ticket.

On Tue, Oct 13, 2015 at 9:33 AM, Michel Wortmann <wortmann at pik-potsdam.de<mailto:wortmann at pik-potsdam.de>> wrote:
Hi Stefan,
I have been meaning to implement something like this too and got your example to work with the additional step of setting the environment variable GRASS_ADDON_PATH (and under unix setting the permissions). Here is my example just parsing the first mapset it finds:

import os, tempfile, stat
import grass.script as grass

module = 'subbasins.py'

if __name__=='__main__':
    answer = grass.mapsets(search_path = True)
    available_mapsets = grass.mapsets()

    script=file(module,'r').read()

    with tempfile.NamedTemporaryFile(delete = False) as s:
        s.write('''#!/usr/bin/env python
# -*- coding: utf-8 -*-

{script}

#%Option
#% key:{option}
#%end

'''.format(script=script,option=available_mapsets[0].lower()))

    startcmd = 'python '+s.name<http://s.name>
    # set env variable
    aoev='GRASS_ADDON_PATH'
    tmpdir = os.path.basename(s.name<http://s.name>)
    if aoev in os.environ:
        os.environ[aoev]=[tmpdir]+os.environ[aoev]
    else:
        os.environ[aoev]=[tmpdir]
    # set permissions
    os.chmod(s.name<http://s.name>, os.stat(s.name<http://s.name>).st_mode | stat.S_IEXEC)
    # start module
    os.system(startcmd)
    os.remove(s.name<http://s.name>)

Let me know if this works under Windows too.
Michel
On 10/12/2015 12:55 PM, Blumentrath, Stefan wrote:
Hi again,

Now I found out that the parser section in the inner python script was not formated properly.

However, when I now call the inner script with '--ui' I get an error:
Unable to fetch interface description for command 'tmpjksdfjiol'

Details:
Try to set up GRASS_ADDON_PATH or GRASS_ADDON_BASE variable.

It was neither possible to run the script using grass.run_command() (on Windows).

Cheers
Stefan



From: grass-dev [mailto:grass-dev-bounces at lists.osgeo.org] On Behalf Of Blumentrath, Stefan
Sent: 12. oktober 2015 11:36
To: GRASS developers list (grass-dev at lists.osgeo.org<mailto:grass-dev at lists.osgeo.org>) <grass-dev at lists.osgeo.org><mailto:grass-dev at lists.osgeo.org>
Subject: [GRASS-dev] Using a dynamic text in module header for parser

Hi,

I would like to fill:
#% options:
and
#% answer
in a parser option for a python script dynamically.  In particular I want to have tickboxes for available mapsets in the module GUI...

Meaning something like this  (but less complex / not interactive):
http://permalink.gmane.org/gmane.comp.gis.grass.gui/667
My amateur programming skills do unfortunately not allow me to really understand how to accomplish what Glynn describes in the post above...

I tried to generate and run a temporary python script from within my script like this:
def main():

    answer = grass.mapsets(search_path = True)
    available_mapsets = str(grass.mapsets())

    with tempfile.NamedTemporaryFile(delete = False) as s:
        s.write('''    #!/usr/bin/env python
# -*- coding: utf-8 -*-
# Here comes the full module with header for the parser
#% options: ''' + str(','.join(available_mapsets))
...
''')
    startcmd = 'python ' + s.name<http://s.name>
    os.system(startcmd)
    os.remove(s.name<http://s.name>)

But that way the GUI never starts, when I call the outer script from GRASS and it seems that option never get parsed...

Any hints how to proceed?

Thanks for helping in advance.

Stefan




_______________________________________________

grass-dev mailing list

grass-dev at lists.osgeo.org<mailto:grass-dev at lists.osgeo.org>

http://lists.osgeo.org/mailman/listinfo/grass-dev


_______________________________________________
grass-dev mailing list
grass-dev at lists.osgeo.org<mailto:grass-dev at lists.osgeo.org>
http://lists.osgeo.org/mailman/listinfo/grass-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/grass-dev/attachments/20151019/d2c72737/attachment-0001.html>


More information about the grass-dev mailing list