web_algo.cpp
来自「ncbi源码」· C++ 代码 · 共 365 行
CPP
365 行
/* * =========================================================================== * PRODUCTION $Log: web_algo.cpp,v $ * PRODUCTION Revision 1000.2 2004/06/01 20:56:13 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7 * PRODUCTION * =========================================================================== *//* $Id: web_algo.cpp,v 1000.2 2004/06/01 20:56:13 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors: Josh Cherry * * File Description: Plugin to call remote procedure via cgi * */#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>// http stuff#include <connect/ncbi_conn_stream.hpp>#include <connect/ncbi_core_cxx.hpp>#include <connect/ncbi_util.h>#include "../basic/output_dlg.hpp"#include <gui/core/idocument.hpp>#include <gui/core/plugin_utils.hpp>#include <gui/plugin/PluginRequest.hpp>#include <gui/plugin/PluginInfo.hpp>#include <gui/plugin/PluginCommandSet.hpp>#include <gui/plugin/PluginValueConstraint.hpp>#include <gui/core/version.hpp>#include <gui/objutils/utils.hpp>#include <gui/utils/browser_utils.hpp>#include "web_algo.hpp"#include "plugin_args_as_strs.hpp"#include <objmgr/util/sequence.hpp>#include <objmgr/scope.hpp>#include <objmgr/seq_vector.hpp>#include <objmgr/util/sequence.hpp>#include <objtools/readers/readfeat.hpp>#include <objects/seqloc/Seq_loc.hpp>#include <objects/general/Object_id.hpp>#include <connect/ncbi_pipe.hpp>#include <serial/serial.hpp>#include <serial/objostr.hpp>#include <serial/objistr.hpp>#include <cgi/ncbicgi.hpp>#include <util/regexp.hpp>BEGIN_NCBI_SCOPEUSING_SCOPE(objects);void CAlgoWebService::GetInfo(CPluginInfo& info){ info.Reset(); // version info macro info.SetInfo(CPluginVersion::eMajor, CPluginVersion::eMinor, 0, string(__DATE__) + " " + string(__TIME__), "CAlgoWebService", "", "", ""); // command info CPluginCommandSet& cmds = info.SetCommands(); CPluginCommand& args = cmds.AddAlgoCommand(eAlgoCommand_run); args.AddArgument("locs", "Sequences to evaluate", CSeq_loc::GetTypeInfo(), CPluginArg::TData::e_Array); args.SetConstraint("locs", *CPluginValueConstraint::CreateSeqSameMol()); args.AddArgument("__url", "url", CPluginArg::eString);}void CAlgoWebService::RunCommand(CPluginMessage& msg){ const CPluginCommand& args = msg.GetRequest().GetCommand(); CPluginReply& reply = msg.SetReply(); _TRACE("CAlgoWebService::Run()"); if ( !m_OutputDlg.get() ) { m_OutputDlg.reset(new COutputDlg()); } m_OutputDlg->SetTitle("Results of calling web algorithm"); const CPluginArgSet::Tdata& argset = args.GetArgs().Get(); vector<string> keys, values; try { PluginArgsAsStrs(argset, keys, values); } catch (exception& e) { LOG_POST(Info << "CAlgoWebService: couldn't convert to string rep: " << e.what()); reply.SetStatus(eMessageStatus_failed); return; } catch (...) { LOG_POST(Info << "CAlgoWebService: couldn't convert to string rep"); reply.SetStatus(eMessageStatus_failed); return; } keys.push_back("action"); values.push_back("run"); string query; for (unsigned int i = 0; i < keys.size(); i++) { if (i > 0) { query += '&'; } query += URL_EncodeString(keys[i]) + "=" + URL_EncodeString(values[i]); } string body; string headers; string base; if (args.HasArgument("__url") && CPluginUtils::IsValid(args["__url"])) { x_DoPost(args["__url"].AsString(), query, body, headers); base = args["__url"].AsString(); } else { throw runtime_error("CAlgoWebService::run: no url"); } // see if we have a Content-type; if so, act appropriately string content_type = x_GetContentType(headers); if (content_type == "chemical/ncbi-asn1-ascii" || content_type == "chemical/ncbi-asn1-binary" || content_type == "chemical/ncbi-xml" || content_type == "chemical/ncbi-five-col") { // in these cases we'll try to make an annot CRef<CSeq_annot> annot; CNcbiIstrstream is(body.c_str(), body.size()); if (content_type == "chemical/ncbi-asn1-ascii" || content_type == "chemical/ncbi-asn1-binary" || content_type == "chemical/ncbi-xml") { ESerialDataFormat serial_format; if (content_type == "chemical/ncbi-asn1-ascii") { serial_format = eSerial_AsnText; } else if (content_type == "chemical/ncbi-asn1-binary") { serial_format = eSerial_AsnBinary; } else if (content_type == "chemical/ncbi-xml") { serial_format = eSerial_Xml; } auto_ptr<CObjectIStream> istr(CObjectIStream::Open(serial_format, is)); annot.Reset(new CSeq_annot); *istr >> *annot; } else if (content_type == "chemical/ncbi-five-col") { annot = CFeature_table_reader::ReadSequinFeatureTable(is); } try { x_DealWithAnnot(annot, args, reply); } catch (exception& e) { LOG_POST(Error << e.what()); reply.SetStatus(eMessageStatus_failed); return; } reply.AddAction(CPluginReplyAction::e_Add_to_document); } else if (content_type == "text/html") { if (!base.empty()) { CBrowserUtils::AddBaseTag(body, base); } CBrowserUtils::SendToBrowser(body); } else if (content_type == "text/plain" || content_type.empty()) { string str; str += "Output:\n\n"; str += body + "\n\n"; m_OutputDlg->SetText(str); m_OutputDlg->Show(); } else { CBrowserUtils::SendToBrowser(body, content_type); } reply.SetStatus(eMessageStatus_success);}void CAlgoWebService::x_DealWithAnnot(CRef<CSeq_annot> annot, const CPluginCommand& args, CPluginReply& reply){ // figure out which argument this annot belongs to CSeq_annot::TData::TFtable& ftable = annot->SetData().SetFtable(); const CSeq_id& orig_id = sequence::GetId(ftable.front()->GetLocation()); const string& orig_id_str = orig_id.GetLocal().GetStr(); const CSeq_loc *loc; const IDocument *doc; // if it has the form name[integer], interpret it as array member CRegexp re("(.*)\\[ *([0-9]+) *\\]"); if (!re.GetMatch(orig_id_str.c_str(), 0).empty()) { const int *name_range = re.GetResults(1); string name = orig_id_str.substr(name_range[0], name_range[1]); const int *index_range = re.GetResults(2); unsigned int index = NStr::StringToInt(orig_id_str .substr(index_range[0], index_range[1] - index_range[0])); plugin_args::TLocList loc_list; GetArgValue(args[name], loc_list); if (index > loc_list.size() - 1) { throw runtime_error(orig_id_str + " does not exist; " + name + " has only " + NStr::IntToString(loc_list.size()) + " elements"); } plugin_args::TLocList::iterator iter = loc_list.begin(); advance(iter, index); loc = iter->second; doc = iter->first; } else { const CPluginArg& arg = args[orig_id_str]; loc = dynamic_cast<const CSeq_loc*> (&arg.AsObject()); doc = arg.GetDocument(); } // now set the ids and remap NON_CONST_ITERATE (list<CRef<CSeq_feat> >, feat, ftable) { CSeq_loc& feat_loc = (*feat)->SetLocation(); feat_loc.SetId(sequence::GetId(*loc)); (*feat)->SetLocation(*CSeqUtils::RemapChildToParent(*loc, feat_loc)); } reply.AddObject(*doc, *annot); m_OutputDlg->SetText("Annotations added to " + doc->GetShortTitle()); m_OutputDlg->Show();}string CAlgoWebService::x_GetContentType(const string& headers){ list<string> lines; string content_type; NStr::Split(headers, "\n", lines); ITERATE (list<string>, line, lines) { if (NStr::StartsWith(*line, "content-type:", NStr::eNocase)) { content_type = line->substr(string("content-type:").size()); content_type = NStr::TruncateSpaces(content_type); NStr::ToLower(content_type); break; } } return content_type;}void CAlgoWebService::x_DoPost(const string& url, const string& query, string& body, string& headers){ body.erase(); headers.erase(); SConnNetInfo* net_info = ConnNetInfo_Create(0); if (!net_info) { throw runtime_error("ConnNetInfo_Create(0) returned null"); } ConnNetInfo_ParseURL(net_info, url.c_str()); net_info->req_method = eReqMethod_Post; // pretend to be a 'real' web browser; some servers // care about this string user_header = "User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; " "Windows NT 5.0; (R1 1.1))"; user_header = "Content-type: application/x-www-form-urlencoded\n"; CConn_HttpStream http(net_info, user_header, fHCC_AutoReconnect | fHCC_KeepHeader); ConnNetInfo_Destroy(net_info); // write the query string to server http << query; // now read char buf[1024]; string line; while (getline(http, line)) { if (line.find_first_not_of(" \t\n\r\f\v") == string::npos) { break; } headers += line + '\n'; } while (!http.fail()) { http.read(buf, 1024); body.append(buf, http.gcount()); }}END_NCBI_SCOPE/* * =========================================================================== * $Log: web_algo.cpp,v $ * Revision 1000.2 2004/06/01 20:56:13 gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7 * * Revision 1.7 2004/05/21 22:27:47 gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.6 2004/05/03 13:05:42 dicuccio * gui/utils --> gui/objutils where needed * * Revision 1.5 2004/01/27 18:45:25 dicuccio * Added missing header files * * Revision 1.4 2003/12/19 18:38:18 jcherry * Alert the user when annotations are added * * Revision 1.3 2003/12/01 23:22:00 jcherry * Added registry file format for plugin info * * Revision 1.2 2003/11/26 17:13:08 dicuccio * Lots of code clean-up. CHanged names of algorithms to CAlgoWebServices{Init} * * Revision 1.1 2003/11/25 19:08:50 jcherry * Initial version * * =========================================================================== */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?