Repository: weecology/retriever

Issue:
retriever ls -v command does not work 
While executing the ```retriever ls -v``` command, output is incorrect due to ```IndexError: list index out of range```.
Possible reasons are that some dataset json files have no license field or the license field is empty.
```
aakash01@aakash01-G3-3579:~/Desktop/gsoc/retriever (main)$ retriever ls -v
Offline datasets : 251

1. Abalone Age and Size Data
 abalone-age
[]
Database to aid in the prediction of the age of an Abalone given physical measurements
None
Lichman, M. (2013). UCI Machine Learning Repository [http://archive.ics.uci.edu/ml]. Irvine, CA: University of California, School of Information and Computer Science.

2. Long term limnological measures in Acton Lake, database, 1992-2017
 acton-lake
['lake', 'stream', 'nutrients', 'nitrogen', 'phosphorus', 'chlorophyll', 'LTREB', 'long-term', 'ecosystem', 'ammonium-nitrogen', 'nitrate-N', 'oxygen', 'carbon']
Long-term data collected from Acton Lake and its inflow streams, on a suite of physical, chemical and biological variables investigating how Acton Lake, responds to changes in ecosystem subsidies of detritus (sediments) and nutrients.
None
Michael J Vanni, Maria J Gonzalez, and William H Renwick. 2019. Long term limnological measures in Acton Lake, a southwest Ohio reservoir, and its inflow streams: 1992-2017. Environmental Data Initiative.

Traceback (most recent call last):
  File "/home/aakash01/anaconda3/envs/gsoc-dev/bin/retriever", line 8, in <module>
    sys.exit(main())
  File "/home/aakash01/anaconda3/envs/gsoc-dev/lib/python3.7/site-packages/retriever/__main__.py", line 150, in main
    licenses=str(script.licenses[0]['name']),
IndexError: list index out of range
```


Discussion:
Fixing this issue myself.

Resolving patch:
diff --git a/retriever/__main__.py b/retriever/__main__.py
--- a/retriever/__main__.py
+++ b/retriever/__main__.py
@@ -6,7 +6,7 @@
 import sys
 
 from retriever.engines import engine_list, choose_engine
-from retriever.lib.datasets import datasets, dataset_names, license
+from retriever.lib.datasets import datasets, dataset_names, license, dataset_verbose_list
 from retriever.lib.defaults import sample_script, CITATION, SCRIPT_SEARCH_PATHS, LICENSE
 from retriever.lib.engine_tools import reset_retriever
 from retriever.lib.get_opts import parser
@@ -26,7 +26,6 @@ def main():
     else:
         # otherwise, parse them
         args = parser.parse_args()
-
         reset_or_update = args.command in ["reset", "update"]
         if (not reset_or_update and not os.path.isdir(SCRIPT_SEARCH_PATHS[1]) and not [
                 f for f in os.listdir(SCRIPT_SEARCH_PATHS[-1])
@@ -86,7 +85,6 @@ def main():
             f = open(args.filename, 'w')
             f.write(sample_script)
             f.close()
-
             return
 
         if args.command == 'reset':
@@ -123,47 +121,8 @@ def main():
                       "https://github.com/weecology/retriever-recipes.")
 
             elif isinstance(args.v, list):
-                online_scripts = []
-                if args.v:
-                    try:
-                        all_scripts = [get_script(dataset) for dataset in args.v]
-                    except KeyError:
-                        all_scripts = []
-                        print("Dataset(s) is not found.")
-                else:
-                    scripts = datasets()
-                    all_scripts = scripts['offline']
-                    online_scripts = scripts['online']
-                count = 1
-                if not args.v:
-                    print("Offline datasets : {}\n".format(len(all_scripts)))
-                for script in all_scripts:
-                    print("{count}. {title}\n {name}\n"
-                          "{keywords}\n{description}\n"
-                          "{licenses}\n{citation}\n"
-                          "".format(
-                              count=count,
-                              title=script.title,
-                              name=script.name,
-                              keywords=script.keywords,
-                              description=script.description,
-                              licenses=str(script.licenses[0]['name']),
-                              citation=script.citation,
-                          ))
-                    count += 1
-
-                count = 1
-                offline_scripts = [script.name for script in all_scripts]
-                set_online_scripts = []
-                for script in online_scripts:
-                    if script in offline_scripts:
-                        continue
-                    set_online_scripts.append(script)
-                if not args.v:
-                    print("Online datasets : {}\n".format(len(set_online_scripts)))
-                for script in set_online_scripts:
-                    print("{count}. {name}".format(count=count, name=script))
-                    count += 1
+                dataset_verbose_list(args.v)
+
             else:
                 param_licenses = args.l if args.l else None
                 keywords = args.k if args.k else None
@@ -178,14 +137,16 @@ def main():
                     print(offline_mesg.format(len(searched_scripts['offline'])))
                     count = 1
                     for script in searched_scripts['offline']:
-                        print("{count}. {title}\n{name}\n"
-                              "{keywords}\n{licenses}\n".format(
-                                  count=count,
-                                  title=script.title,
-                                  name=script.name,
-                                  keywords=script.keywords,
-                                  licenses=str(script.licenses[0]['name']),
-                              ))
+                        print(
+                            "{count}. {title}\n{name}\n"
+                            "{keywords}\n{licenses}\n".format(
+                                count=count,
+                                title=script.title,
+                                name=script.name,
+                                keywords=script.keywords,
+                                licenses=str(script.licenses[0]['name']) if
+                                script.licenses and len(script.licenses) else str('N/A'),
+                            ))
                         count += 1
 
                     count = 1
diff --git a/retriever/lib/datasets.py b/retriever/lib/datasets.py
--- a/retriever/lib/datasets.py
+++ b/retriever/lib/datasets.py
@@ -65,10 +65,45 @@ def dataset_names():
 
 def license(dataset):
     """Get the license for a dataset."""
-    return get_script(dataset).licenses[0]['name']
+    script = get_script(dataset)
+    if script.licenses and len(script.licenses):
+        return script.licenses[0]['name']
+    else:
+        return str('N/A')
 
 
 def dataset_licenses():
     """Return set with all available licenses."""
-    license_values = [str(script.licenses[0]['name']).lower() for script in SCRIPT_LIST()]
+    license_values = [
+        str(script.licenses[0]['name']).lower()
+        for script in SCRIPT_LIST()
+        if script.licenses
+    ]
     return set(license_values)
+
+
+def dataset_verbose_list(script_names: list):
+    """Returns the verbose list of the specified dataset(s)"""
+    if isinstance(script_names, list):
+        try:
+            scripts = [get_script(dataset) for dataset in script_names]
+        except KeyError:
+            scripts = []
+            print("Dataset(s) is not found")
+
+        count = 1
+        for script in scripts:
+            print("{count}. {title}\nDataset Name: {name}\n"
+                  "Keywords: {keywords}\nDescription: {description}\n"
+                  "Licenses: {licenses}\nCitation: {citation}\n"
+                  "".format(
+                      count=count,
+                      title=script.title,
+                      name=script.name,
+                      keywords=script.keywords,
+                      description=script.description,
+                      licenses=str(script.licenses[0]['name'])
+                      if script.licenses and len(script.licenses) else str('N/A'),
+                      citation=script.citation,
+                  ))
+            count += 1


Test patch: