From c183df6af9b00dee5bd0293dfa595d6f7b05b0d5 Mon Sep 17 00:00:00 2001
From: vuillaut <thomas.vuillaume@gmail.com>
Date: Tue, 14 Sep 2021 16:58:23 +0200
Subject: [PATCH] add zenodo Record class and basic zenodo search function

---
 eossr/api/zenodo.py | 74 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 71 insertions(+), 3 deletions(-)

diff --git a/eossr/api/zenodo.py b/eossr/api/zenodo.py
index 36b0ef88..6860addf 100644
--- a/eossr/api/zenodo.py
+++ b/eossr/api/zenodo.py
@@ -6,8 +6,11 @@ import pprint
 import requests
 from os.path import abspath
 from pathlib import Path
+from urllib.parse import urlencode
 from ..metadata.codemeta2zenodo import parse_codemeta_and_write_zenodo_metadata_file
 
+zenodo_api_url = "https://zenodo.org/api"
+
 
 class ZenodoAPI:
     def __init__(self, access_token, sandbox=True, proj_root_dir='./'):
@@ -38,11 +41,10 @@ class ZenodoAPI:
         """
 
         if sandbox:
-            zenodo_api_url = "https://sandbox.zenodo.org/api"
+            self.zenodo_api_url = "https://sandbox.zenodo.org/api"
         else:
-            zenodo_api_url = "https://zenodo.org/api"
+            self.zenodo_api_url = zenodo_api_url
 
-        self.zenodo_api_url = zenodo_api_url
         self.access_token = access_token
         self.parameters = {'access_token': self.access_token}
 
@@ -401,3 +403,69 @@ class ZenodoAPI:
               "`OSSR how to publish tutorial`:\n"
               "\t https://escape2020.pages.in2p3.fr/wp3/ossr-pages/page/contribute/publish_tutorial/#3-add-the-following-code-snippet \n"
               "In case you do, please contact us !\n")
+
+
+class Record:
+
+    def __init__(self, data: dict):
+        for k in ['id', 'metadata', 'files', 'links']:
+            if k not in data.keys():
+                raise ValueError(f"key {k} not present in data")
+        self.data = data
+
+    def __str__(self):
+        entry_id = self.data['id']
+        metadata = self.data['metadata']
+        return f"Record #{entry_id} : {metadata['title']}"
+
+    def __repr__(self):
+        return f"Record({self.data})"
+
+    def print_info(self):
+        entry_id = self.data['id']
+        metadata = self.data['metadata']
+        descrp = metadata['description']
+        print(f"=== Record #{entry_id} ===")
+        print(f"Title: {metadata['title']} ===")
+        print(f"DOI: {self.data['doi']}")
+        print(f"URL: {self.data['links']['html']}")
+        print(f"Description:\n{descrp}")
+        print('\n')
+
+
+def get_zenodo_records(search='', **kwargs) -> list[Record]:
+    """
+    Search the ossr based on `search`.
+    Function rewritten from pyzenodo3 (https://github.com/space-physics/pyzenodo3)
+
+    :param search: string
+    :param kwargs: Zenodo query arguments.
+        For an exhaustive list, see the query arguments at https://developers.zenodo.org/#list36
+        Common arguments are:
+            - size: int
+                Number of results to return
+            - all_versions: int
+                Show (1) or hide (0) all versions of records
+            - type: string
+                Records of the specified type (Publication, Poster, Presentation, Software, ...)
+            - keywords: string
+                Records with the specified keywords
+
+    :return:
+    list of `Record`
+    """
+    search = search.replace("/", " ")  # zenodo can't handle '/' in search query
+
+    params = {
+        'q': search,
+        **kwargs
+    }
+
+    url = zenodo_api_url + "/records?" + urlencode(params)
+
+    recs = [Record(hit) for hit in requests.get(url).json()["hits"]["hits"]]
+
+    if not recs:
+        raise LookupError(f"No records found for search {search}")
+
+    return recs
-- 
GitLab