|
3 | 3 | # Authors: Tom Kralidis <tomkralidis@gmail.com> |
4 | 4 | # Angelos Tzotsos <tzotsos@gmail.com> |
5 | 5 | # |
6 | | -# Copyright (c) 2025 Tom Kralidis |
| 6 | +# Copyright (c) 2026 Tom Kralidis |
7 | 7 | # Copyright (c) 2021 Angelos Tzotsos |
8 | 8 | # |
9 | 9 | # Permission is hereby granted, free of charge, to any person |
@@ -483,6 +483,23 @@ def collection(self, headers_, args, collection='metadata:main'): |
483 | 483 | 'hreflang': self.config['server']['language'] |
484 | 484 | }] |
485 | 485 |
|
| 486 | + if collection == 'metadata:main' and 'federatedcatalogues' in self.config: |
| 487 | + LOGGER.debug('Adding federated catalogues') |
| 488 | + response['links'].append({ |
| 489 | + 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/federatedCatalogues', |
| 490 | + 'type': 'application/json', |
| 491 | + 'title': 'Federated catalogs as JSON', |
| 492 | + 'href': f"{url_base}/federatedCatalogs?f=json", |
| 493 | + 'hreflang': self.config['server']['language'] |
| 494 | + }) |
| 495 | + response['links'].append({ |
| 496 | + 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/federatedCatalogues', |
| 497 | + 'type': 'text/html', |
| 498 | + 'title': 'Federated catalogs as HTML', |
| 499 | + 'href': f"{url_base}/federatedCatalogs?f=html", |
| 500 | + 'hreflang': self.config['server']['language'] |
| 501 | + }) |
| 502 | + |
486 | 503 | return self.get_response(200, headers_, response, 'collection.html') |
487 | 504 |
|
488 | 505 | def queryables(self, headers_, args, collection='metadata:main'): |
@@ -550,7 +567,7 @@ def items(self, headers_, json_post_data, args, collection='metadata:main'): |
550 | 567 | headers_['Content-Type'] = self.get_content_type(headers_, args) |
551 | 568 |
|
552 | 569 | reserved_query_params = [ |
553 | | - 'distributed', |
| 570 | + 'distributedsearch', |
554 | 571 | 'f', |
555 | 572 | 'facets', |
556 | 573 | 'filter', |
@@ -796,19 +813,27 @@ def items(self, headers_, json_post_data, args, collection='metadata:main'): |
796 | 813 | for record in records: |
797 | 814 | response['features'].append(record2json(record, self.config['server']['url'], collection, self.mode)) |
798 | 815 |
|
799 | | - response['distributedFeatures'] = [] |
| 816 | + response['federatedSearchResults'] = {} |
800 | 817 |
|
801 | | - distributed = str2bool(args.get('distributed', False)) |
| 818 | + distributed = str2bool(args.get('distributedsearch', False)) |
802 | 819 |
|
803 | 820 | if distributed: |
804 | 821 | for fc in self.config.get('federatedcatalogues', []): |
805 | | - LOGGER.debug(f'Running distributed search against {fc}') |
806 | | - fc_url, _, fc_collection = fc.rsplit('/', 2) |
| 822 | + if fc['type'] != 'OARec': |
| 823 | + LOGGER.debug(f"Federated catalogue type {fc['type']} not supported; skipping") |
| 824 | + continue |
| 825 | + LOGGER.debug(f"Running distributed search against {fc['url']}") |
| 826 | + fc_url, _, fc_collection = fc['url'].rsplit('/', 2) |
| 827 | + response['federatedSearchResults'][fc['id']] = { |
| 828 | + 'type': 'FeatureCollection', |
| 829 | + 'features': [] |
| 830 | + } |
807 | 831 | try: |
808 | 832 | w = Records(fc_url) |
| 833 | + args.pop('distributedsearch') |
809 | 834 | fc_results = w.collection_items(fc_collection, **args) |
810 | 835 | for feature in fc_results['features']: |
811 | | - response['distributedFeatures'].append(feature) |
| 836 | + response['federatedSearchResults'][fc['id']]['features'].append(feature) |
812 | 837 | except Exception as err: |
813 | 838 | LOGGER.warning(err) |
814 | 839 |
|
@@ -946,7 +971,10 @@ def item(self, headers_, args, collection, item): |
946 | 971 |
|
947 | 972 | if distributed: |
948 | 973 | for fc in self.config.get('federatedcatalogues', []): |
949 | | - LOGGER.debug(f'Running distributed item search against {fc}') |
| 974 | + if fc['type'] != 'OARec': |
| 975 | + LOGGER.debug(f"Federated catalogue type {fc['type']} not supported; skipping") |
| 976 | + continue |
| 977 | + LOGGER.debug(f"Running distributed item search against {fc['url']}") |
950 | 978 | fc_url, _, fc_collection = fc.rsplit('/', 2) |
951 | 979 | try: |
952 | 980 | w = Records(fc_url) |
@@ -1133,18 +1161,79 @@ def get_collection_info(self, collection_name: str = 'metadata:main', |
1133 | 1161 | }] |
1134 | 1162 | } |
1135 | 1163 |
|
1136 | | - if collection_name == 'metadata:main': |
| 1164 | + return collection_info |
| 1165 | + |
| 1166 | + def federated_catalogues(self, headers_, args, collection): |
| 1167 | + """ |
| 1168 | + Provide federated catalogues |
| 1169 | +
|
| 1170 | + :param headers_: copy of HEADERS object |
| 1171 | + :param args: request parameters |
| 1172 | + :param collection: name of collection |
| 1173 | +
|
| 1174 | + :returns: tuple of headers, status code, content |
| 1175 | + """ |
| 1176 | + |
| 1177 | + headers_['Content-Type'] = self.get_content_type(headers_, args) |
| 1178 | + |
| 1179 | + response = {} |
| 1180 | + fedcats = [] |
| 1181 | + |
| 1182 | + if collection == 'metadata:main': |
1137 | 1183 | if 'federatedcatalogues' in self.config: |
1138 | | - LOGGER.debug('Adding federated catalogues') |
1139 | | - collection_info['federatedCatalogues'] = [] |
1140 | | - if self.config.get('federatedcatalogues') not in [None, '']: # if empty in config |
1141 | | - for fc in self.config.get('federatedcatalogues'): |
1142 | | - collection_info['federatedCatalogues'].append({ |
1143 | | - 'type': 'OGC API - Records', |
1144 | | - 'url': fc |
1145 | | - }) |
| 1184 | + LOGGER.debug('Adding federated catalogue {fc}') |
| 1185 | + fedcats = self.config.get('federatedcatalogues') |
1146 | 1186 |
|
1147 | | - return collection_info |
| 1187 | + if headers_['Content-Type'] == 'text/html': |
| 1188 | + response['title'] = self.config['metadata']['identification']['title'] |
| 1189 | + response['collection'] = collection |
| 1190 | + response['fedcats'] = fedcats |
| 1191 | + else: |
| 1192 | + response = fedcats |
| 1193 | + |
| 1194 | + template = 'federatedcatalogs.html' |
| 1195 | + |
| 1196 | + return self.get_response(200, headers_, response, template) |
| 1197 | + |
| 1198 | + def federated_catalogue(self, headers_, args, collection, catalogue): |
| 1199 | + """ |
| 1200 | + Provide federated catalogue |
| 1201 | +
|
| 1202 | + :param headers_: copy of HEADERS object |
| 1203 | + :param args: request parameters |
| 1204 | + :param collection: name of collection |
| 1205 | + :param catalogue: id of catalogue |
| 1206 | +
|
| 1207 | + :returns: tuple of headers, status code, content |
| 1208 | + """ |
| 1209 | + |
| 1210 | + headers_['Content-Type'] = self.get_content_type(headers_, args) |
| 1211 | + |
| 1212 | + response = {} |
| 1213 | + fedcat = None |
| 1214 | + |
| 1215 | + if collection == 'metadata:main': |
| 1216 | + fedcats = self.config.get('federatedcatalogues') |
| 1217 | + for fedcat_ in fedcats: |
| 1218 | + if fedcat_['id'] == catalogue: |
| 1219 | + fedcat = fedcat_ |
| 1220 | + break |
| 1221 | + |
| 1222 | + if fedcat is None: |
| 1223 | + msg = 'Federated catalogue does not exist' |
| 1224 | + LOGGER.exception(msg) |
| 1225 | + return self.get_exception(404, headers_, 'InvalidParameterValue', msg) |
| 1226 | + |
| 1227 | + if headers_['Content-Type'] == 'text/html': |
| 1228 | + response['title'] = self.config['metadata']['identification']['title'] |
| 1229 | + response['collection'] = collection |
| 1230 | + response['fedcat'] = fedcat |
| 1231 | + else: |
| 1232 | + response = fedcat |
| 1233 | + |
| 1234 | + template = 'federatedcatalog.html' |
| 1235 | + |
| 1236 | + return self.get_response(200, headers_, response, template) |
1148 | 1237 |
|
1149 | 1238 | def get_all_collections(self) -> list: |
1150 | 1239 | """ |
|
0 commit comments