[GRASS-SVN] r72279 - grass-addons/grass7/raster/r.sentinel/r.sentinel.download

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Feb 26 02:13:00 PST 2018


Author: martinl
Date: 2018-02-26 02:13:00 -0800 (Mon, 26 Feb 2018)
New Revision: 72279

Modified:
   grass-addons/grass7/raster/r.sentinel/r.sentinel.download/r.sentinel.download.html
   grass-addons/grass7/raster/r.sentinel/r.sentinel.download/r.sentinel.download.py
Log:
r.sentinel.download: user, password changed to settings option (sync with r.modis)
                     interactive prompt also supported
                     i18n
                     manual updated


Modified: grass-addons/grass7/raster/r.sentinel/r.sentinel.download/r.sentinel.download.html
===================================================================
--- grass-addons/grass7/raster/r.sentinel/r.sentinel.download/r.sentinel.download.html	2018-02-25 15:28:44 UTC (rev 72278)
+++ grass-addons/grass7/raster/r.sentinel/r.sentinel.download/r.sentinel.download.html	2018-02-26 10:13:00 UTC (rev 72279)
@@ -3,13 +3,34 @@
 Hub</a>.
 
 <p>
-To connect Copernicus Open Access Hub a <b>user</b>
-and <b>password</b> are required,
+To connect Copernicus Open Access Hub a <em>user</em>
+and <em>password</em> are required,
 see <a href="https://scihub.copernicus.eu/dhus/#/self-registration">Register
 new account</a> page for signing up.
 
+<p><em>r.sentinel.download</em> reads user credentials
+from <b>settings</b> file. The file must contain at least two lines:
+
+<div class="code"><pre>
+myusername
+mypassword
+</pre></div>
+
+Optionally on third line custom API URL can be defined. Note that
+empty lines in settings file are silently skipped.
+
 <h2>NOTES</h2>
 
+<p>User credentials can be also defined interactively
+when <b>settings=-</b> is given. Note that interactive prompt does not
+work in GUI.
+
+<div class="code"><pre>
+Insert username: myusername
+Insert password: 
+Insert API URL (leave empty for https://scihub.copernicus.eu/dhus):
+</pre></div>
+
 <p>
 By default Sentinel products are sorted by <i>cloudcoverpercentage</i>
 and <i>ingestiondate</i> (see <b>sort</b> option). By default,
@@ -43,7 +64,7 @@
 Find S2MSI1C products in last 60 days covering current computation region extent.
 
 <div class="code"><pre>
-r.sentinel.download -l user=myusername password=mypassword
+r.sentinel.download -l settings=sentinel.txt
 
 1 Sentinel product(s) found
 ae1c33ec-aa33-4303-a525-9e6481709614 2017-12-08T10:23:59Z 18% S2MSI1C
@@ -52,7 +73,7 @@
 Find all S2MSI2Ap products in 2017.
 
 <div class="code"><pre>
-r.sentinel.download -l user=myusername password=mypassword producttype=S2MSI2Ap start=2017-01-01 end=2017-12-31
+r.sentinel.download -l settings=sentinel.txt producttype=S2MSI2Ap start=2017-01-01 end=2017-12-31
     
 7 Sentinel product(s) found
 e5df8b4f-a4c6-47bd-88f3-e16b7540cc7a 2017-05-27T10:20:31Z  2% S2MSI2Ap
@@ -67,7 +88,7 @@
 Sort products by <b>ingestiondate</b>, limit cloud coverage to 5% per scene.
 
 <div class="code"><pre>
-r.sentinel.download -l user=myusername password=mypassword producttype=S2MSI2Ap start=2017-01-01 end=2017-12-31 sort=ingestiondate order=desc clouds=5
+r.sentinel.download -l settings=sentinel.txt producttype=S2MSI2Ap start=2017-01-01 end=2017-12-31 sort=ingestiondate order=desc clouds=5
 
 3 Sentinel product(s) found
 9a6bc289-98e9-4489-84eb-1aac95aaa056 2017-08-15T10:20:21Z  3% S2MSI2Ap
@@ -78,7 +99,7 @@
 Create vector map with <b>footprints</b>.
 
 <div class="code"><pre>
-r.sentinel.download -l user=myusername password=mypassword producttype=S2MSI2Ap start=2017-01-01 end=2017-12-31 footprints=ft
+r.sentinel.download -l settings=sentinel.txt producttype=S2MSI2Ap start=2017-01-01 end=2017-12-31 footprints=ft
 </pre></div>
 
 <h3>Download Sentinel products</h3>
@@ -86,7 +107,7 @@
 Download first (<b>limit=1</b>) found S2MSI2Ap product into <i>data</i> directory.
 
 <div class="code"><pre>
-r.sentinel.download user=myusername password=mypassword producttype=S2MSI2Ap start=2017-01-01 end=2017-12-31 limit=1 output=data
+r.sentinel.download settings=sentinel.txt producttype=S2MSI2Ap start=2017-01-01 end=2017-12-31 limit=1 output=data
 </pre></div>
 
 Such downloaded data can be easily imported into GRASS

Modified: grass-addons/grass7/raster/r.sentinel/r.sentinel.download/r.sentinel.download.py
===================================================================
--- grass-addons/grass7/raster/r.sentinel/r.sentinel.download/r.sentinel.download.py	2018-02-25 15:28:44 UTC (rev 72278)
+++ grass-addons/grass7/raster/r.sentinel/r.sentinel.download/r.sentinel.download.py	2018-02-26 10:13:00 UTC (rev 72279)
@@ -14,7 +14,7 @@
 #
 #############################################################################
 
-#%Module
+#%module
 #% description: Downloads Sentinel data from Copernicus Open Access Hub using sentinelsat library.
 #% keyword: raster
 #% keyword: imagery
@@ -21,18 +21,11 @@
 #% keyword: sentinel
 #% keyword: download
 #%end
-#%option
-#% key: user
-#% type: string
-#% description: Username for connecting SciHub
-#% required: yes
+#%option G_OPT_F_INPUT
+#% key: settings
+#% label: Full path to settings file (user, password)
+#% description: '-' for standard input
 #%end
-#%option
-#% key: password
-#% type: string
-#% description: Password for connecting SciHub
-#% required: yes
-#%end
 #%option G_OPT_M_DIR
 #% key: output
 #% description: Name for output directory where to store downloaded Sentinel data
@@ -140,15 +133,15 @@
     )
 
 class SentinelDownloader(object):
