1 /*  $Id: eutils_sample.cpp 607528 2020-05-05 14:03:22Z ivanov $
2  * ===========================================================================
3  *
4  *                            PUBLIC DOMAIN NOTICE
5  *               National Center for Biotechnology Information
6  *
7  *  This software/database is a "United States Government Work" under the
8  *  terms of the United States Copyright Act.  It was written as part of
9  *  the author's official duties as a United States Government employee and
10  *  thus cannot be copyrighted.  This software/database is freely available
11  *  to the public for use. The National Library of Medicine and the U.S.
12  *  Government have not placed any restriction on its use or reproduction.
13  *
14  *  Although all reasonable efforts have been taken to ensure the accuracy
15  *  and reliability of the software and data, the NLM and the U.S.
16  *  Government do not and cannot warrant the performance or results that
17  *  may be obtained by using this software or data. The NLM and the U.S.
18  *  Government disclaim all warranties, express or implied, including
19  *  warranties of performance, merchantability or fitness for any particular
20  *  purpose.
21  *
22  *  Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author:  Aleksey Grichenko
27  *
28  * File Description:
29  *   Example of using e-utils
30  *
31  */
32 
33 #include <ncbi_pch.hpp>
34 
35 #include <corelib/ncbiapp.hpp>
36 #include <corelib/ncbienv.hpp>
37 #include <corelib/ncbiargs.hpp>
38 
39 #include <objects/seq/Bioseq.hpp>
40 #include <objects/seqset/Seq_entry.hpp>
41 #include <objects/seqset/Bioseq_set.hpp>
42 
43 #include <objtools/eutils/api/eutils.hpp>
44 #include <objtools/eutils/api/einfo.hpp>
45 #include <objtools/eutils/api/esearch.hpp>
46 #include <objtools/eutils/api/egquery.hpp>
47 #include <objtools/eutils/api/efetch.hpp>
48 #include <objtools/eutils/api/epost.hpp>
49 #include <objtools/eutils/api/elink.hpp>
50 #include <objtools/eutils/api/esummary.hpp>
51 #include <objtools/eutils/api/espell.hpp>
52 #include <objtools/eutils/api/ehistory.hpp>
53 #include <objtools/eutils/einfo/einfo__.hpp>
54 #include <objtools/eutils/esearch/esearch__.hpp>
55 #include <objtools/eutils/egquery/egquery__.hpp>
56 #include <objtools/eutils/elink/elink__.hpp>
57 #include <objtools/eutils/esummary/esummary__.hpp>
58 #include <objtools/eutils/espell/espell__.hpp>
59 #include <objtools/eutils/ehistory/ehistory__.hpp>
60 
61 
62 USING_NCBI_SCOPE;
63 USING_SCOPE(objects);
64 
65 
66 /////////////////////////////////////////////////////////////////////////////
67 //
68 //  EUtils demo application
69 //
70 
71 class CEUtilsApp : public CNcbiApplication
72 {
73 public:
74     virtual void Init(void);
75     virtual int  Run (void);
76     virtual void Exit(void);
77 
78 private:
79     void CallEInfo(const CArgs& args);
80     void CallESearch(const CArgs& args);
81     void CallEPost(const CArgs& args);
82     void CallEGQuery(const CArgs& args);
83     void CallELink(const CArgs& args);
84     void CallESummary(const CArgs& args);
85     void CallEFetch(const CArgs& args);
86     void CallESpell(const CArgs& args);
87     void CallEHistory(const CArgs& args);
88 
89     CEFetch_Request* x_CreateLitRequest(const CArgs& args);
90     CEFetch_Request* x_CreateSeqRequest(const CArgs& args);
91     CEFetch_Request* x_CreateTaxRequest(const CArgs& args);
92 
93     CRef<CEUtils_ConnContext>& x_GetCtx(void);
94     void x_SetHttpMethod(CEUtils_Request& req, const CArgs& args);
95     void x_DumpRequest(CEUtils_Request& req);
96 
97     CRef<CEUtils_ConnContext> m_Ctx;
98     bool                      m_DumpRequests;
99 };
100 
101 
x_GetCtx(void)102 CRef<CEUtils_ConnContext>& CEUtilsApp::x_GetCtx(void)
103 {
104     if ( !m_Ctx ) {
105         m_Ctx.Reset(new CEUtils_ConnContext);
106     }
107     return m_Ctx;
108 }
109 
110 
Init(void)111 void CEUtilsApp::Init(void)
112 {
113     // Prepare command line descriptions
114     //
115 
116     // Create
117     unique_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
118 
119     arg_desc->AddFlag("einfo", "Call einfo utility", true);
120     arg_desc->AddFlag("efetch", "Call efetch utility", true);
121     // arg_desc->SetDependency("einfo", CArgDescriptions::eExcludes, "efetch");
122     arg_desc->AddFlag("esearch", "Call esearch utility", true);
123     arg_desc->AddFlag("epost", "Call epost utility", true);
124     arg_desc->AddFlag("elink", "Call elink utility", true);
125     arg_desc->AddFlag("egquery", "Call egquery utility", true);
126     arg_desc->AddFlag("esummary", "Call esummary utility", true);
127     arg_desc->AddFlag("espell", "Call espell utility", true);
128     arg_desc->AddFlag("ehistory", "Call ehistory utility", true);
129 
130     // Switch HTTP method
131     arg_desc->AddDefaultKey("http", "Method",
132         "HTTP method used to send requests",
133         CArgDescriptions::eString, "post");
134     arg_desc->SetConstraint("http", &(*new CArgAllow_Strings, "post", "get"));
135 
136     // Debug flag
137     arg_desc->AddFlag("dump", "Print raw incoming data", true);
138 
139     // Context setup
140     arg_desc->AddOptionalKey("webenv", "WebEnv", "Web environment",
141         CArgDescriptions::eString);
142     arg_desc->AddOptionalKey("query_key", "query_key", "Query key",
143         CArgDescriptions::eString);
144     arg_desc->AddOptionalKey("tool", "tool", "Client tool",
145         CArgDescriptions::eString);
146     arg_desc->AddOptionalKey("email", "email", "Client e-mail",
147         CArgDescriptions::eString);
148 
149     // Arguments for all queries
150     arg_desc->AddOptionalKey("db", "db", "Database name",
151         CArgDescriptions::eString);
152     arg_desc->AddOptionalKey("id", "id", "ID to fetch",
153         CArgDescriptions::eString);
154     arg_desc->AddOptionalKey("term", "term", "Term to search for",
155         CArgDescriptions::eString);
156     arg_desc->AddOptionalKey("retstart", "RetStart", "First item to fetch",
157         CArgDescriptions::eInteger);
158     arg_desc->SetConstraint("retstart", new CArgAllow_Integers(1, kMax_Int));
159     arg_desc->AddOptionalKey("retmax", "RetMax", "Number of items to fetch",
160         CArgDescriptions::eInteger);
161     arg_desc->SetConstraint("retmax", new CArgAllow_Integers(1, kMax_Int));
162     arg_desc->AddDefaultKey("retmode", "RetMode", "Data format",
163         CArgDescriptions::eString, "text");
164     arg_desc->SetConstraint("retmode", &(*new CArgAllow_Strings,
165         "text", "xml", "asn", "html"));
166     arg_desc->AddOptionalKey("rettype", "RetType", "Fetched data type",
167         CArgDescriptions::eString);
168     arg_desc->SetConstraint("rettype", &(*new CArgAllow_Strings,
169         // Literature
170         "uilist", "abstract", "citation", "medline", "full",
171         // Sequence
172         "native", "fasta", "gb", "gbc", "gbwithparts", "est", "gss",
173         "gp", "gpc", "seqid", "acc", "chr", "flt", "rsr", "brief", "docset",
174         // Search
175         "count", "uilist"));
176     arg_desc->AddOptionalKey("reldate", "RelDate", "Age of date in days",
177         CArgDescriptions::eInteger);
178     // taxonomy only
179     arg_desc->AddOptionalKey("report", "Report", "Taxonomy data format",
180         CArgDescriptions::eString);
181     arg_desc->SetConstraint("report", &(*new CArgAllow_Strings,
182         "uilist", "brief", "docsum", "xml"));
183     // esearch
184     arg_desc->AddOptionalKey("usehistory", "UseHistory", "Use history",
185         CArgDescriptions::eBoolean);
186     arg_desc->AddOptionalKey("sort", "Sort", "Sort order or 'none'",
187         CArgDescriptions::eString);
188 
189     // Dependencies
190     // ESearch
191     arg_desc->SetDependency("esearch", CArgDescriptions::eRequires, "db");
192     arg_desc->SetDependency("esearch", CArgDescriptions::eRequires, "term");
193     arg_desc->SetDependency("usehistory", CArgDescriptions::eRequires, "esearch");
194     arg_desc->SetDependency("sort", CArgDescriptions::eRequires, "esearch");
195     // EGQuery
196     arg_desc->SetDependency("egquery", CArgDescriptions::eRequires, "term");
197     // EFetch
198     arg_desc->SetDependency("efetch", CArgDescriptions::eRequires, "db");
199     arg_desc->SetDependency("epost", CArgDescriptions::eRequires, "db");
200     arg_desc->SetDependency("epost", CArgDescriptions::eRequires, "id");
201     // ELink
202     arg_desc->SetDependency("elink", CArgDescriptions::eRequires, "db");
203     // ESummary
204     arg_desc->SetDependency("esummary", CArgDescriptions::eRequires, "db");
205     // ESpell
206     arg_desc->SetDependency("espell", CArgDescriptions::eRequires, "db");
207     arg_desc->SetDependency("espell", CArgDescriptions::eRequires, "term");
208 
209     // elink arguments
210     // dbfrom
211     arg_desc->AddOptionalKey("dbfrom", "dbfrom", "origination db for elink",
212         CArgDescriptions::eString);
213     // cmd
214     arg_desc->AddOptionalKey("cmd", "Command", "elink command",
215         CArgDescriptions::eString);
216     arg_desc->SetConstraint("cmd", &(*new CArgAllow_Strings,
217         "prlinks", "llinks", "llinkslib", "lcheck", "ncheck",
218         "neighbor", "neighbor_history", "acheck"));
219     // linkname
220     arg_desc->AddOptionalKey("linkname", "Linkname", "elink linkname",
221         CArgDescriptions::eString);
222     // holding
223     arg_desc->AddOptionalKey("holding", "holding", "elink holding",
224         CArgDescriptions::eString);
225     // version
226     arg_desc->AddOptionalKey("version", "Version", "elink DTD version",
227         CArgDescriptions::eString);
228 
229     // Program description
230     string prog_description =
231         "Test loading data from EUtils";
232     arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
233                               prog_description, false);
234 
235     // Pass argument descriptions to the application
236     SetupArgDescriptions(arg_desc.release());
237 }
238 
239 
x_SetHttpMethod(CEUtils_Request & req,const CArgs & args)240 void CEUtilsApp::x_SetHttpMethod(CEUtils_Request& req, const CArgs& args)
241 {
242     if ( args["http"].AsString() == "get" ) {
243         req.SetRequestMethod(CEUtils_Request::eHttp_Get);
244     }
245 }
246 
247 
x_DumpRequest(CEUtils_Request & req)248 void CEUtilsApp::x_DumpRequest(CEUtils_Request& req)
249 {
250     string data;
251     req.Read(&data);
252     cout << data << endl;
253 }
254 
255 
CallEInfo(const CArgs & args)256 void CEUtilsApp::CallEInfo(const CArgs& args)
257 {
258     string db = args["db"] ? args["db"].AsString() : kEmptyStr;
259     CEInfo_Request req(db, x_GetCtx());
260     x_SetHttpMethod(req, args);
261 
262     cout << req.GetScriptName() << "?" << req.GetQueryString() << endl;
263 
264     if ( m_DumpRequests ) {
265         x_DumpRequest(req);
266         return;
267     }
268 
269     CRef<einfo::CEInfoResult> result = req.GetEInfoResult();
270     _ASSERT(result);
271     cout << MSerial_Xml << *result << endl;
272     if ( result->IsDbList() ) {
273         for (const auto& name : result->GetDbList().GetDbName()) {
274             req.SetDatabase(name);
275             cout << req.GetScriptName() << "?" << req.GetQueryString() << endl;
276             CRef<einfo::CEInfoResult> db_info = req.GetEInfoResult();
277             _ASSERT(db_info);
278             cout << MSerial_Xml << *db_info << endl;
279         }
280     }
281 }
282 
283 
CallESearch(const CArgs & args)284 void CEUtilsApp::CallESearch(const CArgs& args)
285 {
286     // Prepare request
287     CESearch_Request req(args["db"].AsString(), x_GetCtx());
288     x_SetHttpMethod(req, args);
289 
290     req.SetTerm(args["term"].AsString());
291     if ( args["usehistory"] ) {
292         req.SetUseHistory(args["usehistory"].AsBoolean());
293     }
294     if ( args["sort"] ) {
295         req.SetSortOrderName(args["sort"].AsString());
296     }
297     if ( args["reldate"] ) {
298         req.SetRelDate(args["reldate"].AsInteger());
299     }
300 
301     if ( args["retmax"] ) {
302         req.SetRetMax(args["retmax"].AsInteger());
303     }
304 
305     string rettype = args["rettype"] ? args["rettype"].AsString() : kEmptyStr;
306     if (rettype == "count") {
307         req.SetRetType(CESearch_Request::eRetType_count);
308     }
309     else if (rettype == "uilist") {
310         req.SetRetType(CESearch_Request::eRetType_uilist);
311     }
312     else if ( !rettype.empty() ) {
313         ERR_POST(Error << "Rettype " << rettype <<
314             " is incompatible with e-search request.");
315         return;
316     }
317 
318     // Print query string
319     cout << req.GetScriptName() << "?" << req.GetQueryString() << endl;
320 
321     if ( m_DumpRequests ) {
322         x_DumpRequest(req);
323         return;
324     }
325 
326     // Get and show the results
327     CRef<esearch::CESearchResult> result = req.GetESearchResult();
328     _ASSERT(result);
329     cout << MSerial_Xml << *result << endl;
330     cout << "WebEnv=" << x_GetCtx()->GetWebEnv() << endl;
331     cout << "query_key=" << x_GetCtx()->GetQueryKey() << endl;
332 }
333 
334 
CallEGQuery(const CArgs & args)335 void CEUtilsApp::CallEGQuery(const CArgs& args)
336 {
337     // Prepare request
338     CEGQuery_Request req(x_GetCtx());
339     x_SetHttpMethod(req, args);
340 
341     req.SetTerm(args["term"].AsString());
342 
343     // Print query string
344     cout << req.GetScriptName() << "?" << req.GetQueryString() << endl;
345 
346     if ( m_DumpRequests ) {
347         x_DumpRequest(req);
348         return;
349     }
350 
351     // Get and show the results
352     CRef<egquery::CResult> result = req.GetResult();
353     _ASSERT(result);
354     cout << MSerial_Xml << *result << endl;
355 }
356 
357 
CallEPost(const CArgs & args)358 void CEUtilsApp::CallEPost(const CArgs& args)
359 {
360     // Prepare request
361     CEPost_Request req(args["db"].AsString(), x_GetCtx());
362     x_SetHttpMethod(req, args);
363 
364     req.GetId().SetIds(args["id"].AsString());
365 
366     // Print query string
367     cout << req.GetScriptName() << "?" << req.GetQueryString() << endl;
368 
369     if ( m_DumpRequests ) {
370         x_DumpRequest(req);
371         return;
372     }
373 
374     // Get and show the results
375     CRef<epost::CEPostResult> result = req.GetEPostResult();
376     _ASSERT(result);
377     cout << MSerial_Xml << *result << endl;
378     cout << "WebEnv=" << x_GetCtx()->GetWebEnv() << endl;
379     cout << "query_key=" << x_GetCtx()->GetQueryKey() << endl;
380 }
381 
382 
CallELink(const CArgs & args)383 void CEUtilsApp::CallELink(const CArgs& args)
384 {
385     // Prepare request
386     CELink_Request req(args["db"].AsString(), x_GetCtx());
387     x_SetHttpMethod(req, args);
388 
389     if ( args["dbfrom"] ) {
390         req.SetDbFrom(args["dbfrom"].AsString());
391     }
392     // If WebEnv was set (as an command line argument or by previous requests)
393     // use it instead of id.
394     if ( req.GetConnContext()->GetWebEnv().empty()  &&  args["id"] ) {
395         req.GetIdGroups().SetGroups(args["id"].AsString());
396     }
397     if ( args["cmd"] ) {
398         string cmd = args["cmd"].AsString();
399         if (cmd == "prlinks") {
400             req.SetCommand(CELink_Request::eCmd_prlinks);
401         }
402         else if (cmd == "llinks" ) {
403             req.SetCommand(CELink_Request::eCmd_llinks);
404         }
405         else if (cmd == "llinkslib") {
406             req.SetCommand(CELink_Request::eCmd_llinkslib);
407         }
408         else if (cmd == "lcheck") {
409             req.SetCommand(CELink_Request::eCmd_lcheck);
410         }
411         else if (cmd == "ncheck") {
412             req.SetCommand(CELink_Request::eCmd_ncheck);
413         }
414         else if (cmd == "neighbor") {
415             req.SetCommand(CELink_Request::eCmd_neighbor);
416         }
417         else if (cmd == "neighbor_history") {
418             req.SetCommand(CELink_Request::eCmd_neighbor_history);
419         }
420         else if (cmd == "acheck") {
421             req.SetCommand(CELink_Request::eCmd_acheck);
422         }
423         else {
424             ERR_POST(Error << "Unsupported elink command: " << cmd);
425         }
426     }
427     if ( args["linkname"] ) {
428         req.SetLinkName(args["linkname"].AsString());
429     }
430     if ( args["holding"] ) {
431         req.SetHolding(args["holding"].AsString());
432     }
433     if ( args["version"] ) {
434         req.SetHolding(args["version"].AsString());
435     }
436     if ( args["reldate"] ) {
437         req.SetRelDate(args["reldate"].AsInteger());
438     }
439 
440     // Print query string
441     cout << req.GetScriptName() << "?" << req.GetQueryString() << endl;
442 
443     if ( m_DumpRequests ) {
444         x_DumpRequest(req);
445         return;
446     }
447 
448     // Get and show the results
449     CRef<elink::CELinkResult> result = req.GetELinkResult();
450     _ASSERT(result);
451     cout << MSerial_Xml << *result << endl;
452 }
453 
454 
CallESummary(const CArgs & args)455 void CEUtilsApp::CallESummary(const CArgs& args)
456 {
457     // Prepare request
458     string db = args["db"] ? args["db"].AsString() : kEmptyStr;
459     CESummary_Request req(db, x_GetCtx());
460     x_SetHttpMethod(req, args);
461 
462     // If WebEnv was set (as an command line argument or by previous requests)
463     // use it instead of id.
464     if ( req.GetConnContext()->GetWebEnv().empty()  &&  args["id"] ) {
465         req.GetId().SetIds(args["id"].AsString());
466     }
467     if ( args["retstart"] ) {
468         req.SetRetStart(args["retstart"].AsInteger());
469     }
470     if ( args["retmax"] ) {
471         req.SetRetMax(args["retmax"].AsInteger());
472     }
473 
474     // Print query string
475     cout << req.GetScriptName() << "?" << req.GetQueryString() << endl;
476 
477     if ( m_DumpRequests ) {
478         x_DumpRequest(req);
479         return;
480     }
481 
482     try {
483         // Get and show the results. GetESummaryResult() may fail if the
484         // selected database uses an incompatible DTD, so report exceptions
485         // if any (in real life this case must be handled by using XmlWrapp
486         // library to parse the data).
487         CRef<esummary::CESummaryResult> result = req.GetESummaryResult();
488         _ASSERT(result);
489         cout << MSerial_Xml << *result << endl;
490     }
491     catch (CSerialException& ex) {
492         cout << "Deserialization error: " << ex.what() << endl;
493     }
494 }
495 
496 
CallESpell(const CArgs & args)497 void CEUtilsApp::CallESpell(const CArgs& args)
498 {
499     // Prepare request
500     string db = args["db"] ? args["db"].AsString() : kEmptyStr;
501     CESpell_Request req(db, x_GetCtx());
502     x_SetHttpMethod(req, args);
503 
504     req.SetTerm(args["term"].AsString());
505 
506     // Print query string
507     cout << req.GetScriptName() << "?" << req.GetQueryString() << endl;
508 
509     if ( m_DumpRequests ) {
510         x_DumpRequest(req);
511         return;
512     }
513 
514     // Get and show the results
515     CRef<espell::CESpellResult> result = req.GetESpellResult();
516     _ASSERT(result);
517     cout << MSerial_Xml << *result << endl;
518 }
519 
520 
CallEHistory(const CArgs & args)521 void CEUtilsApp::CallEHistory(const CArgs& args)
522 {
523     // Prepare request
524     string db;
525     if ( args["db"] ) {
526         db = args["db"].AsString();
527     }
528     CEHistory_Request req(db, x_GetCtx());
529     x_SetHttpMethod(req, args);
530 
531     // Print query string
532     cout << req.GetScriptName() << "?" << req.GetQueryString() << endl;
533 
534     if ( m_DumpRequests ) {
535         x_DumpRequest(req);
536         return;
537     }
538 
539     // Get and show the results
540     CRef<ehistory::CEHistoryResult> result = req.GetEHistoryResult();
541     _ASSERT(result);
542     cout << MSerial_Xml << *result << endl;
543 }
544 
545 
x_CreateLitRequest(const CArgs & args)546 CEFetch_Request* CEUtilsApp::x_CreateLitRequest(const CArgs& args)
547 {
548     // Prepare literature request
549     string db = args["db"].AsString();
550     CEFetch_Literature_Request::ELiteratureDB ldb;
551     if (db == "pubmed") {
552         ldb = CEFetch_Literature_Request::eDB_pubmed;
553     }
554     else if (db == "pmc") {
555         ldb = CEFetch_Literature_Request::eDB_pmc;
556     }
557     else if (db == "journals") {
558         ldb = CEFetch_Literature_Request::eDB_journals;
559     }
560     else if (db == "omim") {
561         ldb = CEFetch_Literature_Request::eDB_omim;
562     }
563     else {
564         return 0;
565     }
566     unique_ptr<CEFetch_Literature_Request> lit_req(
567         new CEFetch_Literature_Request(ldb, x_GetCtx()));
568 
569     string rettype = args["rettype"] ? args["rettype"].AsString() : kEmptyStr;
570     if (rettype == "uilist") {
571         lit_req->SetRetType(CEFetch_Literature_Request::eRetType_uilist);
572     }
573     else if (rettype == "abstract") {
574         lit_req->SetRetType(CEFetch_Literature_Request::eRetType_abstract);
575     }
576     else if (rettype == "citation") {
577         lit_req->SetRetType(CEFetch_Literature_Request::eRetType_citation);
578     }
579     else if (rettype == "medline") {
580         lit_req->SetRetType(CEFetch_Literature_Request::eRetType_medline);
581     }
582     else if (rettype == "full") {
583         lit_req->SetRetType(CEFetch_Literature_Request::eRetType_full);
584     }
585     else if ( !rettype.empty() ) {
586         ERR_POST(Error << "Rettype " << rettype <<
587             " is incompatible with the selected database " << db);
588         return 0;
589     }
590 
591     return lit_req.release();
592 }
593 
594 
x_CreateSeqRequest(const CArgs & args)595 CEFetch_Request* CEUtilsApp::x_CreateSeqRequest(const CArgs& args)
596 {
597     // Prepare sequence request
598     string db = args["db"].AsString();
599     CEFetch_Sequence_Request::ESequenceDB sdb;
600     if (db == "gene") {
601         sdb = CEFetch_Sequence_Request::eDB_gene;
602     }
603     else if (db == "genome") {
604         sdb = CEFetch_Sequence_Request::eDB_genome;
605     }
606     else if (db == "nucleotide") {
607         sdb = CEFetch_Sequence_Request::eDB_nucleotide;
608     }
609     else if (db == "nuccore") {
610         sdb = CEFetch_Sequence_Request::eDB_nuccore;
611     }
612     else if (db == "nucest") {
613         sdb = CEFetch_Sequence_Request::eDB_nucest;
614     }
615     else if (db == "nucgss") {
616         sdb = CEFetch_Sequence_Request::eDB_nucgss;
617     }
618     else if (db == "protein") {
619         sdb = CEFetch_Sequence_Request::eDB_protein;
620     }
621     else if (db == "popset") {
622         sdb = CEFetch_Sequence_Request::eDB_popset;
623     }
624     else if (db == "snp") {
625         sdb = CEFetch_Sequence_Request::eDB_snp;
626     }
627     else if (db == "sequences") {
628         sdb = CEFetch_Sequence_Request::eDB_sequences;
629     }
630     else {
631         return 0;
632     }
633     unique_ptr<CEFetch_Sequence_Request> seq_req(
634         new CEFetch_Sequence_Request(sdb, x_GetCtx()));
635 
636     string rettype = args["rettype"] ? args["rettype"].AsString() : kEmptyStr;
637     if (rettype == "native") {
638         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_native);
639     }
640     else if (rettype == "fasta") {
641         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_fasta);
642     }
643     else if (rettype == "gb") {
644         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_gb);
645     }
646     else if (rettype == "gbc") {
647         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_gbc);
648     }
649     else if (rettype == "gbwithparts") {
650         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_gbwithparts);
651     }
652     else if (rettype == "est") {
653         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_est);
654     }
655     else if (rettype == "gss") {
656         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_gss);
657     }
658     else if (rettype == "gp") {
659         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_gp);
660     }
661     else if (rettype == "gpc") {
662         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_gpc);
663     }
664     else if (rettype == "seqid") {
665         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_seqid);
666     }
667     else if (rettype == "acc") {
668         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_acc);
669     }
670     else if (rettype == "chr") {
671         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_chr);
672     }
673     else if (rettype == "flt") {
674         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_flt);
675     }
676     else if (rettype == "rsr") {
677         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_rsr);
678     }
679     else if (rettype == "brief") {
680         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_brief);
681     }
682     else if (rettype == "docset") {
683         seq_req->SetRetType(CEFetch_Sequence_Request::eRetType_docset);
684     }
685     else if ( !rettype.empty() ) {
686         ERR_POST(Error << "Rettype " << rettype <<
687             " is incompatible with the selected database " << db);
688         return 0;
689     }
690 
691     return seq_req.release();
692 }
693 
694 
x_CreateTaxRequest(const CArgs & args)695 CEFetch_Request* CEUtilsApp::x_CreateTaxRequest(const CArgs& args)
696 {
697     // Prepare taxonomy request
698     string db = args["db"].AsString();
699     if (db != "taxonomy") {
700         return 0;
701     }
702     unique_ptr<CEFetch_Taxonomy_Request> tax_req(
703         new CEFetch_Taxonomy_Request(x_GetCtx()));
704 
705     if ( args["report"] ) {
706         string report = args["report"].AsString();
707         if (report == "uilist") {
708             tax_req->SetReport(CEFetch_Taxonomy_Request::eReport_uilist);
709         }
710         else if (report == "brief") {
711             tax_req->SetReport(CEFetch_Taxonomy_Request::eReport_brief);
712         }
713         else if (report == "docsum") {
714             tax_req->SetReport(CEFetch_Taxonomy_Request::eReport_docsum);
715         }
716         else if (report == "xml") {
717             tax_req->SetReport(CEFetch_Taxonomy_Request::eReport_xml);
718         }
719         else {
720             ERR_POST(Error << "Unsupported taxonomy report: " << report);
721             return 0;
722         }
723     }
724     return tax_req.release();
725 }
726 
727 
CallEFetch(const CArgs & args)728 void CEUtilsApp::CallEFetch(const CArgs& args)
729 {
730     // Try to create literature request
731     unique_ptr<CEFetch_Request> req(x_CreateLitRequest(args));
732     if ( !req.get() ) {
733         // Try to create sequence request
734         req.reset(x_CreateSeqRequest(args));
735     }
736     if ( !req.get() ) {
737         // Try to create taxonomy request
738         req.reset(x_CreateTaxRequest(args));
739     }
740     if ( !req.get() ) {
741         // the database is not related to any known request type
742         ERR_POST(Error << "Can not connect to database "
743             << args["db"].AsString() << " using the specified arguments.");
744         return;
745     }
746     x_SetHttpMethod(*req, args);
747 
748     // If WebEnv was set (as an command line argument or by previous requests)
749     // use it instead of id.
750     if ( req->GetConnContext()->GetWebEnv().empty()  &&  args["id"] ) {
751         req->GetId().SetIds(args["id"].AsString());
752     }
753 
754     string retmode_str = args["retmode"].AsString();
755     CEFetch_Request::ERetMode retmode = CEFetch_Request::eRetMode_none;
756     if (retmode_str == "text") {
757         retmode = CEFetch_Request::eRetMode_text;
758     }
759     else if (retmode_str == "xml") {
760         retmode = CEFetch_Request::eRetMode_xml;
761     }
762     else if (retmode_str == "html") {
763         retmode = CEFetch_Request::eRetMode_html;
764     }
765     else if (retmode_str == "asn") {
766         retmode = CEFetch_Request::eRetMode_asn;
767     }
768     else {
769         ERR_POST(Error << "Unknown retmode: " << retmode_str);
770     }
771     req->SetRetMode(retmode);
772 
773     cout << req->GetScriptName() << "?" << req->GetQueryString() << endl;
774 
775     if ( m_DumpRequests ) {
776         x_DumpRequest(*req);
777         return;
778     }
779 
780     // efetch can return different object types, just print plain content
781     string content;
782     req->Read(&content);
783     cout << content << endl;
784 }
785 
786 
Run(void)787 int CEUtilsApp::Run(void)
788 {
789     // Process command line args
790     const CArgs& args = GetArgs();
791 
792     m_DumpRequests = args["dump"];
793 
794     // Set connection context parameters
795     if (args["webenv"]) {
796         x_GetCtx()->SetWebEnv(args["webenv"].AsString());
797     }
798     if (args["query_key"]) {
799         x_GetCtx()->SetQueryKey(args["query_key"].AsString());
800     }
801     if (args["tool"]) {
802         x_GetCtx()->SetTool(args["tool"].AsString());
803     }
804     if (args["email"]) {
805         x_GetCtx()->SetEmail(args["email"].AsString());
806     }
807 
808     // Call the requested utils
809     if ( args["einfo"] ) {
810         CallEInfo(args);
811     }
812     if ( args["egquery"] ) {
813         CallEGQuery(args);
814     }
815     if ( args["espell"] ) {
816         CallESpell(args);
817     }
818     if ( args["esearch"] ) {
819         CallESearch(args);
820     }
821     if ( args["epost"] ) {
822         CallEPost(args);
823     }
824     if ( args["elink"] ) {
825         CallELink(args);
826     }
827     if ( args["esummary"] ) {
828         CallESummary(args);
829     }
830     if ( args["efetch"] ) {
831         CallEFetch(args);
832     }
833     // EHistory is the last one - shows all other requests if any
834     if ( args["ehistory"] ) {
835         CallEHistory(args);
836     }
837     return 0;
838 }
839 
840 
Exit(void)841 void CEUtilsApp::Exit(void)
842 {
843     return;
844 }
845 
846 
847 /////////////////////////////////////////////////////////////////////////////
848 //  MAIN
849 
NcbiSys_main(int argc,ncbi::TXChar * argv[])850 int NcbiSys_main(int argc, ncbi::TXChar* argv[])
851 {
852     return CEUtilsApp().AppMain(argc, argv);
853 }
854