Skip to content
Snippets Groups Projects
Select Git revision
  • d6077d9a9acad1e2f3357aac7dd9bc0656722ced
  • master default protected
  • devel
  • hruska-feature-clients-api
  • malostik-#5066-deduplicate-idea-ids
  • warden-postgresql-port
  • hruska-feature-#6799-filter-keys
  • hruska-feature-5066-duplicateIdeaID
  • warden-client-3.0-beta3
  • warden-server-3.0-beta3
  • warden-client-2.2-final
  • warden-server-2.2-final
  • warden-client-3.0-beta2
  • warden-server-3.0-beta2
  • warden-client-2.2
  • warden-server-2.2-patch3
  • warden-client-3.0-beta1
  • warden-server-3.0-beta1
  • warden-server-2.2-patch1
  • warden-client-3.0-beta0
  • warden-server-3.0-beta0
  • warden-server-2.2
  • warden-server-2.1-patch1
  • warden-client-2.1
  • warden-server-2.1
  • warden-server-2.1-beta6
  • warden-server-2.1-beta5
  • warden-server-2.1-beta4
28 results

row_details.html

Blame
  • web-api.ts 3.25 KiB
    /**
     * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
     *
     * @author David Sehnal <david.sehnal@gmail.com>
     */
    
    import * as express from 'express';
    import Config from '../config';
    import { QueryDefinition, QueryList } from './api';
    import { ConsoleLogger } from 'mol-util/console-logger';
    import { resolveJob } from './query';
    import { JobManager } from './jobs';
    import { UUID } from 'mol-util';
    
    function makePath(p: string) {
        return Config.appPrefix + '/' + p;
    }
    
    function wrapResponse(fn: string, res: express.Response) {
        const w = {
            doError(this: any, code = 404) {
                if (!this.headerWritten) {
                    res.writeHead(code);
                    this.headerWritten = true;
                }
                this.end();
            },
            writeHeader(this: any, binary: boolean) {
                if (this.headerWritten) return;
                res.writeHead(200, {
                    'Content-Type': binary ? 'application/octet-stream' : 'text/plain; charset=utf-8',
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Headers': 'X-Requested-With',
                    'Content-Disposition': `inline; filename="${fn}"`
                });
                this.headerWritten = true;
            },
            writeBinary(this: any, data: Uint8Array) {
                if (!this.headerWritten) this.writeHeader(true);
                return res.write(new Buffer(data.buffer));
            },
            writeString(this: any, data: string) {
                if (!this.headerWritten) this.writeHeader(false);
                return res.write(data);
            },
            end(this: any) {
                if (this.ended) return;
                res.end();
                this.ended = true;
            },
            ended: false,
            headerWritten: false
        };
    
        return w;
    }
    
    const responseMap = new Map<UUID, express.Response>();
    
    async function processNextJob() {
        if (!JobManager.hasNext()) return;
    
        const job = JobManager.getNext();
        const response = responseMap.get(job.id)!;
        responseMap.delete(job.id);
    
        const filenameBase = `${job.entryId}_${job.queryDefinition.name.replace(/\s/g, '_')}`
        const writer = wrapResponse(job.responseFormat.isBinary ? `${filenameBase}.bcif` : `${filenameBase}.cif`, response);
        try {
            writer.writeHeader(job.responseFormat.isBinary);
            await resolveJob(job, writer);
        } catch (e) {
            ConsoleLogger.errorId(job.id, '' + e);
            // TODO: add some error?
            writer.doError(404);
        } finally {
            writer.end();
            setImmediate(processNextJob);
        }
    }
    
    function mapQuery(app: express.Express, queryName: string, queryDefinition: QueryDefinition) {
        app.get(makePath(':entryId/' + queryName), async (req, res) => {
            ConsoleLogger.log('Server', `Query '${req.params.entryId}/${queryName}'...`);
    
            if (JobManager.size >= Config.maxQueueLength) {
                // TODO use proper code: server busy
                res.writeHead(404);
                res.end();
                return;
            }
    
            const jobId = JobManager.add('pdb', req.params.entryId, queryName, req.query);
            responseMap.set(jobId, res);
            processNextJob();
        });
    }
    
    export function initWebApi(app: express.Express) {
        for (const q of QueryList) {
            mapQuery(app, q.name, q.definition);
        }
    }