Explorar el Código

model-server landing page, property bug fixes

David Sehnal hace 6 años
padre
commit
d2d4e491ce

+ 24 - 14
src/mol-model-props/pdbe/structure-quality-report.ts

@@ -28,16 +28,17 @@ const _Descriptor = ModelPropertyDescriptor({
         categories: [{
             name: 'pdbe_structure_quality_report',
             instance(ctx) {
-                if (ctx.globalCache.pdbe_structure_quality_report) return CifWriter.Category.Empty;
-                ctx.globalCache.pdbe_structure_quality_report = true;
-                return { fields: _structure_quality_report_fields, rowCount: 1 }
+                const issues = StructureQualityReport.get(ctx.model);
+                if (typeof ctx.globalCache.pdbe_structure_quality_report !== 'undefined' && ctx.globalCache.pdbe_structure_quality_report !== ctx.model.modelNum) return CifWriter.Category.Empty;
+                ctx.globalCache.pdbe_structure_quality_report = ctx.model.modelNum;
+                return { fields: _structure_quality_report_fields, rowCount: 1, data: issues ? issues.updated : 'n/a' }
             }
         }, {
             name: 'pdbe_structure_quality_report_issues',
             instance(ctx) {
                 const issues = StructureQualityReport.get(ctx.model);
-                if (!issues) return CifWriter.Category.Empty;
-                return ResidueCustomProperty.createCifCategory(ctx, issues, _structure_quality_report_issues_fields);
+                if (!issues || !issues.map) return CifWriter.Category.Empty;
+                return ResidueCustomProperty.createCifCategory(ctx, issues.map, _structure_quality_report_issues_fields);
             }
         }]
     },
@@ -56,8 +57,8 @@ const _structure_quality_report_issues_fields: CifField<number, ExportCtx>[] = [
     CifField.str<number, ExportCtx>('issues', (i, d) => d.property(i).join(','))
 ];
 
-const _structure_quality_report_fields: CifField<ResidueIndex, ExportCtx>[] = [
-    CifField.str('updated_datetime_utc', () => `${new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')}`)
+const _structure_quality_report_fields: CifField<number, string>[] = [
+    CifField.str('updated_datetime_utc', (_, date) => date)
 ];
 
 function createIssueMapFromJson(modelData: Model, data: any): IssueMap | undefined {
@@ -98,6 +99,11 @@ function createIssueMapFromCif(modelData: Model, data: Table<typeof StructureQua
 }
 
 export namespace StructureQualityReport {
+    export interface Data {
+        updated: string,
+        map: IssueMap | undefined
+    }
+
     export const Descriptor = _Descriptor;
 
     export const Schema = {
@@ -118,10 +124,11 @@ export namespace StructureQualityReport {
     }) {
         if (get(model)) return true;
 
-        let issueMap;
-
+        let issueMap, updated = `${new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')}`;
         if (model.sourceData.kind === 'mmCIF' && model.sourceData.frame.categoryNames.includes('pdbe_structure_quality_report')) {
-            const data = toTable(Schema.pdbe_structure_quality_report_issues, model.sourceData.frame.categories.pdbe_structure_quality_report);
+            const data = toTable(Schema.pdbe_structure_quality_report_issues, model.sourceData.frame.categories.pdbe_structure_quality_report_issues);
+            const f = model.sourceData.frame.categories['pdbe_structure_quality_report'].getField('updated_datetime_utc');
+            updated = f ? f.str(0) : updated;
             issueMap = createIssueMapFromCif(model, data);
         } else if (params.PDBe_apiSourceJson) {
             const data = await params.PDBe_apiSourceJson(model);
@@ -132,11 +139,14 @@ export namespace StructureQualityReport {
         }
 
         model.customProperties.add(Descriptor);
-        model._dynamicPropertyData.__StructureQualityReport__ = issueMap;
+        (model._dynamicPropertyData.__StructureQualityReport__ as Data) = {
+            updated,
+            map: issueMap
+        };
         return true;
     }
 
-    export function get(model: Model): IssueMap | undefined {
+    export function get(model: Model): Data | undefined {
         return model._dynamicPropertyData.__StructureQualityReport__;
     }
 
@@ -144,8 +154,8 @@ export namespace StructureQualityReport {
     export function getIssues(e: StructureElement) {
         if (!Unit.isAtomic(e.unit)) return _emptyArray;
         const issues = StructureQualityReport.get(e.unit.model);
-        if (!issues) return _emptyArray;
+        if (!issues || !issues.map) return _emptyArray;
         const rI = e.unit.residueIndex[e.element];
-        return issues.has(rI) ? issues.get(rI)! : _emptyArray;
+        return issues.map.has(rI) ? issues.map.get(rI)! : _emptyArray;
     }
 }

+ 5 - 0
src/servers/model/server/api-web.ts

@@ -12,6 +12,7 @@ import { ConsoleLogger } from 'mol-util/console-logger';
 import { resolveJob } from './query';
 import { JobManager } from './jobs';
 import { UUID } from 'mol-util';
+import { LandingPage } from './landing';
 
 function makePath(p: string) {
     return Config.appPrefix + '/' + p;
@@ -138,6 +139,10 @@ export function initWebApi(app: express.Express) {
         if (JobManager.size === 1) processNextJob();
     });
 
+    app.get('*', (req, res) => {
+        res.send(LandingPage);
+    });
+
     // for (const q of QueryList) {
     //     mapQuery(app, q.name, q.definition);
     // }

+ 49 - 0
src/servers/model/server/landing.ts

@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import Version from '../version'
+
+function create() {
+    return `<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8" />
+        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+        <title>Mol* ModelServer ${Version}</title>
+        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" />
+    </head>
+    <body>
+        <h1>Mol* Model Server ${Version}</h1>
+        <textarea style="height: 280px; width: 600px; font-family: monospace" id="query-text">{
+    "id": "1cbs",
+    "name": "residueInteraction",
+    "params": {
+        "radius": 5,
+        "atom_site": { "label_comp_id": "REA" }
+    }
+}</textarea><br>
+        <button class="button button-primary" style="width: 600px" id="query">Query</button>
+        <div id='error' style='color: red; font-weight: blue'></div>
+        <div>Static input files available as CIF and BinaryCIF at <a href='ModelServer/static/cif/1cbs' target='_blank'>static/cif/id</a> and <a href='ModelServer/static/bcif/1cbs' target='_blank'>static/bcif/id</a> respectively.</div>
+        <script>
+            const err = document.getElementById('error');
+            document.getElementById('query').onclick = function () {
+                err.innerText = '';
+                try {
+                    var q = JSON.parse(document.getElementById('query-text').value);
+                    var path = 'ModelServer/api/v1?' + encodeURIComponent(JSON.stringify(q));
+                    console.log(path);
+                    window.open(path, '_blank');
+                } catch (e) {
+                    err.innerText = '' + e;
+                }
+            }
+        </script>
+    </body>
+</html>`;
+}
+
+export const LandingPage = create();

+ 1 - 1
src/servers/model/version.ts

@@ -4,4 +4,4 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-export default '0.1.0';
+export default '0.8.0';