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 + -
显示快捷键?