Skip to content

Commit

Permalink
refactors the query string search plugin + pagination
Browse files Browse the repository at this point in the history
- The RestoSearch plugin is dismissed and merged with its parent to allow
better generalization of the QueryStringSearch plugin.
- A mecanism that enables walking through all the search results of a
provider is also added (see #58).
- An enhancement on how the free text search configuration parameter is
resolved is also introduced (it may be of interest to make this
mechanism the default way of handling search parameters to enable
searching by an arbitrary number of metadata)
  • Loading branch information
Adrien Oyono committed Feb 11, 2019
1 parent f90bdf6 commit 1751bf2
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 156 deletions.
4 changes: 0 additions & 4 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,6 @@ Search Plugins
:show-inheritance:
:undoc-members:

.. autoclass:: eodag.plugins.search.qssearch.RestoSearch
:show-inheritance:
:undoc-members:

.. autoclass:: eodag.plugins.search.qssearch.AwsSearch
:show-inheritance:
:undoc-members:
Expand Down
339 changes: 215 additions & 124 deletions eodag/plugins/search/qssearch.py

Large diffs are not rendered by default.

81 changes: 56 additions & 25 deletions eodag/resources/providers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
search: !plugin
type: AwsSearch
api_endpoint: 'http://finder.eocloud.eu/resto/api/collections/{collection}/search.json'
pagination:
next_page_url_tpl: '{url}?{search}&maxRecords={items_per_page}&page={page}'
total_items_nb_key_path: '$.properties.totalResults'
metadata_mapping:
id: '$.id'
geometry:
Expand Down Expand Up @@ -108,8 +111,11 @@
collection: Pleiades
product_type: Bundle (Pan, XS)
search: !plugin
type: RestoSearch
type: QueryStringSearch
api_endpoint: 'https://theia-landsat.cnes.fr/resto/api/collections/{collection}/search.json'
pagination:
next_page_url_tpl: '{url}?{search}&maxRecords={items_per_page}&page={page}'
total_items_nb_key_path: '$.properties.totalResults'
metadata_mapping:
id: '$.id'
geometry:
Expand Down Expand Up @@ -176,8 +182,11 @@
name: theia
priority: 0
search: !plugin
type: RestoSearch
type: QueryStringSearch
api_endpoint: 'https://theia.cnes.fr/atdistrib/resto2/api/collections/{collection}/search.json'
pagination:
next_page_url_tpl: '{url}?{search}&maxRecords={items_per_page}&page={page}'
total_items_nb_key_path: '$.properties.totalResults'
metadata_mapping:
id: '$.id'
geometry:
Expand Down Expand Up @@ -229,8 +238,11 @@
name: peps
priority: 1
search: !plugin
type: RestoSearch
type: QueryStringSearch
api_endpoint: 'https://peps.cnes.fr/resto/api/collections/{collection}/search.json'
pagination:
next_page_url_tpl: '{url}?{search}&maxRecords={items_per_page}&page={page}'
total_items_nb_key_path: '$.properties.totalResults'
metadata_mapping:
id: '$.id'
geometry:
Expand Down Expand Up @@ -339,10 +351,14 @@
S3_SRA_A_BS:
product_type: SR_1_SRA_A_
search: !plugin
type: RestoSearch
type: QueryStringSearch
api_endpoint: 'https://sobloo.eu/api/v1/services/explore/explore/{collection}/_geosearch'
collection: catalog
result_type: 'json'
pagination:
count_endpoint: 'https://sobloo.eu/api/v1/services/explore/explore/{collection}/_count'
next_page_url_tpl: '{url}?{search}&size={items_per_page}&from={page}'
total_items_nb_key_path: '$.totalnb'
metadata_mapping:
id: '$.properties.uid'
geometry:
Expand Down Expand Up @@ -384,8 +400,11 @@
name: creodias
priority: 0
search: !plugin
type: RestoSearch
type: QueryStringSearch
api_endpoint: 'https://finder.creodias.eu/resto/api/collections/{collection}/search.json'
pagination:
next_page_url_tpl: '{url}?{search}&maxRecords={items_per_page}&page={page}'
total_items_nb_key_path: '$.properties.totalResults'
metadata_mapping:
id: '$.id'
geometry:
Expand Down Expand Up @@ -491,18 +510,24 @@
name: mundi
priority: 0
search: !plugin
type: RestoSearch
type: QueryStringSearch
api_endpoint: 'https://mundiwebservices.com/acdc/catalog/proxy/search/{collection}/opensearch'
result_type: 'xml'
result_entry: '//ns:entry'
literal_search_params:
format: atom
relation: intersects
free_text_search_param: 'q'
free_text_search_operations:
AND:
- 'sensingStartDate:[{startTimeFromAscendingNode}Z TO *]'
- 'sensingStopDate:[* TO {completionTimeFromAscendingNode}Z]'
q:
union: ' AND '
wrapper: '({})'
operations:
AND:
- 'sensingStartDate:[{startTimeFromAscendingNode}Z TO *]'
- 'sensingStopDate:[* TO {completionTimeFromAscendingNode}Z]'
pagination:
next_page_url_tpl: '{url}?{search}&maxRecords={items_per_page}&startIndex={page}'
total_items_nb_key_path: '//os:totalResults/text()'
metadata_mapping:
id: 'ns:id/text()'
abstract: 'ns:summary/text()'
Expand Down Expand Up @@ -610,31 +635,37 @@
search: !plugin
type: ODataV4Search
api_endpoint: 'https://catalogue.onda-dias.eu/dias-catalogue/Products'
pagination:
count_endpoint: 'https://catalogue.onda-dias.eu/dias-catalogue/Products/$count'
next_page_url_tpl: '{url}?{search}&$top={items_per_page}&$skip={skip}'
results_entry: 'value'
literal_search_params:
$format: json
free_text_search_operations:
$search:
union: ' OR '
wrapper: '"{}"'
operations:
AND:
- 'footprint:"Intersects({geometry#to_wkt})"'
- 'productType:{productType}'
- 'cloudCoverPercentage:[0 TO {cloudCover}]'
- 'beginPosition:[{startTimeFromAscendingNode}Z TO *]'
- 'endPosition:[* TO {completionTimeFromAscendingNode}Z]'
metadata_mapping:
id: '$.id'
geometry:
- 'footprint:"Intersects({geometry#to_wkt})"'
- '$.footprint'
productType:
- "productType:{productType}"
- '$.productType'
geometry: '$.footprint'
productType: '$.productType'
platform: '$.platformName'
platformSerialIdentifier: '$.platformSerialIdentifier'
instrument: '$.instrumentName'
processingLevel: '$.processingLevel'
title: '$.filename'
orbitNumber: '$.orbitNumber'
orbitDirection: '$.orbitDirection'
cloudCover:
- 'cloudCoverPercentage:[0 TO {cloudCover}]'
- '$.cloudCoverPercentage'
startTimeFromAscendingNode:
- 'beginPosition:[{startTimeFromAscendingNode}Z TO *]'
- '$.beginPosition'
completionTimeFromAscendingNode:
- 'endPosition:[* TO {completionTimeFromAscendingNode}Z]'
- '$.endPosition'
cloudCover: '$.cloudCoverPercentage'
startTimeFromAscendingNode: '$.beginPosition'
completionTimeFromAscendingNode: '$.endPosition'
sensorMode: '$.sensorOperationalMode'
quicklook: '$.quicklook'
downloadLink: '%(base_uri)s({id})/$value'
Expand Down
4 changes: 2 additions & 2 deletions eodag/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
from urlparse import urljoin, urlparse, parse_qs, urlunparse # noqa

try: # PY3
from urllib.parse import urlencode # noqa
from urllib.parse import urlencode, quote # noqa
except ImportError: # PY2
from urllib import urlencode # noqa
from urllib import urlencode, quote # noqa


class RequestsTokenAuth(AuthBase):
Expand Down
5 changes: 5 additions & 0 deletions eodag/utils/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,8 @@ class AuthenticationError(Exception):

class DownloadError(Exception):
"""An error indicating something wrong with the download process"""


class RequestError(Exception):
"""An error indicating that a HTTP request has failed. Usually eodag functions and methods should catch and skip
this"""
2 changes: 1 addition & 1 deletion eodag/utils/metadata_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def get_field(self, field_name, args, kwargs):
def convert_field(self, value, conversion):
# Do custom conversion if any (see get_field)
if self.custom_converter is not None:
converted = self.custom_converter(value)
converted = self.custom_converter(value) if value is not None else ''
# Clear this state variable in case the same converter is used to resolve other named arguments
self.custom_converter = None
return converted
Expand Down

0 comments on commit 1751bf2

Please sign in to comment.