From 310939b6aa07cabee9bb609ce67d6e44cb1d84fe Mon Sep 17 00:00:00 2001
From: Markus Scheidgen <markus.scheidgen@gmail.com>
Date: Fri, 24 Aug 2018 13:32:36 +0200
Subject: [PATCH] Added stub for repo calc view. Added repo API endpoint.

---
 gui/src/api.js                 |  8 ++++-
 gui/src/components/App.js      |  4 ++-
 gui/src/components/RepoCalc.js | 56 ++++++++++++++++++++++++++++++++++
 nomad/api.py                   | 15 +++++++--
 tests/test_api.py              | 13 ++++++++
 tests/test_processing.py       |  1 -
 6 files changed, 91 insertions(+), 6 deletions(-)
 create mode 100644 gui/src/components/RepoCalc.js

diff --git a/gui/src/api.js b/gui/src/api.js
index 8ae56538d7..f7dec4856d 100644
--- a/gui/src/api.js
+++ b/gui/src/api.js
@@ -61,10 +61,16 @@ function archive(uploadHash, calcHash) {
     .then(response => response.json())
 }
 
+function repo(uploadHash, calcHash) {
+  return fetch(`${apiBase}/repo/${uploadHash}/${calcHash}`)
+    .then(response => response.json())
+}
+
 const api = {
   createUpload: createUpload,
   getUploads: getUploads,
-  archive: archive
+  archive: archive,
+  repo: repo
 };
 
 export default api;
\ No newline at end of file
diff --git a/gui/src/components/App.js b/gui/src/components/App.js
index e902bf3a05..cea8b9fb75 100644
--- a/gui/src/components/App.js
+++ b/gui/src/components/App.js
@@ -5,6 +5,7 @@ import Navigation from './Navigation';
 import { BrowserRouter, Switch, Route } from 'react-router-dom';
 import Uploads from './Uploads'
 import ArchiveCalc from './ArchiveCalc';
+import RepoCalc from './RepoCalc';
 
 function App() {
   return (
@@ -13,7 +14,8 @@ function App() {
         <Navigation>
           <Switch>
             <Route exact path="/" render={() => <div>Home</div>} />
-            <Route path="/repo" render={() => <div>Browse</div>} />
+            <Route exact path="/repo" render={() => <div>Browse</div>} />
+            <Route path="/repo/:uploadHash/:calcHash" component={RepoCalc} />
             <Route path="/upload" component={Uploads} />
             <Route exact path="/archive" render={() => <div>Archive</div>} />
             <Route path="/archive/:uploadHash/:calcHash" component={ArchiveCalc} />
diff --git a/gui/src/components/RepoCalc.js b/gui/src/components/RepoCalc.js
new file mode 100644
index 0000000000..8560dcd80f
--- /dev/null
+++ b/gui/src/components/RepoCalc.js
@@ -0,0 +1,56 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withStyles, Paper, LinearProgress } from '@material-ui/core';
+import ReactJson from 'react-json-view'
+import api from '../api';
+import Markdown from './Markdown';
+
+
+class RepoCalc extends React.Component {
+  static propTypes = {
+    classes: PropTypes.object.isRequired
+  }
+  static styles = theme => ({
+    root: {},
+    calcData: {
+      padding: theme.spacing.unit
+    }
+  });
+
+  constructor(props) {
+    super(props)
+    this.state = {
+      data: null
+    }
+  }
+
+  componentDidMount() {
+    const { uploadHash, calcHash} = this.props.match.params
+    api.repo(uploadHash, calcHash).then(data => {
+      this.setState({data: data})
+    })
+  }
+
+  render() {
+    const { classes } = this.props
+    const { data } = this.state
+
+    return (
+      <div className={classes.root}>
+        <Markdown>{`
+          ## The Repository – Raw Code Data
+        `}</Markdown>
+        <Paper className={classes.calcData}>
+          {
+            data ?
+              <ReactJson src={this.state.data} enableClipboard={false} collapsed={4} /> :
+              <LinearProgress variant="query" />
+          }
+        </Paper>
+      </div>
+
+    )
+  }
+}
+
+export default withStyles(RepoCalc.styles)(RepoCalc);
\ No newline at end of file
diff --git a/nomad/api.py b/nomad/api.py
index 79aa3d2cd8..2e8a003ceb 100644
--- a/nomad/api.py
+++ b/nomad/api.py
@@ -4,6 +4,7 @@ from datetime import datetime
 import mongoengine.errors
 from flask_cors import CORS
 import logging
+from elasticsearch.exceptions import NotFoundError
 
 from nomad import users, files, search
 from nomad.processing import UploadProc
@@ -76,14 +77,22 @@ class Upload(Resource):
 
 
 class Repo(Resource):
+    @staticmethod
+    def _render(data: dict):
+        if 'upload_time' in data:
+            data['upload_time'] = data['upload_time'].isoformat()
+
+        return {key: value for key, value in data.items() if value is not None}
+
     def get(self, upload_hash, calc_hash):
         try:
             data = search.Calc.get(id='%s/%s' % (upload_hash, calc_hash))
+        except NotFoundError:
+            abort(404, message='There is no calculation for %s/%s' % (upload_hash, calc_hash))
         except Exception as e:
-            # TODO
-            abort(404, message=str(e))
+            abort(500, message=str(e))
 
-        return data, 200
+        return Repo._render(data.to_dict()), 200
 
 
 @app.route('/archive/<string:upload_hash>/<string:calc_hash>', methods=['GET'])
diff --git a/tests/test_api.py b/tests/test_api.py
index 2bd0ddeef8..6e8f891608 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -13,6 +13,9 @@ from tests.test_processing import example_files
 from tests.test_files import assert_exists
 # import fixtures
 from tests.test_files import clear_files, archive_id  # pylint: disable=unused-import
+from tests.test_normalizing import normalized_vasp_example  # pylint: disable=unused-import
+from tests.test_parsing import parsed_vasp_example  # pylint: disable=unused-import
+from tests.test_search import example_entry  # pylint: disable=unused-import
 from tests.test_processing import celery_config, celery_includes  # pylint: disable=unused-import
 
 
@@ -150,6 +153,16 @@ def test_processing(client, file, celery_session_worker):
     assert_exists(config.files.uploads_bucket, upload['upload_id'])
 
 
+def test_get_repo(client, example_entry):
+    rv = client.get('/repo/%s/%s' % (example_entry.upload_hash, example_entry.calc_hash))
+    assert rv.status_code == 200
+
+
+def test_non_existing_repo(client):
+    rv = client.get('/repo/doesnt/exist')
+    assert rv.status_code == 404
+
+
 def test_get_archive(client, archive_id):
     rv = client.get('/archive/%s' % archive_id)
     assert rv.status_code == 302
diff --git a/tests/test_processing.py b/tests/test_processing.py
index 2b8b87414d..35a2e8001f 100644
--- a/tests/test_processing.py
+++ b/tests/test_processing.py
@@ -28,7 +28,6 @@ from nomad.processing import start_processing
 
 from tests.test_files import example_file, empty_file
 # import fixtures
-from tests.test_search import index  # pylint: disable=unused-import
 from tests.test_files import clear_files  # pylint: disable=unused-import
 
 example_files = [empty_file, example_file]
-- 
GitLab