-    def __init__(self, user, password):
+    def __init__(self, user, password, api_url='https://scihub.copernicus.eu/dhus'):
         try:
             from sentinelsat import SentinelAPI
         except ImportError as e:
-            gs.fatal("Module requires sentinelsat library: {}".format(e))
+            gs.fatal(_("Module requires sentinelsat library: {}").format(e))
         try:
             import pandas
         except ImportError as e:
-            gs.fatal("Module requires pandas library: {}".format(e))
+            gs.fatal(_("Module requires pandas library: {}").format(e))
 
         # init logger
         root = logging.getLogger()
@@ -157,8 +150,8 @@
         ))
 
         # connect SciHub via API
-        self._api = SentinelAPI(options['user'], options['password'],
-                                api_url='https://scihub.copernicus.eu/dhus'
+        self._api = SentinelAPI(user, password,
+                                api_url=api_url
         )
 
         self._products_df_sorted = None
@@ -187,7 +180,7 @@
         )
         products_df = self._api.to_dataframe(products)
         if len(products_df) < 1:
-            gs.message('No product found')
+            gs.message(_('No product found'))
             return
 
         # sort and limit to first sorted product
@@ -200,7 +193,7 @@
         if limit:
             self._products_df_sorted = self._products_df_sorted.head(int(limit))
 
-        gs.message('{} Sentinel product(s) found'.format(len(self._products_df_sorted)))
+        gs.message(_('{} Sentinel product(s) found').format(len(self._products_df_sorted)))
 
     def list(self):
         if self._products_df_sorted is None:
@@ -220,7 +213,7 @@
 
         if not os.path.exists(output):
             os.makedirs(output)
-        gs.message('Downloading data into <{}>...'.format(output))
+        gs.message(_('Downloading data into <{}>...').format(output))
         for idx in range(len(self._products_df_sorted)):
             gs.message('{} -> {}.SAFE'.format(
                 self._products_df_sorted['uuid'][idx],
@@ -243,9 +236,9 @@
         try:
             from osgeo import ogr, osr
         except ImportError as e:
-            gs.fatal("Option <footprints> requires GDAL library: {}".format(e))
+            gs.fatal(_("Option <footprints> requires GDAL library: {}").format(e))
 
-        gs.message("Writing footprints into <{}>...".format(map_name))
+        gs.message(_("Writing footprints into <{}>...").format(map_name))
         driver = ogr.GetDriverByName("GPKG")
         tmp_name = gs.tempfile() + '.gpkg'
         data_source = driver.CreateDataSource(tmp_name)
@@ -287,20 +280,50 @@
         )
 
 def main():
+    user = password = None
+    api_url='https://scihub.copernicus.eu/dhus'
+
+    if options['settings'] == '-':
+        # stdin
+        import getpass
+        user = raw_input(_('Insert username: '))
+        password = getpass.getpass(_('Insert password: '))
+        url = raw_input(_('Insert API URL (leave empty for {}): ').format(api_url))
+        if url:
+            api_url = url
+    else:
+        try:
+            with open(options['settings'], 'r') as fd:
+                lines = filter(None, (line.rstrip() for line in fd)) # non-blank lines only
+                if len(lines) < 2:
+                    gs.fatal(_("Invalid settings file"))
+                user = lines[0].strip()
+                password = lines[1].strip()
+                if len(lines) > 2:
+                    api_url = lines[2].strip()
+        except IOError as e:
+            gs.fatal(_("Unable to open settings file: {}").format(e))
+
+    if user is None or password is None:
+        gs.fatal(_("No user or password given"))
+
     map_box = get_aoi_box(options['map'])
 
-    downloader = SentinelDownloader(options['user'], options['password'])
+    try:
+        downloader = SentinelDownloader(user, password, api_url)
 
-    downloader.filter(area=map_box,
-                      area_relation=options['area_relation'],
-                      clouds=options['clouds'],
-                      producttype=options['producttype'],
-                      limit=options['limit'],
-                      start=options['start'],
-                      end=options['end'],
-                      sortby=options['sort'].split(','),
-                      asc=options['order'] == 'asc'
-    )
+        downloader.filter(area=map_box,
+                          area_relation=options['area_relation'],
+                          clouds=options['clouds'],
+                          producttype=options['producttype'],
+                          limit=options['limit'],
+                          start=options['start'],
+                          end=options['end'],
+                          sortby=options['sort'].split(','),
+                          asc=options['order'] == 'asc'
+        )
+    except StandardError as e:
+        gs.fatal(_('Unable to connect Copernicus Open Access Hub: {}').format(e))
 
     if options['footprints']:
         downloader.save_footprints(options['footprints'])



More information about the grass-commit mailing list