ARES-SDK/ARES/application/scidb.lsl

206 lines
7.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/* =========================================================================
*
* Nanite Systems Advanced Research Encapsulation System
*
* Copyright (c) 20222025 Nanite Systems Corporation
*
* =========================================================================
*
* Scientific Database Lookup Utility
*
* This program is covered under the terms of the ARES Software Copyright
* License, Section 2 (ASCL-ii). Although it appears in ARES as part of
* commercial software, it may be used as the basis of derivative,
* non-profit works that retain a compatible license. Derivative works of
* ASCL-ii software must retain proper attribution in documentation and
* source files as described in the terms of the ASCL. Furthermore, they
* must be distributed free of charge and provided with complete, legible
* source code included in the package.
*
* To see the full text of the ASCL, type 'help license' on any standard
* ARES distribution, or visit http://nanite-systems.com/ASCL for the
* current version.
*
* DISCLAIMER
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS
* IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DAMAGES HOWEVER CAUSED ON ANY THEORY OF LIABILITY ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* =========================================================================
*
*/
#include <ARES/a>
#define CLIENT_VERSION "0.2.2"
#define CLIENT_VERSION_TAGS "alpha"
string DEFAULT_DOMAIN = "eutils.ncbi.nlm.nih.gov";
string DEFAULT_DB = "pubmed";
string DEFAULT_QUERY_KEY = "1";
#define SEARCH_STRING(DB, Q) "/entrez/eutils/esearch.fcgi?usehistory=y&db=" + llEscapeURL(DB) + "&term=" + llEscapeURL(Q)
#define POST_STRING(DB, Q) "/entrez/eutils/epost.fcgi?usehistory=y&db=" + llEscapeURL(DB) + "&id=" + llEscapeURL(Q)
#define SUMMARY_STRING(DB, Q, ENV) "/entrez/eutils/esummary.fcgi?usehistory=y&db=" + llEscapeURL(DB) + "&query_key=" + llEscapeURL(Q) + "&WebEnv=" + llEscapeURL(ENV)
#define ABSTRACT_STRING(DB, Q, ENV) "/entrez/eutils/efetch.fcgi?usehistory=y&db=" + llEscapeURL(DB) + "&query_key=" + llEscapeURL(Q) + "&WebEnv=" + llEscapeURL(ENV) + "&rettype=abstract&retmode=text"
#define FASTA_STRING(DB, Q, ENV) "/entrez/eutils/efetch.fcgi?usehistory=y&db=" + llEscapeURL(DB) + "&query_key=" + llEscapeURL(Q) + "&WebEnv=" + llEscapeURL(ENV) + "&rettype=fasta&retmode=text"
key scidb_receive_pipe;
string waiting_queries = "{}";
string queries_in_progress = "{}";
#define MODE_SEARCH 0
#define MODE_SUMMARY 1
#define MODE_ABSTRACT 2
#define MODE_FASTA 3
send_query(string query, key handle) {
string domain = getjs(query, [4]);
string database = getjs(query, [5]);
string question = getjs(query, [6]);
integer mode = (integer)getjs(query, [7]);
string query_key = getjs(query, [8]);
queries_in_progress = setjs(queries_in_progress, [(string)handle], query);
string url;
if(mode == MODE_SEARCH)
url = domain + SEARCH_STRING(database, question);
else if(mode == MODE_SEARCH)
url = domain + POST_STRING(database, question);
else if(mode == MODE_SUMMARY)
url = domain + SUMMARY_STRING(database, query_key, question);
else if(mode == MODE_ABSTRACT)
url = domain + ABSTRACT_STRING(database, query_key, question);
else if(mode == MODE_FASTA)
url = domain + FASTA_STRING(database, query_key, question);
http_get(url, scidb_receive_pipe, handle);
}
main(integer src, integer n, string m, key outs, key ins, key user) {
if(n == SIGNAL_INVOKE) {
list argv = split(m, " ");
integer argc = count(argv);
string msg = "";
if(argc == 1) {
msg = "Syntax: " + PROGRAM_NAME + " [-d <database> -m <domain> -q <querykey> -s|-f|-a-p] <query>\n\nLooks up <query> on the specified [https://www.ncbi.nlm.nih.gov/ NCBI Entrez] database at <domain> (default: " + DEFAULT_DB + " at " + DEFAULT_DOMAIN + "). -s will retrieve summaries from a matching WebEnv query. -q will set the query key (default: 1) -p will post queries to sequence databases. -a will fetch abstracts. -f will fetch FASTA sequences.";
} else {
string domain = DEFAULT_DOMAIN;
string database = DEFAULT_DB;
integer mode = MODE_SEARCH;
string query_key = DEFAULT_QUERY_KEY;
string a1;
integer a1i;
while(~(a1i = llListFindList(["-m", "-d", "-s", "-f", "-a", "-q"], [a1 = gets(argv, 1)]))) {
if(a1i == 0) { // -m
domain = gets(argv, 2);
argv = delrange(argv, 1, 2);
} else if(a1i == 1) { // -d
database = gets(argv, 2);
argv = delrange(argv, 1, 2);
} else if(a1i == 5) { // -q
query_key = gets(argv, 2);
argv = delrange(argv, 1, 2);
} else if(a1i == 2) { // -s
mode = MODE_SUMMARY;
argv = delrange(argv, 1, 1);
} else if(a1i == 3) { // -f
mode = MODE_FASTA;
argv = delrange(argv, 1, 1);
} else if(a1i == 4) { // -a
mode = MODE_ABSTRACT;
argv = delrange(argv, 1, 1);
}
}
string question = concat(delitem(argv, 0), " ");
if(!~strpos(domain, "://"))
domain = "https://" + domain;
key handle = llGenerateKey();
string query = jsarray([outs, ins, user, _resolved, domain, database, question, mode, query_key]);
_resolved = 0;
llSetMemoryLimit(0x10000);
if(scidb_receive_pipe) {
queries_in_progress = setjs(queries_in_progress, [handle], query);
send_query(query, handle);
} else {
scidb_receive_pipe = llGenerateKey();
waiting_queries = setjs(waiting_queries, [handle], query);
pipe_open(["p:"+(string)scidb_receive_pipe + " notify " + PROGRAM_NAME + " response"]);
}
}
if(msg != "")
print(outs, user, msg);
} else if(n == SIGNAL_NOTIFY) {
list argv = split(m, " ");
string cmd = gets(argv, 1);
if(cmd == "pipe") {
list queries = jskeys(waiting_queries);
integer qi = 0;
integer qmax = count(queries);
while(qi < qmax) {
key handle = gets(queries, qi);
string query = getjs(waiting_queries, [(string)handle]);
waiting_queries = setjs(waiting_queries, [(string)handle], JSON_DELETE);
send_query(query, handle);
++qi;
}
} else if(cmd == "response") {
string query = getjs(queries_in_progress, [(string)user]);
if(query != JSON_INVALID) {
key o_outs = getjs(query, [0]);
key o_ins = getjs(query, [1]);
key o_user = getjs(query, [2]);
integer o_rc = (integer)getjs(query, [3]);
string buffer;
pipe_read(ins, buffer);
/* string fieldset = getjs(buffer, ["query", "pages", 0]);
string field;
if(fieldset != JSON_INVALID) {
if(getjs(fieldset, ["missing"]) == JSON_TRUE) {
field = getjs(fieldset, ["title"]) + " does not exist (" + getjs(query, [0]) + "/)";
} else {
field = getjs(fieldset, ["extract"]);
}
} else {
field = buffer;
} */
print(o_outs, o_user, buffer);
// resolve_io(o_rc, o_outs, o_ins);
queries_in_progress = setjs(queries_in_progress, [(string)user], JSON_DELETE);
resolve_i(o_rc, o_ins);
}
if(queries_in_progress == "{}") {
pipe_close(scidb_receive_pipe);
scidb_receive_pipe = "";
llSetMemoryLimit(0x2000);
}
}
} else if(n == SIGNAL_INIT) {
#ifdef DEBUG
echo("[" + PROGRAM_NAME + "] init event");
#endif
llSetMemoryLimit(0x2000);
} else if(n == SIGNAL_UNKNOWN_SCRIPT) {
echo("[" + PROGRAM_NAME + "] failed to run '" + m + "' (kernel could not find the program specified)");
} else {
echo("[" + PROGRAM_NAME + "] unimplemented signal " + (string)n + ": " + m);
}
}
#include <ARES/program>