From 549320ab3f627d2cef5f8694670e7bb22ea146ec Mon Sep 17 00:00:00 2001 From: Franklin_Zhang Date: Mon, 23 Apr 2018 17:12:24 +0800 Subject: [PATCH 01/17] python SDK update Signed-off-by: Franklin_Zhang --- swig/python/modelser.py | 40 ++++++++++++++++++++++++++++++++++++--- swig/python/modelser.pyc | Bin 2819 -> 4005 bytes swig/python/server.py | 4 ++-- swig/python/server.pyc | Bin 4073 -> 4638 bytes swig/python/test.py | 14 +++++++------- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/swig/python/modelser.py b/swig/python/modelser.py index 99e7949..443499e 100644 --- a/swig/python/modelser.py +++ b/swig/python/modelser.py @@ -7,11 +7,25 @@ from data import DataConfigrationItem class ModelService(Service): - def __init__(self, ip, port, id, name, type): + def __init__(self, ip, port, id, name, type, url, pid, mid, registered, description, version, platform, deploymenttime, img, deployorname, deployoremail, status, limitation, permission): Service.__init__(self, ip, port) self.id = id self.name = name self.type = type + self.url = url + self.pid = pid + self.mid = mid + self.registered = registered + self.description = description + self.version = version + self.platform = platform + self.deploymenttime = deploymenttime + self.img = img + self.deployorname = deployorname + self.deployoremail = deployoremail + self.status = status + self.limitation = limitation + self.permission = permission def invoke(self, list_data): path = "/modelser/" + self.id + "?ac=run&inputdata=[" @@ -19,18 +33,35 @@ class ModelService(Service): path += "{\"StateId\":\"" + item.stateid + "\",\"Event\":\"" + item.eventname + "\",\"DataId\":\"" + item.dataid + "\",\"Destoryed\":\"" + str(item.destoryed) + "\"}" path += "]" jsData = HttpHelper.Request_get_sync(self.ip, self.port, path) + recordid = -1 if jsData["result"] == "suc": recordid = jsData["data"] return recordid + def refresh(self): + path = "/modelser/json" + self.id + jsData = HttpHelper.Request_get_sync(self.ip, self.port, path) + if jsData["result"] == "suc": + jsMs = jsData["data"] + self.status = int(jsMs["ms_status"]) + self.limitation = int(jsMs["ms_limited"]) + return 1 + return -1 + + class ModelServiceRunningRecord(Service): - def __init__(self, ip, port, id, msid, status, inputs = [], outputs = []): + def __init__(self, ip, port, id, msid, status = 1, inputs = [], outputs = [], timespan = 0.0, standout = '', standerr = '', invokeerr = '', logs = []): Service.__init__(self, ip, port) self.id = id self.msid = msid self.status = status self.inputs = inputs self.outputs = outputs + self.timespan = timespan + self.standout = standout + self.standerr = standerr + self.invokeerr = invokeerr + self.logs = logs def waitForFinished(self): self.refresh() @@ -43,10 +74,13 @@ class ModelServiceRunningRecord(Service): jsData = HttpHelper.Request_get_sync(self.ip, self.port, "/modelserrun/json/" + self.id) if jsData["result"] == "suc": self.status = int(jsData["data"]["msr_status"]) + self.timespan = float(jsData["data"]["msr_span"]) + self.standout = jsData["data"]["msr_runninginfo"]["StdErr"] + self.standerr = jsData["data"]["msr_runninginfo"]["StdOut"] + self.invokeerr = jsData["data"]["msr_runninginfo"]["InvokeErr"] self.inputs = [] for index, item in enumerate(jsData["data"]["msr_input"]): self.inputs.append(DataConfigrationItem.MakeUpDataItem(item)) - self.outputs = [] for index, item in enumerate(jsData["data"]["msr_output"]): self.outputs.append(DataConfigrationItem.MakeUpDataItem(item)) \ No newline at end of file diff --git a/swig/python/modelser.pyc b/swig/python/modelser.pyc index 4541bfdb198e08783603c578e949fbecbb9e9d70..c62e2a1ae5d3ee673d0df48ba043da81b49fb430 100644 GIT binary patch literal 4005 zcmcgv>uy^`5T0W@PMk}dG;KpDt<;njQ!Xi}w9p$Bz0iUhq_rR-q_T|9COz)CD@EYO+=&O*R4v>+(Y6xybix z;}VYVwN4CMC%8zf*}#I)U-+yv1E_uy;-2^UJsan?DBH%-*0RNusB6oHqiDF@@ts>) zx)E&_9Uo=seQy&#jgALdXyd`~;Q=}K7kJzm2#cd(hr+$!P}m2Rs)Q9)YGPVVdZf#B z_|)*+!sC91@FKlHo{2nztjP1K1kb9p+ZB0MQw8RjDlqG+z#LZv=7cIR8>+yZR0Zag zDln&2fjOfJ%tNZcJgf@LSyf=psRHweDlq3&Il?ox)MYEpd2HRNizlG9+ff?%cH38A zM4{&i(@tVl@jJQobU?p|^*6@|+6jIcpu%oO&fCIyPi*0+bD=!$ z_>HVc{2?8f$JtI|Q|}|J#VMm?Q==AIc4dWbVrDotD{Rtuz z9HCHGav^gJqKT&z?jp21SJuCb{4IcRedVkDSZv+?dfh#ZHrMkV|0qk>6XMj_;=_E$ z(EZ$kdmBQ6`JnM1e_h6nXW)qxn!iE;l7YjX$O53euv?Ms@5G}mkmrHiet1vTE3#Xa zUBD8s2TE(w!@#g63skF6$4V6~$lwJJ+@hn-_ZN`G3zsqJ)+t%#`x8P75$`FYdkW_s zz^h5IJ0@X6c7b;&ld>32$>WL?zoxjjA&^X$d@{3USlcDLSX_Rgng=ZI? z`r%tzrLRJLP9n6iMnyi*ogz&8!it0}LBElR>E z^OY87j+Rsa*wL@*k-H6yElOiMF!CBh^U5vK~0GF_Pi zrQ5kNy`V58F19w;JCr)@01ob1ke+rTe>W@c;u_{2*-%l>^c3Xp5oGeA5tDKkdiIO( z#1O1Q3LS7ODmFP(tNlI>y%3N&;ULiHKiLx(&_VNvK~cyDZQ~d|A&X>M)b)Lhjj|DC zeqST%J4a42QK?MJ_Eqt?tPaLZDM#Oacvf#9dI@1{rlogC;Eo>du2n{iLEHLGRtM9} z$@Y!?)8N{G5&xQI?v>Njf>m5FLgrg}!C=7}Rs&osmRS&%U#p=YmiAW~9ueFjLwD_LhW0ZwymFe8nDhi0?R7i)L#^frPFc_9PfB50GAQgfd|!nPm>N-rno4!SePXeW^ptojJhssBzTWV5=89X z3frxSuO3F%qCu$KcK7xm3L{SG4I=h^CKn1~1r&!k%7H4wEJKaJCsSZTtov!NNQcLHhvmtD75<2t$B1 z6SmGkWWf-jm7q=cZ3 zrtxB$>2aQyutM)eNp8t+Ua8E*iWI{H0iDZg_t*XiEqkfTyb97Xh{Fu~rH#1n?QS%t zZd$%iHBKsxRTou53Y(0;iOH|oSvgWFbBk=iz)pdAphEu_h!hM|IAn0+-WT~@Ssf12U~6F7 zSun>om)Lw_jmSScLNy+0IbJg8^&{5Bp5V9#>x(0F8WVa|72ZXg^Vx5A}? zWjjG+A6uQCC-PBruiX?6yS^u~(Y&{3H-$5RFxUbUf>02v;VtL@tgJx!4l9*b+IkL=K0T9J-hsIwFSyk;7q3F19hb6fD^Z zI?N^HaFUQyfk3GtsEg^wkWb-Z_%z83Ns)vO$mzNAGKoo2A(N#f@>ROeKFE3P+w$>pzDRkZajX>k zhL0@pU7OcNYr3HrS8$PFC_b;rgTl?x^K6k#HYiGKTQ)vFzAE44)+_(pgPtm%m({$< zYVvaaBip1Va>LlJEKuqa$qLCWk}Z;L*)MF2{upoAB%Ph_kc2mJhcXJ^m4!k{yGr3T Mxlq_-yBOd93$-K0aR2}S delta 513 zcmZvZy-Pw-7{=douioo5KQhuvBPF6P715^+5khJdS;J{)sIU(s6jDk92Zf-m_1zl! z4;tbQP5lGWP=7*GwFM5Xokws88qSZy^FBP!d+xm(`HGu*%kO)X?c#P-cIFKec4y+D%P^8XA=p4NS!O8ts$`+O}=+ ztA3=}CV#t@c+UOQH!FI@v8FoQ>X@Cry6Q`6HR6xzi(NvLQ(E#y_<82|Xv^Z&(SS2?U;w{Pt|@vy>S z?GT%C+5aq-5zNhijK*M(1EatqkOEftKD6%41|LN?ewWMu_?U7PlOdT^cQ~u)F@&Yt R0ZgZW89oT*L{=Hke*ud|T_pej diff --git a/swig/python/test.py b/swig/python/test.py index 1be6b5c..f50400a 100644 --- a/swig/python/test.py +++ b/swig/python/test.py @@ -1,22 +1,22 @@ from setup import OGMSService_DEBUG -server = OGMSService_DEBUG.CreateServer("172.21.212.155", 8060) +server = OGMSService_DEBUG.CreateServer("127.0.0.1", 8060) print str(server.connect()) access = server.getServiceAccess() list_ms = access.getModelServicesList() for index, item in enumerate(list_ms): print "ID : " + item.id + " - Name : " + item.name + " - Type : " + item.type -dataid = access.uploadDataByFile("swat_input", "E:\\DemoData\\GeoModeling\\SWAT\\SWAT_Input.zip") -print "SWAT - Data ID : " + dataid -swat = access.getModelServiceByID("5aac7d81926ec0059c553f0c") -recordid = swat.invoke([access.createDataConfigurationItem("04579ee0-5983-4d75-bdc9-a1a460229aa0", "LoadHydroResponseUnit", dataid)]) +dataid = access.uploadDataByFile("aread8_input", "E:\\DemoData\\GeoModeling\\udx_zip_d8\\d8.tif") +print "AreaD8 - Input Data ID : " + dataid +swat = access.getModelServiceByID("5acf6bde18f9e109f0aafa38") +recordid = swat.invoke([access.createDataConfigurationItem("851a1985-a3f6-4c13-be53-f1c765022929", "D8FlowDirection", dataid)]) record = access.getModelServiceRunningRecordByID(recordid) record.waitForFinished() -print "SWAT has been finished" +print "AreaD8 has been finished" for index,item in enumerate(record.outputs): dat = access.getDataByID(item.dataid) - dat.save("E:\\DemoData\\GeoModeling\\SWAT\\SWAT664_OUTPUT_" + item.eventname + ".zip") + dat.save("E:\\DemoData\\GeoModeling\\udx_zip_d8\\AreaD8_" + item.eventname + ".zip") # conn = httplib.HTTPConnection("127.0.0.1:8060") # conn.request("GET", "/modelser/json/all") -- Gitee From 26081fcee6e4644d3241faa358d717060c3a59bc Mon Sep 17 00:00:00 2001 From: Franklin_Zhang Date: Thu, 26 Apr 2018 22:34:23 +0800 Subject: [PATCH 02/17] add new functions in instance interface add log convert from JSON to OBJECT update running log interface Signed-off-by: Franklin_Zhang --- include/INxModelServiceInstance.h | 8 +++- include/INxModelServiceRecord.h | 4 ++ include/INxRunningLog.h | 9 +++++ src/NxModelServiceInstance.cpp | 57 ++++++++++++++++++++++++++- src/NxModelServiceInstance.h | 11 +++++- src/NxModelServiceInstanceFactory.cpp | 21 +++++++++- src/NxModelServiceInstanceFactory.h | 2 + src/NxModelServiceRecord.cpp | 12 +++++- src/NxModelServiceRecord.h | 8 ++++ src/NxModelServiceRecordFactory.cpp | 1 + src/NxRunningLog.cpp | 16 ++++++++ src/NxRunningLog.h | 17 +++++--- src/NxRunningLogFactory.cpp | 13 +++++- src/NxRunningLogFactory.h | 6 +-- src/NxServiceAccess.cpp | 7 ++-- test/test.cpp | 42 ++++++-------------- utils/NxCommon.cpp | 18 +++++++++ utils/NxCommon.h | 16 ++++++++ 18 files changed, 219 insertions(+), 49 deletions(-) create mode 100644 utils/NxCommon.cpp create mode 100644 utils/NxCommon.h diff --git a/include/INxModelServiceInstance.h b/include/INxModelServiceInstance.h index 4818875..cf69a0a 100644 --- a/include/INxModelServiceInstance.h +++ b/include/INxModelServiceInstance.h @@ -17,7 +17,8 @@ namespace NJGIS INSTA_UNKNOWN = 0, INSTA_RUNNING = 1, INSTA_REQUESTING = 2, - INSTA_HANGING = 3 + INSTA_HANGING = 3, + INSTA_FINISHED = 4 }NjModelInstanceStatus; class INjModelServiceInstance : public virtual INjService @@ -35,6 +36,8 @@ namespace NJGIS virtual std::vector* getLogs() = 0; + virtual std::vector* getNewLogs() = 0; + virtual NjModelInstanceStatus getStatus() = 0; virtual int kill() = 0; @@ -43,6 +46,9 @@ namespace NJGIS virtual int restart() = 0; + //! Defualt Timeout is 7200 seconds, if you need long, please set a larger value as you request. + virtual int wait4Status(NJGIS::SERVICE::NjModelInstanceStatus status, double timeout = 7200, bool log = false) = 0; + virtual int refresh() = 0; }; } diff --git a/include/INxModelServiceRecord.h b/include/INxModelServiceRecord.h index 13944b8..6c868f2 100644 --- a/include/INxModelServiceRecord.h +++ b/include/INxModelServiceRecord.h @@ -31,6 +31,8 @@ namespace NJGIS virtual const char* getStartDatetime() = 0; + virtual const char* getGUID() = 0; + virtual int getTimeSpan() = 0; virtual INjDataConfiguration* getInputData() = 0; @@ -47,6 +49,8 @@ namespace NJGIS virtual std::vector* getLogs() = 0; + virtual void waitForFinished() = 0; + virtual int refresh() = 0; }; } diff --git a/include/INxRunningLog.h b/include/INxRunningLog.h index 3e6c9db..89ede29 100644 --- a/include/INxRunningLog.h +++ b/include/INxRunningLog.h @@ -29,6 +29,15 @@ namespace NJGIS //! get datetime virtual const char* getDateTime() = 0; + + //! get mark + virtual bool getMark() = 0; + + //! set mark + virtual void setMark(bool mark) = 0; + + //! print + virtual void print() = 0; }; } } diff --git a/src/NxModelServiceInstance.cpp b/src/NxModelServiceInstance.cpp index aec73b1..79ffc65 100644 --- a/src/NxModelServiceInstance.cpp +++ b/src/NxModelServiceInstance.cpp @@ -1,5 +1,8 @@ #include "NxModelServiceInstance.h" +#include "NxModelServiceInstanceFactory.h" +#include "NxRunningLogFactory.h" #include "../utils/NxHttp.h" +#include "../utils/NxCommon.h" #include "json/json.h" const char* NJGIS::SERVICE::NjModelServiceInstance::getCurrentState() @@ -32,6 +35,20 @@ std::vector* NJGIS::SERVICE::NjModelServiceInsta return this->_logs; } +std::vector* NJGIS::SERVICE::NjModelServiceInstance::getNewLogs() +{ + std::vector* nlog = new std::vector(); + for(int i = 0; i < (this->_logs)->size(); i++) + { + if(!(*this->_logs)[i]->getMark()) + { + (*this->_logs)[i]->setMark(true); + nlog->push_back((*this->_logs)[i]); + } + } + return nlog; +} + NJGIS::SERVICE::NjModelInstanceStatus NJGIS::SERVICE::NjModelServiceInstance::getStatus() { return this->_status; @@ -107,7 +124,20 @@ int NJGIS::SERVICE::NjModelServiceInstance::refresh() NJGIS::SERVICE::NjHttpHelper::request_get_json_sync(url.c_str(), jsResponse); if(jsResponse["result"].asString() == "suc") { - jsResponse[""].asString(); + Json::Value mis = jsResponse["data"]; + if(mis == Json::nullValue) + { + this->_status = NJGIS::SERVICE::NjModelInstanceStatus::INSTA_FINISHED; + return 1; + } + else + { + this->_event = mis["event"].asString(); + this->_state = mis["state"].asString(); + this->_status = NJGIS::SERVICE::NjModelServiceInstanceFactory::convertString2Status(mis["status"].asCString()); + NJGIS::SERVICE::NJRunningLogFactory::convertJson2Logs(mis["log"], this->_logs); + this->_statusDes = mis["statusDes"].asCString(); + } return 1; } else if(jsResponse["result"].asString() == "err") @@ -117,3 +147,28 @@ int NJGIS::SERVICE::NjModelServiceInstance::refresh() return -1; } +int NJGIS::SERVICE::NjModelServiceInstance::wait4Status( NJGIS::SERVICE::NjModelInstanceStatus status, double timeout /*= 0*/, bool log ) +{ + int steps = (int)timeout; + int step = 0; + while(this->_status != status && step < steps) + { + step ++; + NJGIS::SERVICE::NjCommonLibrary::sleep(2); + this->refresh(); + if(log) + { + std::vector* list_logs = this->getNewLogs(); + int count = list_logs->size(); + for(int i = 0; i < count; i++) + { + (*list_logs)[i]->print(); + } + } + } + if(this->_status == status) + { + return 1; + } + return -1; +} \ No newline at end of file diff --git a/src/NxModelServiceInstance.h b/src/NxModelServiceInstance.h index 70e5d31..8c42f7a 100644 --- a/src/NxModelServiceInstance.h +++ b/src/NxModelServiceInstance.h @@ -21,7 +21,8 @@ namespace NJGIS const char* ip, int port, std::vector* logs = NULL, - NjModelInstanceStatus status = NJGIS::SERVICE::INSTA_UNKNOWN + NjModelInstanceStatus status = NJGIS::SERVICE::INSTA_UNKNOWN, + const char* statusDes = "" ): _state(state), _event(eventname), @@ -29,6 +30,7 @@ namespace NJGIS _startDT(startDT), _serviceID(serviceID), _status(status), + _statusDes(statusDes), NjService(ip, port) { this->_logs = new std::vector(); @@ -58,6 +60,8 @@ namespace NJGIS virtual std::vector* getLogs(); + virtual std::vector* getNewLogs(); + virtual NjModelInstanceStatus getStatus(); virtual int kill(); @@ -68,6 +72,8 @@ namespace NJGIS virtual int refresh(); + virtual int wait4Status(NJGIS::SERVICE::NjModelInstanceStatus status, double timeout = 7200, bool log = false); + private: std::string _startDT; @@ -88,6 +94,9 @@ namespace NJGIS //! dynamic NjModelInstanceStatus _status; + + //! dynamic + std::string _statusDes; }; } } diff --git a/src/NxModelServiceInstanceFactory.cpp b/src/NxModelServiceInstanceFactory.cpp index 457980d..6d31fa3 100644 --- a/src/NxModelServiceInstanceFactory.cpp +++ b/src/NxModelServiceInstanceFactory.cpp @@ -1,4 +1,5 @@ #include "NxModelServiceInstanceFactory.h" +#include "NxRunningLogFactory.h" NJGIS::SERVICE::INjModelServiceInstance* NJGIS::SERVICE::NjModelServiceInstanceFactory::createModelServiceInstacnce(Json::Value jsData, const char* ip, int port) { @@ -12,4 +13,22 @@ NJGIS::SERVICE::INjModelServiceInstance* NJGIS::SERVICE::NjModelServiceInstanceF port ); return pInstance; -} \ No newline at end of file +} + +NJGIS::SERVICE::NjModelInstanceStatus NJGIS::SERVICE::NjModelServiceInstanceFactory::convertString2Status( const char* cstatus ) +{ + std::string status = std::string(cstatus); + if(status == "RUNNING") + { + return NJGIS::SERVICE::NjModelInstanceStatus::INSTA_RUNNING; + } + else if(status == "REQUESTING") + { + return NJGIS::SERVICE::NjModelInstanceStatus::INSTA_REQUESTING; + } + else if(status == "HANGING") + { + return NJGIS::SERVICE::NjModelInstanceStatus::INSTA_HANGING; + } + return NJGIS::SERVICE::NjModelInstanceStatus::INSTA_UNKNOWN; +} diff --git a/src/NxModelServiceInstanceFactory.h b/src/NxModelServiceInstanceFactory.h index 17cb69f..6d79a3f 100644 --- a/src/NxModelServiceInstanceFactory.h +++ b/src/NxModelServiceInstanceFactory.h @@ -11,6 +11,8 @@ namespace NJGIS { public: static INjModelServiceInstance* createModelServiceInstacnce(Json::Value jsData, const char* ip, int port); + + static NjModelInstanceStatus convertString2Status(const char* cstatus); }; } } diff --git a/src/NxModelServiceRecord.cpp b/src/NxModelServiceRecord.cpp index 68498b1..d133673 100644 --- a/src/NxModelServiceRecord.cpp +++ b/src/NxModelServiceRecord.cpp @@ -99,7 +99,7 @@ int NJGIS::SERVICE::NjModelServiceRecord::refresh() //update log information Json::Value jLogs = jMsr["msr_logs"]; for(int i =0 ; i < jLogs.size(); i++){ - this->_list_log->push_back(NJRunningLogFactory::createRunningLogByJSON(jLogs[i],this->getIP(),this->getPort())); + this->_list_log->push_back(NJRunningLogFactory::createRunningLogByJSON(jLogs[i])); } } else{ return -1; @@ -107,3 +107,13 @@ int NJGIS::SERVICE::NjModelServiceRecord::refresh() return 1; } + +void NJGIS::SERVICE::NjModelServiceRecord::waitForFinished() +{ + +} + +const char* NJGIS::SERVICE::NjModelServiceRecord::getGUID() +{ + return this->_guid.c_str(); +} diff --git a/src/NxModelServiceRecord.h b/src/NxModelServiceRecord.h index 670d36c..3787a15 100644 --- a/src/NxModelServiceRecord.h +++ b/src/NxModelServiceRecord.h @@ -22,6 +22,7 @@ namespace NJGIS const char* msid, const char* datetime, double span, + const char* guid, INjDataConfiguration* input, INjDataConfiguration* output, NjRecordStatus status, @@ -35,6 +36,7 @@ namespace NJGIS _msid(msid), _datetime(datetime), _span(span), + _guid(guid), _input(input), _output(output), _status(status), @@ -74,6 +76,10 @@ namespace NJGIS virtual int refresh(); + virtual void waitForFinished(); + + virtual const char* getGUID(); + private: std::string _oid; @@ -83,6 +89,8 @@ namespace NJGIS double _span; + std::string _guid; + INjDataConfiguration* _input; INjDataConfiguration* _output; diff --git a/src/NxModelServiceRecordFactory.cpp b/src/NxModelServiceRecordFactory.cpp index f01617b..594fdb4 100644 --- a/src/NxModelServiceRecordFactory.cpp +++ b/src/NxModelServiceRecordFactory.cpp @@ -19,6 +19,7 @@ NJGIS::SERVICE::INjModelServiceRecord* NJGIS::SERVICE::NjModelServiceRecordFacto jMsr["ms_id"].asString().c_str(), jMsr["msr_datetime"].asString().c_str(), jMsr["msr_span"].asDouble(), + jMsr["msr_guid"].asCString(), pInput, pOutput, restatus, diff --git a/src/NxRunningLog.cpp b/src/NxRunningLog.cpp index fa8da44..3a716af 100644 --- a/src/NxRunningLog.cpp +++ b/src/NxRunningLog.cpp @@ -1,4 +1,5 @@ #include "NxRunningLog.h" +#include const char* NJGIS::SERVICE::NjRunningLog::getType() { @@ -30,3 +31,18 @@ const char* NJGIS::SERVICE::NjRunningLog::getDateTime() return this->_datetime.c_str(); } +bool NJGIS::SERVICE::NjRunningLog::getMark() +{ + return this->_mark; +} + +void NJGIS::SERVICE::NjRunningLog::setMark( bool mark ) +{ + this->_mark = mark; +} + +void NJGIS::SERVICE::NjRunningLog::print() +{ + std::cout << this->_type << " - " << this->_state << " - " << this->_event << " - " << this->_message << std::endl ; +} + diff --git a/src/NxRunningLog.h b/src/NxRunningLog.h index b782e04..212671f 100644 --- a/src/NxRunningLog.h +++ b/src/NxRunningLog.h @@ -7,10 +7,10 @@ namespace NJGIS { namespace SERVICE { - class NjRunningLog : public virtual INjRunningLog, public virtual NjService + class NjRunningLog : public virtual INjRunningLog { public: - NjRunningLog(){}; + NjRunningLog():_mark(false){}; NjRunningLog( const char* type, @@ -18,9 +18,7 @@ namespace NJGIS const char* event, int flag, const char* message, - const char* datetime, - const char* ip, - int port + const char* datetime ): _type(type), _state(state), @@ -28,7 +26,7 @@ namespace NJGIS _flag(flag), _message(message), _datetime(datetime), - NjService(ip,port) + _mark(false) {}; virtual const char* getType(); @@ -42,6 +40,12 @@ namespace NJGIS virtual const char* getDateTime(); + virtual bool getMark(); + + virtual void setMark( bool mark ); + + virtual void print(); + private: std::string _type; std::string _state; @@ -49,6 +53,7 @@ namespace NJGIS int _flag; std::string _message; std::string _datetime; + bool _mark; }; } } diff --git a/src/NxRunningLogFactory.cpp b/src/NxRunningLogFactory.cpp index 89e1cd2..cd240ef 100644 --- a/src/NxRunningLogFactory.cpp +++ b/src/NxRunningLogFactory.cpp @@ -1,7 +1,7 @@ #include "NxRunningLogFactory.h" #include "NxRunningLog.h" -NJGIS::SERVICE::INjRunningLog* NJGIS::SERVICE::NJRunningLogFactory::createRunningLogByJSON(Json::Value &JLog, const char* ip, int port){ +NJGIS::SERVICE::INjRunningLog* NJGIS::SERVICE::NJRunningLogFactory::createRunningLogByJSON(Json::Value &JLog){ std::string type = JLog["Type"].asString(); std::string state = JLog["State"].asString(); @@ -10,7 +10,16 @@ NJGIS::SERVICE::INjRunningLog* NJGIS::SERVICE::NJRunningLogFactory::createRunnin std::string message = JLog["Message"].asString(); std::string datetime = JLog["Datetime"].asString(); - INjRunningLog* pRl = new NjRunningLog(type.c_str(),state.c_str(),event.c_str(),flag,message.c_str(),datetime.c_str(),ip,port); + INjRunningLog* pRl = new NjRunningLog(type.c_str(),state.c_str(),event.c_str(),flag,message.c_str(),datetime.c_str()); return pRl; } + +void NJGIS::SERVICE::NJRunningLogFactory::convertJson2Logs( Json::Value jsLogs, std::vector* &logs ) +{ + for(int i = logs->size() ; i < jsLogs.size(); i++) + { + NJGIS::SERVICE::INjRunningLog* log = NJGIS::SERVICE::NJRunningLogFactory::createRunningLogByJSON(jsLogs[i]); + logs->push_back(log); + } +} diff --git a/src/NxRunningLogFactory.h b/src/NxRunningLogFactory.h index da328dd..65c12c6 100644 --- a/src/NxRunningLogFactory.h +++ b/src/NxRunningLogFactory.h @@ -11,9 +11,9 @@ namespace NJGIS class NJRunningLogFactory { public: - static INjRunningLog* createRunningLogByJSON(Json::Value &jLog, const char* ip, int port); - protected: - private: + static INjRunningLog* createRunningLogByJSON(Json::Value &jLog); + + static void convertJson2Logs(Json::Value jsLogs, std::vector* &logs); }; } } diff --git a/src/NxServiceAccess.cpp b/src/NxServiceAccess.cpp index fca9a8a..e2173c3 100644 --- a/src/NxServiceAccess.cpp +++ b/src/NxServiceAccess.cpp @@ -62,14 +62,15 @@ NJGIS::SERVICE::INjData* NJGIS::SERVICE::NjServiceAccess::getDataServiceByID( co { std::string url; this->getBaseUrl(url); - url = url + "modelser/json/" + id; + url = url + "geodata/json/" + id; Json::Value jResonese; NJGIS::SERVICE::NjHttpHelper::request_get_json_sync(url.c_str(), jResonese); + if(jResonese["result"].asString() == "suc") { Json::Value jData = jResonese["data"]; - if(jData.asString() == "") + if(jData.type() == Json::stringValue && jData.asString() == "") { return NULL; } @@ -150,7 +151,7 @@ NJGIS::SERVICE::INjModelServiceInstance* NJGIS::SERVICE::NjServiceAccess::getMod std::string url; this->getBaseUrl(url); - url += "modelserins/json/" + std::string(guid); + url += "modelins/json/" + std::string(guid); //NJGIS::SERVICE::INjModelServiceRecord* pRecord = NULL; Json::Value jResponse; diff --git a/test/test.cpp b/test/test.cpp index 726af6b..08aed12 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -16,9 +16,6 @@ int main() { std::cout <<"Hello My SDK!" << std::endl; NJGIS::SERVICE::INjServiceAccess* pServiceAccess = pServer->getServiceAccess(); - - - std::vector list_ms; pServiceAccess->getModelServicesList(list_ms); @@ -27,40 +24,25 @@ int main() if(list_ms[i] == NULL) continue; std::cout << list_ms[i]->getServiceOID() << " - " << list_ms[i]->getServiceName() << " - " << list_ms[i]->getServiceType() << std::endl; } - //ÉÏ´«Ä£ÐÍÔËÐÐÊý¾Ý - NJGIS::SERVICE::INjData* pData = pServiceAccess->uploadDataByFile("E:\\NativeTest\\TestData\\TouchAir\\input.xml","input.xml"); - if(pData != NULL){ + // upload data + NJGIS::SERVICE::INjData* pData = pServiceAccess->getDataServiceByID("gd_b3f13f70-4891-11e8-b000-3571b206c6be"); + + if(pData != NULL) + { std::cout << pData->getID() << " - " << pData->getSize() << " - " << pData->getGenarationDateTime() << " - " << pData->getTag() << std::endl; + NJGIS::SERVICE::INjModelService* pMservice = pServiceAccess->getModelServiceByOID("5ac9dbcdbe7b8d12c484952e"); NJGIS::SERVICE::INjDataConfiguration * pDataconfig = pServiceAccess->createDataConfig(); - pDataconfig->insertData("aa00cced-60e7-48a5-90d2-f91ac08b624d","InputData",pData->getID()); - NJGIS::SERVICE::INjModelService* pMservice = pServiceAccess->getModelServiceByOID("5aabaa522f89583c98ead293"); + pDataconfig->insertData("04579ee0-5983-4d75-bdc9-a1a460229aa0","LoadHydroResponseUnit",pData->getID()); std::string recordid; - //µ÷ÓÃÄ£ÐÍ - if(pMservice->invoke(pDataconfig,recordid) == 1 ){ - + // invoke model service + if(pMservice->invoke(pDataconfig, recordid) == 1 ) + { std::cout << "Invoke successfully! Model Service Record ID is : [" << recordid << "]" << std::endl; NJGIS::SERVICE::INjModelServiceRecord* pRecord = pServiceAccess->getModelServiceRecordByID(recordid.c_str()); - while(true){ - Sleep(2000); - //ˢмͼ - pRecord->refresh(); - std::cout << pRecord->getStatus() << std::endl; - - //²âÊԵõ½logsÐÅÏ¢¹¦ÄÜ - std::vector* list_logs; - list_logs = pRecord->getLogs(); - for (int j = 0; j < list_logs->size(); j++) - { - if((*list_logs)[j] == NULL)continue; - - std::cout<< (*list_logs)[j]->getType() << " - " << (*list_logs)[j]->getState() << " - " << (*list_logs)[j]->getEvent() << " - " << (*list_logs)[j]->getMessage() <getModelServiceInstanceByGUID(pRecord->getGUID()); + pInstance->wait4Status(NJGIS::SERVICE::NjModelInstanceStatus::INSTA_FINISHED, 7200, true); } - - } - } } diff --git a/utils/NxCommon.cpp b/utils/NxCommon.cpp new file mode 100644 index 0000000..f458d6d --- /dev/null +++ b/utils/NxCommon.cpp @@ -0,0 +1,18 @@ +#include "NxCommon.h" +#ifdef _WINDOWS +#include +#endif +#ifdef _LINUX +#include +#endif + +void NJGIS::SERVICE::NjCommonLibrary::sleep( double second ) +{ +#ifdef _WINDOWS + Sleep(second * 1000); +#endif +#ifdef _LINUX + sleep(second); +#endif +} + diff --git a/utils/NxCommon.h b/utils/NxCommon.h new file mode 100644 index 0000000..0cb1582 --- /dev/null +++ b/utils/NxCommon.h @@ -0,0 +1,16 @@ +#ifndef __NJGIS_COMMON_H__ +#define __NJGIS_COMMON_H__ + +namespace NJGIS +{ + namespace SERVICE + { + class NjCommonLibrary + { + public: + static void sleep(double second); + }; + } +} + +#endif \ No newline at end of file -- Gitee From b42f8edb7db6a2d6ab7be3ede888ef8dacdebd4a Mon Sep 17 00:00:00 2001 From: Franklin_Zhang Date: Wed, 2 May 2018 16:44:07 +0800 Subject: [PATCH 03/17] update CPP SDK interfaces about instance and record update Python SDK interfaces Signed-off-by: Franklin_Zhang --- include/INxModelServiceInstance.h | 2 +- include/INxModelServiceRecord.h | 2 +- src/NxData.cpp | 24 +- src/NxDataFactory.cpp | 42 +- src/NxDataFactory.h | 2 + src/NxModelServiceRecord.cpp | 2 +- src/NxModelServiceRecord.h | 2 +- swig/python/__init__.py | 2 + swig/python/data.py | 5 + swig/python/{modelser.py => modelserivce.py} | 37 - .../python/{modelser.pyc => modelserivce.pyc} | Bin 4005 -> 2319 bytes swig/python/modelserviceinstance.py | 84 ++ swig/python/modelserviceinstance.pyc | Bin 0 -> 3858 bytes swig/python/modelservicerecord.py | 41 + swig/python/modelservicerecord.pyc | Bin 0 -> 2211 bytes swig/python/requests/__init__.py | 121 +++ swig/python/requests/__init__.pyc | Bin 0 -> 4052 bytes swig/python/requests/__version__.py | 14 + swig/python/requests/__version__.pyc | Bin 0 -> 618 bytes swig/python/requests/_internal_utils.py | 42 + swig/python/requests/_internal_utils.pyc | Bin 0 -> 1628 bytes swig/python/requests/adapters.py | 525 ++++++++++ swig/python/requests/adapters.pyc | Bin 0 -> 19558 bytes swig/python/requests/api.py | 152 +++ swig/python/requests/api.pyc | Bin 0 -> 7339 bytes swig/python/requests/auth.py | 293 ++++++ swig/python/requests/auth.pyc | Bin 0 -> 10637 bytes swig/python/requests/certs.py | 18 + swig/python/requests/certs.pyc | Bin 0 -> 637 bytes swig/python/requests/compat.py | 69 ++ swig/python/requests/compat.pyc | Bin 0 -> 1907 bytes swig/python/requests/cookies.py | 542 ++++++++++ swig/python/requests/cookies.pyc | Bin 0 -> 24047 bytes swig/python/requests/exceptions.py | 122 +++ swig/python/requests/exceptions.pyc | Bin 0 -> 7650 bytes swig/python/requests/help.py | 120 +++ swig/python/requests/help.pyc | Bin 0 -> 3461 bytes swig/python/requests/hooks.py | 34 + swig/python/requests/hooks.pyc | Bin 0 -> 1359 bytes swig/python/requests/models.py | 948 ++++++++++++++++++ swig/python/requests/models.pyc | Bin 0 -> 30772 bytes swig/python/requests/packages.py | 14 + swig/python/requests/packages.pyc | Bin 0 -> 502 bytes swig/python/requests/sessions.py | 737 ++++++++++++++ swig/python/requests/sessions.pyc | Bin 0 -> 22678 bytes swig/python/requests/status_codes.py | 91 ++ swig/python/requests/status_codes.pyc | Bin 0 -> 4664 bytes swig/python/requests/structures.py | 105 ++ swig/python/requests/structures.pyc | Bin 0 -> 6008 bytes swig/python/requests/utils.py | 904 +++++++++++++++++ swig/python/requests/utils.pyc | Bin 0 -> 26811 bytes swig/python/runninglog.py | 31 + swig/python/runninglog.pyc | Bin 0 -> 1748 bytes swig/python/server.py | 16 +- swig/python/server.pyc | Bin 4638 -> 5290 bytes swig/python/test.py | 4 +- swig/python/test2.py | 8 + swig/python/utils.py | 6 +- swig/python/utils.pyc | Bin 1491 -> 1624 bytes test/test.cpp | 34 +- utils/NxHttp.cpp | 40 +- utils/NxHttp.h | 7 + 62 files changed, 5158 insertions(+), 84 deletions(-) create mode 100644 swig/python/__init__.py rename swig/python/{modelser.py => modelserivce.py} (53%) rename swig/python/{modelser.pyc => modelserivce.pyc} (34%) create mode 100644 swig/python/modelserviceinstance.py create mode 100644 swig/python/modelserviceinstance.pyc create mode 100644 swig/python/modelservicerecord.py create mode 100644 swig/python/modelservicerecord.pyc create mode 100644 swig/python/requests/__init__.py create mode 100644 swig/python/requests/__init__.pyc create mode 100644 swig/python/requests/__version__.py create mode 100644 swig/python/requests/__version__.pyc create mode 100644 swig/python/requests/_internal_utils.py create mode 100644 swig/python/requests/_internal_utils.pyc create mode 100644 swig/python/requests/adapters.py create mode 100644 swig/python/requests/adapters.pyc create mode 100644 swig/python/requests/api.py create mode 100644 swig/python/requests/api.pyc create mode 100644 swig/python/requests/auth.py create mode 100644 swig/python/requests/auth.pyc create mode 100644 swig/python/requests/certs.py create mode 100644 swig/python/requests/certs.pyc create mode 100644 swig/python/requests/compat.py create mode 100644 swig/python/requests/compat.pyc create mode 100644 swig/python/requests/cookies.py create mode 100644 swig/python/requests/cookies.pyc create mode 100644 swig/python/requests/exceptions.py create mode 100644 swig/python/requests/exceptions.pyc create mode 100644 swig/python/requests/help.py create mode 100644 swig/python/requests/help.pyc create mode 100644 swig/python/requests/hooks.py create mode 100644 swig/python/requests/hooks.pyc create mode 100644 swig/python/requests/models.py create mode 100644 swig/python/requests/models.pyc create mode 100644 swig/python/requests/packages.py create mode 100644 swig/python/requests/packages.pyc create mode 100644 swig/python/requests/sessions.py create mode 100644 swig/python/requests/sessions.pyc create mode 100644 swig/python/requests/status_codes.py create mode 100644 swig/python/requests/status_codes.pyc create mode 100644 swig/python/requests/structures.py create mode 100644 swig/python/requests/structures.pyc create mode 100644 swig/python/requests/utils.py create mode 100644 swig/python/requests/utils.pyc create mode 100644 swig/python/runninglog.py create mode 100644 swig/python/runninglog.pyc create mode 100644 swig/python/test2.py diff --git a/include/INxModelServiceInstance.h b/include/INxModelServiceInstance.h index cf69a0a..c9a823c 100644 --- a/include/INxModelServiceInstance.h +++ b/include/INxModelServiceInstance.h @@ -46,7 +46,7 @@ namespace NJGIS virtual int restart() = 0; - //! Defualt Timeout is 7200 seconds, if you need long, please set a larger value as you request. + //! Defualt Timeout is 7200 seconds, if you need longer, please set a larger value as you request. virtual int wait4Status(NJGIS::SERVICE::NjModelInstanceStatus status, double timeout = 7200, bool log = false) = 0; virtual int refresh() = 0; diff --git a/include/INxModelServiceRecord.h b/include/INxModelServiceRecord.h index 6c868f2..9ee8701 100644 --- a/include/INxModelServiceRecord.h +++ b/include/INxModelServiceRecord.h @@ -49,7 +49,7 @@ namespace NJGIS virtual std::vector* getLogs() = 0; - virtual void waitForFinished() = 0; + virtual void wait4Finished() = 0; virtual int refresh() = 0; }; diff --git a/src/NxData.cpp b/src/NxData.cpp index 5bfd5f6..d33eb41 100644 --- a/src/NxData.cpp +++ b/src/NxData.cpp @@ -1,8 +1,25 @@ #include "NxData.h" +#include "../utils/NxHttp.h" +#include "NxDataFactory.h" int NJGIS::SERVICE::NjData::isExist() { - return 0; + std::string url; + this->getBaseUrl(url); + url = url + "geodata/json/" + this->_id; + Json::Value jResonese; + NJGIS::SERVICE::NjHttpHelper::request_get_json_sync(url.c_str(), jResonese); + + if(jResonese["result"].asString() == "suc") + { + Json::Value jData = jResonese["data"]; + if(jData.type() == Json::stringValue && jData.asString() == "") + { + return false; + } + return true; + } + return false; } const char* NJGIS::SERVICE::NjData::getID() @@ -37,5 +54,8 @@ const char* NJGIS::SERVICE::NjData::getValue() int NJGIS::SERVICE::NjData::saveAs( const char* path ) { - return NULL; + std::string url; + this->getBaseUrl(url); + url = url + "geodata/" + this->_id; + return NJGIS::SERVICE::NjHttpHelper::download(url.c_str(), path); } \ No newline at end of file diff --git a/src/NxDataFactory.cpp b/src/NxDataFactory.cpp index d84b089..ecf8643 100644 --- a/src/NxDataFactory.cpp +++ b/src/NxDataFactory.cpp @@ -9,24 +9,7 @@ NJGIS::SERVICE::INjData* NJGIS::SERVICE::NjDataFactory::createDataByJSON( Json:: std::string gd_tag = jData["gd_tag"].asString(); std::string gd_datetime = jData["gd_datetime"].asString(); std::string gd_type = jData["gd_type"].asString(); - NJGIS::SERVICE::NjDataType type; - if (gd_type == "XML") - { - type = NJGIS::SERVICE::NjDataType::DAT_XML; - } - else if (gd_type == "ZIP") - { - type = NJGIS::SERVICE::NjDataType::DAT_ZIP; - } - else if (gd_type == "RAW") - { - type = NJGIS::SERVICE::NjDataType::DAT_RAW; - } - else - { - type = NJGIS::SERVICE::NjDataType::DAT_UNKNOWN; - } - // int gd_size = jData["gd_size"].asInt(); + NJGIS::SERVICE::NjDataType type = NJGIS::SERVICE::NjDataFactory::convertString2DataType(gd_type.c_str()); std::string sszie = jData["gd_size"].asString(); int gd_size = atoi(sszie.c_str()); std::string gd_value = jData["gd_value"].asString(); @@ -47,3 +30,26 @@ NJGIS::SERVICE::INjDataConfiguration* NJGIS::SERVICE::NjDataFactory::createDataC } return pDataConfig; } + +NJGIS::SERVICE::NjDataType NJGIS::SERVICE::NjDataFactory::convertString2DataType( const char* ctype ) +{ + NJGIS::SERVICE::NjDataType type; + std::string stype(ctype); + if (stype == "XML") + { + type = NJGIS::SERVICE::NjDataType::DAT_XML; + } + else if (stype == "ZIP") + { + type = NJGIS::SERVICE::NjDataType::DAT_ZIP; + } + else if (stype == "RAW") + { + type = NJGIS::SERVICE::NjDataType::DAT_RAW; + } + else + { + type = NJGIS::SERVICE::NjDataType::DAT_UNKNOWN; + } + return type; +} diff --git a/src/NxDataFactory.h b/src/NxDataFactory.h index 338c96d..5d652f9 100644 --- a/src/NxDataFactory.h +++ b/src/NxDataFactory.h @@ -15,6 +15,8 @@ namespace NJGIS static NJGIS::SERVICE::INjData* createDataByJSON(Json::Value &jData, const char* ip, int port); static NJGIS::SERVICE::INjDataConfiguration* createDataConfigByJSON(Json::Value &jConfig); + + static NJGIS::SERVICE::NjDataType convertString2DataType(const char* ctype); }; } } diff --git a/src/NxModelServiceRecord.cpp b/src/NxModelServiceRecord.cpp index d133673..c3685ee 100644 --- a/src/NxModelServiceRecord.cpp +++ b/src/NxModelServiceRecord.cpp @@ -108,7 +108,7 @@ int NJGIS::SERVICE::NjModelServiceRecord::refresh() return 1; } -void NJGIS::SERVICE::NjModelServiceRecord::waitForFinished() +void NJGIS::SERVICE::NjModelServiceRecord::wait4Finished() { } diff --git a/src/NxModelServiceRecord.h b/src/NxModelServiceRecord.h index 3787a15..43106bf 100644 --- a/src/NxModelServiceRecord.h +++ b/src/NxModelServiceRecord.h @@ -76,7 +76,7 @@ namespace NJGIS virtual int refresh(); - virtual void waitForFinished(); + virtual void wait4Finished(); virtual const char* getGUID(); diff --git a/swig/python/__init__.py b/swig/python/__init__.py new file mode 100644 index 0000000..fcd657b --- /dev/null +++ b/swig/python/__init__.py @@ -0,0 +1,2 @@ +from setup import OGMSService_DEBUG + diff --git a/swig/python/data.py b/swig/python/data.py index 3a1d0dd..321e8a2 100644 --- a/swig/python/data.py +++ b/swig/python/data.py @@ -14,6 +14,11 @@ class Data(Service): self.datetime = datetime def isExist(self): + jsData = HttpHelper.Request_get_sync(self.ip, self.port, "/geodata/json/" + self.id) + if jsData["result"] == "suc" : + if jsData["result"]["data"] == "": + return False + return True return False def save(self, filepath): diff --git a/swig/python/modelser.py b/swig/python/modelserivce.py similarity index 53% rename from swig/python/modelser.py rename to swig/python/modelserivce.py index 443499e..563c570 100644 --- a/swig/python/modelser.py +++ b/swig/python/modelserivce.py @@ -5,7 +5,6 @@ from base import Service from data import DataConfigrationItem - class ModelService(Service): def __init__(self, ip, port, id, name, type, url, pid, mid, registered, description, version, platform, deploymenttime, img, deployorname, deployoremail, status, limitation, permission): Service.__init__(self, ip, port) @@ -48,39 +47,3 @@ class ModelService(Service): return 1 return -1 - -class ModelServiceRunningRecord(Service): - def __init__(self, ip, port, id, msid, status = 1, inputs = [], outputs = [], timespan = 0.0, standout = '', standerr = '', invokeerr = '', logs = []): - Service.__init__(self, ip, port) - self.id = id - self.msid = msid - self.status = status - self.inputs = inputs - self.outputs = outputs - self.timespan = timespan - self.standout = standout - self.standerr = standerr - self.invokeerr = invokeerr - self.logs = logs - - def waitForFinished(self): - self.refresh() - while self.status == 0: - time.sleep(3) - self.refresh() - return 1 - - def refresh(self): - jsData = HttpHelper.Request_get_sync(self.ip, self.port, "/modelserrun/json/" + self.id) - if jsData["result"] == "suc": - self.status = int(jsData["data"]["msr_status"]) - self.timespan = float(jsData["data"]["msr_span"]) - self.standout = jsData["data"]["msr_runninginfo"]["StdErr"] - self.standerr = jsData["data"]["msr_runninginfo"]["StdOut"] - self.invokeerr = jsData["data"]["msr_runninginfo"]["InvokeErr"] - self.inputs = [] - for index, item in enumerate(jsData["data"]["msr_input"]): - self.inputs.append(DataConfigrationItem.MakeUpDataItem(item)) - self.outputs = [] - for index, item in enumerate(jsData["data"]["msr_output"]): - self.outputs.append(DataConfigrationItem.MakeUpDataItem(item)) \ No newline at end of file diff --git a/swig/python/modelser.pyc b/swig/python/modelserivce.pyc similarity index 34% rename from swig/python/modelser.pyc rename to swig/python/modelserivce.pyc index c62e2a1ae5d3ee673d0df48ba043da81b49fb430..129a64ab0e6728aeb781ea845a7efc03c584344f 100644 GIT binary patch delta 277 zcmZ1~-!CN1{F#?4f~5v1EI{a zlK+7^<>_4X7$JuPi@1Rd%x@n>!=IFcFv% zcA%1?)U=}1;tY++XW1hVN;F~ifn3G`vJYe&8zZL(C$|QOUjlMSNoH>9WFCGUQ4Ju6 j0YMbQ-K`3<3Z%y-H$SB`C)JJ-$Swv6@GuE50wFU1?b|t= delta 1680 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 V-(OKJo$+Uo@A!meAf$f6zW~Mq^U(kR literal 0 HcmV?d00001 diff --git a/swig/python/modelservicerecord.py b/swig/python/modelservicerecord.py new file mode 100644 index 0000000..8508001 --- /dev/null +++ b/swig/python/modelservicerecord.py @@ -0,0 +1,41 @@ +import time +from utils import HttpHelper +from base import Service +from data import DataConfigrationItem + +class ModelServiceRunningRecord(Service): + def __init__(self, ip, port, id, msid, guid, status = 1, inputs = [], outputs = [], timespan = 0.0, standout = '', standerr = '', invokeerr = '', logs = []): + Service.__init__(self, ip, port) + self.id = id + self.msid = msid + self.guid = guid + self.status = status + self.inputs = inputs + self.outputs = outputs + self.timespan = timespan + self.standout = standout + self.standerr = standerr + self.invokeerr = invokeerr + self.logs = logs + + def wait4Finished(self): + self.refresh() + while self.status == 0: + time.sleep(2) + self.refresh() + return 1 + + def refresh(self): + jsData = HttpHelper.Request_get_sync(self.ip, self.port, "/modelserrun/json/" + self.id) + if jsData["result"] == "suc": + self.status = int(jsData["data"]["msr_status"]) + self.timespan = float(jsData["data"]["msr_span"]) + self.standout = jsData["data"]["msr_runninginfo"]["StdErr"] + self.standerr = jsData["data"]["msr_runninginfo"]["StdOut"] + self.invokeerr = jsData["data"]["msr_runninginfo"]["InvokeErr"] + self.inputs = [] + for index, item in enumerate(jsData["data"]["msr_input"]): + self.inputs.append(DataConfigrationItem.MakeUpDataItem(item)) + self.outputs = [] + for index, item in enumerate(jsData["data"]["msr_output"]): + self.outputs.append(DataConfigrationItem.MakeUpDataItem(item)) \ No newline at end of file diff --git a/swig/python/modelservicerecord.pyc b/swig/python/modelservicerecord.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe4c039400eaecdd9be8e8b21bb2bc4976198202 GIT binary patch literal 2211 zcmb_dQEwYX5T3O!cI?<`(ozK@cnA`b#REa8;(?+FkpL~IL0StUELW$)w|3S!?_F;9 z+61Lf?cd@D@yri^Z{{2~4|$C5c04mXH#ajo-(2(Ges|}qf5uZ<{hIjy4$J=zlHyjB z5shoUL7AdugT@U~yw{|xNy~`FQ7uQ5ZP2ns;}+x%G7-%br7e0#^p@z4ahu(ZhHbdE z|KWEsRA56FcHxIEdLb5AR`1uG?yDerH$1M4bpnI$vLJGM?P*6a$zPSJsP&~ zyydWAS^on6O}9aKMOa5z{x1-0Efif7U4u60ZIje>ljXQU*O4#~H-v%M5(Z*h7>Jv~ zKrpJkmq-ZC@K7!CvT(xWEF;U5efJf+@?u^|tO+er{Oe7iIa}54l1jd6UiR zFba{2ybPM(uK8t}9c%WXxjFO}lO7XEh`s0sOm;wqST*s7;LJCZpKLfnM@&wBzTFt3 z<6kEJwVh9jt8kXP$&#DK*F9EBw|r4t=?%Ex5d4QAq#mix9oLjg%8Lsrr_F7Jb6rTM ztIN+tKwl|3Z&3L)A=d>O2|b|D18c*JKAoc9MnkU9i3K4mhr`ZADa9|%tTg^iDkA0L z69^ot&x|SLu=OrKf^~1T2wd#fi49MFMBn%`lRk#R^NEn^s)wqtww08EqvvR(6i*QQ zy73oibYzRv1qX|W_JD#n5Cn7sB+muREGu`g@VPq>IHCutEQBU3 zd^MFuNHG#+fG&L*uaL{&5s@LvFku0ncr02s%f;6yq(12Em=K@*YV2PiT z5wLzkJq3mwqsF4Z0MzE9GCss}6JmemrdqZi@eaF}c&!U{_i~%evOEcQ;+cC(UTs{p zG??;6B20?HxKuMT0)ziWa&CSr_;bLY02vPg7Qui#vGBYr5V0;bmr^VX<9kJj=C9Jn zSpFjrQlF|FwTJ7mTphKqKEd?ZS3}NP24oz&WN9#hIny}CIae7(89RCpI&t|vNa5~d zu5r`IbZ631``exNkQ+rarln3*u$iw>> import requests + >>> r = requests.get('https://www.python.org') + >>> r.status_code + 200 + >>> 'Python is a programming language' in r.content + True + +... or POST: + + >>> payload = dict(key1='value1', key2='value2') + >>> r = requests.post('http://httpbin.org/post', data=payload) + >>> print(r.text) + { + ... + "form": { + "key2": "value2", + "key1": "value1" + }, + ... + } + +The other HTTP methods are supported - see `requests.api`. Full documentation +is at . + +:copyright: (c) 2017 by Kenneth Reitz. +:license: Apache 2.0, see LICENSE for more details. +""" + +import urllib3 +import chardet +import warnings +from .exceptions import RequestsDependencyWarning + + +def check_compatibility(urllib3_version, chardet_version): + urllib3_version = urllib3_version.split('.') + assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git. + + # Sometimes, urllib3 only reports its version as 16.1. + if len(urllib3_version) == 2: + urllib3_version.append('0') + + # Check urllib3 for compatibility. + major, minor, patch = urllib3_version # noqa: F811 + major, minor, patch = int(major), int(minor), int(patch) + # urllib3 >= 1.21.1, <= 1.22 + assert major == 1 + assert minor >= 21 + assert minor <= 22 + + # Check chardet for compatibility. + major, minor, patch = chardet_version.split('.')[:3] + major, minor, patch = int(major), int(minor), int(patch) + # chardet >= 3.0.2, < 3.1.0 + assert major == 3 + assert minor < 1 + assert patch >= 2 + + +# Check imported dependencies for compatibility. +try: + check_compatibility(urllib3.__version__, chardet.__version__) +except (AssertionError, ValueError): + warnings.warn("urllib3 ({0}) or chardet ({1}) doesn't match a supported " + "version!".format(urllib3.__version__, chardet.__version__), + RequestsDependencyWarning) + +# Attempt to enable urllib3's SNI support, if possible +try: + from urllib3.contrib import pyopenssl + pyopenssl.inject_into_urllib3() +except ImportError: + pass + +# urllib3's DependencyWarnings should be silenced. +from urllib3.exceptions import DependencyWarning +warnings.simplefilter('ignore', DependencyWarning) + +from .__version__ import __title__, __description__, __url__, __version__ +from .__version__ import __build__, __author__, __author_email__, __license__ +from .__version__ import __copyright__, __cake__ + +from . import utils +from . import packages +from .models import Request, Response, PreparedRequest +from .api import request, get, head, post, patch, put, delete, options +from .sessions import session, Session +from .status_codes import codes +from .exceptions import ( + RequestException, Timeout, URLRequired, + TooManyRedirects, HTTPError, ConnectionError, + FileModeWarning, ConnectTimeout, ReadTimeout +) + +# Set default logging handler to avoid "No handler found" warnings. +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +logging.getLogger(__name__).addHandler(NullHandler()) + +# FileModeWarnings go off per the default. +warnings.simplefilter('default', FileModeWarning, append=True) diff --git a/swig/python/requests/__init__.pyc b/swig/python/requests/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb244b93e47cb0d144e43c54833e1377de2307ec GIT binary patch literal 4052 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 T>KnL!o%F!3<}~>*y>aU=EKS7O literal 0 HcmV?d00001 diff --git a/swig/python/requests/adapters.py b/swig/python/requests/adapters.py new file mode 100644 index 0000000..00f8792 --- /dev/null +++ b/swig/python/requests/adapters.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- + +""" +requests.adapters +~~~~~~~~~~~~~~~~~ + +This module contains the transport adapters that Requests uses to define +and maintain connections. +""" + +import os.path +import socket + +from urllib3.poolmanager import PoolManager, proxy_from_url +from urllib3.response import HTTPResponse +from urllib3.util import Timeout as TimeoutSauce +from urllib3.util.retry import Retry +from urllib3.exceptions import ClosedPoolError +from urllib3.exceptions import ConnectTimeoutError +from urllib3.exceptions import HTTPError as _HTTPError +from urllib3.exceptions import MaxRetryError +from urllib3.exceptions import NewConnectionError +from urllib3.exceptions import ProxyError as _ProxyError +from urllib3.exceptions import ProtocolError +from urllib3.exceptions import ReadTimeoutError +from urllib3.exceptions import SSLError as _SSLError +from urllib3.exceptions import ResponseError + +from .models import Response +from .compat import urlparse, basestring +from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers, + prepend_scheme_if_needed, get_auth_from_url, urldefragauth, + select_proxy) +from .structures import CaseInsensitiveDict +from .cookies import extract_cookies_to_jar +from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError, + ProxyError, RetryError, InvalidSchema) +from .auth import _basic_auth_str + +try: + from urllib3.contrib.socks import SOCKSProxyManager +except ImportError: + def SOCKSProxyManager(*args, **kwargs): + raise InvalidSchema("Missing dependencies for SOCKS support.") + +DEFAULT_POOLBLOCK = False +DEFAULT_POOLSIZE = 10 +DEFAULT_RETRIES = 0 +DEFAULT_POOL_TIMEOUT = None + + +class BaseAdapter(object): + """The Base Transport Adapter""" + + def __init__(self): + super(BaseAdapter, self).__init__() + + def send(self, request, stream=False, timeout=None, verify=True, + cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest ` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) ` tuple. + :type timeout: float or tuple + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + """ + raise NotImplementedError + + def close(self): + """Cleans up adapter specific items.""" + raise NotImplementedError + + +class HTTPAdapter(BaseAdapter): + """The built-in HTTP Adapter for urllib3. + + Provides a general-case interface for Requests sessions to contact HTTP and + HTTPS urls by implementing the Transport Adapter interface. This class will + usually be created by the :class:`Session ` class under the + covers. + + :param pool_connections: The number of urllib3 connection pools to cache. + :param pool_maxsize: The maximum number of connections to save in the pool. + :param max_retries: The maximum number of retries each connection + should attempt. Note, this applies only to failed DNS lookups, socket + connections and connection timeouts, never to requests where data has + made it to the server. By default, Requests does not retry failed + connections. If you need granular control over the conditions under + which we retry a request, import urllib3's ``Retry`` class and pass + that instead. + :param pool_block: Whether the connection pool should block for connections. + + Usage:: + + >>> import requests + >>> s = requests.Session() + >>> a = requests.adapters.HTTPAdapter(max_retries=3) + >>> s.mount('http://', a) + """ + __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', + '_pool_block'] + + def __init__(self, pool_connections=DEFAULT_POOLSIZE, + pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, + pool_block=DEFAULT_POOLBLOCK): + if max_retries == DEFAULT_RETRIES: + self.max_retries = Retry(0, read=False) + else: + self.max_retries = Retry.from_int(max_retries) + self.config = {} + self.proxy_manager = {} + + super(HTTPAdapter, self).__init__() + + self._pool_connections = pool_connections + self._pool_maxsize = pool_maxsize + self._pool_block = pool_block + + self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) + + def __getstate__(self): + return dict((attr, getattr(self, attr, None)) for attr in + self.__attrs__) + + def __setstate__(self, state): + # Can't handle by adding 'proxy_manager' to self.__attrs__ because + # self.poolmanager uses a lambda function, which isn't pickleable. + self.proxy_manager = {} + self.config = {} + + for attr, value in state.items(): + setattr(self, attr, value) + + self.init_poolmanager(self._pool_connections, self._pool_maxsize, + block=self._pool_block) + + def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs): + """Initializes a urllib3 PoolManager. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param connections: The number of urllib3 connection pools to cache. + :param maxsize: The maximum number of connections to save in the pool. + :param block: Block when no free connections are available. + :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. + """ + # save these values for pickling + self._pool_connections = connections + self._pool_maxsize = maxsize + self._pool_block = block + + self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, + block=block, strict=True, **pool_kwargs) + + def proxy_manager_for(self, proxy, **proxy_kwargs): + """Return urllib3 ProxyManager for the given proxy. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param proxy: The proxy to return a urllib3 ProxyManager for. + :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. + :returns: ProxyManager + :rtype: urllib3.ProxyManager + """ + if proxy in self.proxy_manager: + manager = self.proxy_manager[proxy] + elif proxy.lower().startswith('socks'): + username, password = get_auth_from_url(proxy) + manager = self.proxy_manager[proxy] = SOCKSProxyManager( + proxy, + username=username, + password=password, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs + ) + else: + proxy_headers = self.proxy_headers(proxy) + manager = self.proxy_manager[proxy] = proxy_from_url( + proxy, + proxy_headers=proxy_headers, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs) + + return manager + + def cert_verify(self, conn, url, verify, cert): + """Verify a SSL certificate. This method should not be called from user + code, and is only exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param conn: The urllib3 connection object associated with the cert. + :param url: The requested URL. + :param verify: Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: The SSL certificate to verify. + """ + if url.lower().startswith('https') and verify: + + cert_loc = None + + # Allow self-specified cert location. + if verify is not True: + cert_loc = verify + + if not cert_loc: + cert_loc = DEFAULT_CA_BUNDLE_PATH + + if not cert_loc or not os.path.exists(cert_loc): + raise IOError("Could not find a suitable TLS CA certificate bundle, " + "invalid path: {0}".format(cert_loc)) + + conn.cert_reqs = 'CERT_REQUIRED' + + if not os.path.isdir(cert_loc): + conn.ca_certs = cert_loc + else: + conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + conn.ca_cert_dir = None + + if cert: + if not isinstance(cert, basestring): + conn.cert_file = cert[0] + conn.key_file = cert[1] + else: + conn.cert_file = cert + conn.key_file = None + if conn.cert_file and not os.path.exists(conn.cert_file): + raise IOError("Could not find the TLS certificate file, " + "invalid path: {0}".format(conn.cert_file)) + if conn.key_file and not os.path.exists(conn.key_file): + raise IOError("Could not find the TLS key file, " + "invalid path: {0}".format(conn.key_file)) + + def build_response(self, req, resp): + """Builds a :class:`Response ` object from a urllib3 + response. This should not be called from user code, and is only exposed + for use when subclassing the + :class:`HTTPAdapter ` + + :param req: The :class:`PreparedRequest ` used to generate the response. + :param resp: The urllib3 response object. + :rtype: requests.Response + """ + response = Response() + + # Fallback to None if there's no status_code, for whatever reason. + response.status_code = getattr(resp, 'status', None) + + # Make headers case-insensitive. + response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {})) + + # Set encoding. + response.encoding = get_encoding_from_headers(response.headers) + response.raw = resp + response.reason = response.raw.reason + + if isinstance(req.url, bytes): + response.url = req.url.decode('utf-8') + else: + response.url = req.url + + # Add new cookies from the server. + extract_cookies_to_jar(response.cookies, req, resp) + + # Give the Response some context. + response.request = req + response.connection = self + + return response + + def get_connection(self, url, proxies=None): + """Returns a urllib3 connection for the given URL. This should not be + called from user code, and is only exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param url: The URL to connect to. + :param proxies: (optional) A Requests-style dictionary of proxies used on this request. + :rtype: urllib3.ConnectionPool + """ + proxy = select_proxy(url, proxies) + + if proxy: + proxy = prepend_scheme_if_needed(proxy, 'http') + proxy_manager = self.proxy_manager_for(proxy) + conn = proxy_manager.connection_from_url(url) + else: + # Only scheme should be lower case + parsed = urlparse(url) + url = parsed.geturl() + conn = self.poolmanager.connection_from_url(url) + + return conn + + def close(self): + """Disposes of any internal state. + + Currently, this closes the PoolManager and any active ProxyManager, + which closes any pooled connections. + """ + self.poolmanager.clear() + for proxy in self.proxy_manager.values(): + proxy.clear() + + def request_url(self, request, proxies): + """Obtain the url to use when making the final request. + + If the message is being sent through a HTTP proxy, the full URL has to + be used. Otherwise, we should only use the path portion of the URL. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter `. + + :param request: The :class:`PreparedRequest ` being sent. + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. + :rtype: str + """ + proxy = select_proxy(request.url, proxies) + scheme = urlparse(request.url).scheme + + is_proxied_http_request = (proxy and scheme != 'https') + using_socks_proxy = False + if proxy: + proxy_scheme = urlparse(proxy).scheme.lower() + using_socks_proxy = proxy_scheme.startswith('socks') + + url = request.path_url + if is_proxied_http_request and not using_socks_proxy: + url = urldefragauth(request.url) + + return url + + def add_headers(self, request, **kwargs): + """Add any headers needed by the connection. As of v2.0 this does + nothing by default, but is left for overriding by users that subclass + the :class:`HTTPAdapter `. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter `. + + :param request: The :class:`PreparedRequest ` to add headers to. + :param kwargs: The keyword arguments from the call to send(). + """ + pass + + def proxy_headers(self, proxy): + """Returns a dictionary of the headers to add to any request sent + through a proxy. This works with urllib3 magic to ensure that they are + correctly sent to the proxy, rather than in a tunnelled request if + CONNECT is being used. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter `. + + :param proxies: The url of the proxy being used for this request. + :rtype: dict + """ + headers = {} + username, password = get_auth_from_url(proxy) + + if username: + headers['Proxy-Authorization'] = _basic_auth_str(username, + password) + + return headers + + def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest ` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) ` tuple. + :type timeout: float or tuple or urllib3 Timeout object + :param verify: (optional) Either a boolean, in which case it controls whether + we verify the server's TLS certificate, or a string, in which case it + must be a path to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + :rtype: requests.Response + """ + + conn = self.get_connection(request.url, proxies) + + self.cert_verify(conn, request.url, verify, cert) + url = self.request_url(request, proxies) + self.add_headers(request) + + chunked = not (request.body is None or 'Content-Length' in request.headers) + + if isinstance(timeout, tuple): + try: + connect, read = timeout + timeout = TimeoutSauce(connect=connect, read=read) + except ValueError as e: + # this may raise a string formatting error. + err = ("Invalid timeout {0}. Pass a (connect, read) " + "timeout tuple, or a single float to set " + "both timeouts to the same value".format(timeout)) + raise ValueError(err) + elif isinstance(timeout, TimeoutSauce): + pass + else: + timeout = TimeoutSauce(connect=timeout, read=timeout) + + try: + if not chunked: + resp = conn.urlopen( + method=request.method, + url=url, + body=request.body, + headers=request.headers, + redirect=False, + assert_same_host=False, + preload_content=False, + decode_content=False, + retries=self.max_retries, + timeout=timeout + ) + + # Send the request. + else: + if hasattr(conn, 'proxy_pool'): + conn = conn.proxy_pool + + low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT) + + try: + low_conn.putrequest(request.method, + url, + skip_accept_encoding=True) + + for header, value in request.headers.items(): + low_conn.putheader(header, value) + + low_conn.endheaders() + + for i in request.body: + low_conn.send(hex(len(i))[2:].encode('utf-8')) + low_conn.send(b'\r\n') + low_conn.send(i) + low_conn.send(b'\r\n') + low_conn.send(b'0\r\n\r\n') + + # Receive the response from the server + try: + # For Python 2.7+ versions, use buffering of HTTP + # responses + r = low_conn.getresponse(buffering=True) + except TypeError: + # For compatibility with Python 2.6 versions and back + r = low_conn.getresponse() + + resp = HTTPResponse.from_httplib( + r, + pool=conn, + connection=low_conn, + preload_content=False, + decode_content=False + ) + except: + # If we hit any problems here, clean up the connection. + # Then, reraise so that we can handle the actual exception. + low_conn.close() + raise + + except (ProtocolError, socket.error) as err: + raise ConnectionError(err, request=request) + + except MaxRetryError as e: + if isinstance(e.reason, ConnectTimeoutError): + # TODO: Remove this in 3.0.0: see #2811 + if not isinstance(e.reason, NewConnectionError): + raise ConnectTimeout(e, request=request) + + if isinstance(e.reason, ResponseError): + raise RetryError(e, request=request) + + if isinstance(e.reason, _ProxyError): + raise ProxyError(e, request=request) + + if isinstance(e.reason, _SSLError): + # This branch is for urllib3 v1.22 and later. + raise SSLError(e, request=request) + + raise ConnectionError(e, request=request) + + except ClosedPoolError as e: + raise ConnectionError(e, request=request) + + except _ProxyError as e: + raise ProxyError(e) + + except (_SSLError, _HTTPError) as e: + if isinstance(e, _SSLError): + # This branch is for urllib3 versions earlier than v1.22 + raise SSLError(e, request=request) + elif isinstance(e, ReadTimeoutError): + raise ReadTimeout(e, request=request) + else: + raise + + return self.build_response(request, resp) diff --git a/swig/python/requests/adapters.pyc b/swig/python/requests/adapters.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cf4f2a2e0a631b5d9c241c16b30949b35d8693a GIT binary patch literal 19558 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. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. + :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. + ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` + or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string + defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers + to add for the file. + :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How many seconds to wait for the server to send data + before giving up, as a float, or a :ref:`(connect timeout, read + timeout) ` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param stream: (optional) if ``False``, the response content will be immediately downloaded. + :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. + :return: :class:`Response ` object + :rtype: requests.Response + + Usage:: + + >>> import requests + >>> req = requests.request('GET', 'http://httpbin.org/get') + + """ + + # By using the 'with' statement we are sure the session is closed, thus we + # avoid leaving sockets open which can trigger a ResourceWarning in some + # cases, and look like a memory leak in others. + with sessions.Session() as session: + return session.request(method=method, url=url, **kwargs) + + +def get(url, params=None, **kwargs): + r"""Sends a GET request. + + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('get', url, params=params, **kwargs) + + +def options(url, **kwargs): + r"""Sends an OPTIONS request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('options', url, **kwargs) + + +def head(url, **kwargs): + r"""Sends a HEAD request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return request('head', url, **kwargs) + + +def post(url, data=None, json=None, **kwargs): + r"""Sends a POST request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request('post', url, data=data, json=json, **kwargs) + + +def put(url, data=None, **kwargs): + r"""Sends a PUT request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request('put', url, data=data, **kwargs) + + +def patch(url, data=None, **kwargs): + r"""Sends a PATCH request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request('patch', url, data=data, **kwargs) + + +def delete(url, **kwargs): + r"""Sends a DELETE request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request('delete', url, **kwargs) diff --git a/swig/python/requests/api.pyc b/swig/python/requests/api.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57f021ac25a7ea1ce36bcfdbbfecc04ea1f1afde GIT binary patch literal 7339 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 Qt>k}w`wd#Rzq+;hUp`Z)i2wiq literal 0 HcmV?d00001 diff --git a/swig/python/requests/help.py b/swig/python/requests/help.py new file mode 100644 index 0000000..5440ee6 --- /dev/null +++ b/swig/python/requests/help.py @@ -0,0 +1,120 @@ +"""Module containing bug report helper(s).""" +from __future__ import print_function + +import json +import platform +import sys +import ssl + +import idna +import urllib3 +import chardet + +from . import __version__ as requests_version + +try: + from .packages.urllib3.contrib import pyopenssl +except ImportError: + pyopenssl = None + OpenSSL = None + cryptography = None +else: + import OpenSSL + import cryptography + + +def _implementation(): + """Return a dict with the Python implementation and version. + + Provide both the name and the version of the Python implementation + currently running. For example, on CPython 2.7.5 it will return + {'name': 'CPython', 'version': '2.7.5'}. + + This function works best on CPython and PyPy: in particular, it probably + doesn't work for Jython or IronPython. Future investigation should be done + to work out the correct shape of the code for those platforms. + """ + implementation = platform.python_implementation() + + if implementation == 'CPython': + implementation_version = platform.python_version() + elif implementation == 'PyPy': + implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major, + sys.pypy_version_info.minor, + sys.pypy_version_info.micro) + if sys.pypy_version_info.releaselevel != 'final': + implementation_version = ''.join([ + implementation_version, sys.pypy_version_info.releaselevel + ]) + elif implementation == 'Jython': + implementation_version = platform.python_version() # Complete Guess + elif implementation == 'IronPython': + implementation_version = platform.python_version() # Complete Guess + else: + implementation_version = 'Unknown' + + return {'name': implementation, 'version': implementation_version} + + +def info(): + """Generate information for a bug report.""" + try: + platform_info = { + 'system': platform.system(), + 'release': platform.release(), + } + except IOError: + platform_info = { + 'system': 'Unknown', + 'release': 'Unknown', + } + + implementation_info = _implementation() + urllib3_info = {'version': urllib3.__version__} + chardet_info = {'version': chardet.__version__} + + pyopenssl_info = { + 'version': None, + 'openssl_version': '', + } + if OpenSSL: + pyopenssl_info = { + 'version': OpenSSL.__version__, + 'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER, + } + cryptography_info = { + 'version': getattr(cryptography, '__version__', ''), + } + idna_info = { + 'version': getattr(idna, '__version__', ''), + } + + # OPENSSL_VERSION_NUMBER doesn't exist in the Python 2.6 ssl module. + system_ssl = getattr(ssl, 'OPENSSL_VERSION_NUMBER', None) + system_ssl_info = { + 'version': '%x' % system_ssl if system_ssl is not None else '' + } + + return { + 'platform': platform_info, + 'implementation': implementation_info, + 'system_ssl': system_ssl_info, + 'using_pyopenssl': pyopenssl is not None, + 'pyOpenSSL': pyopenssl_info, + 'urllib3': urllib3_info, + 'chardet': chardet_info, + 'cryptography': cryptography_info, + 'idna': idna_info, + 'requests': { + 'version': requests_version, + }, + } + + +def main(): + """Pretty-print the bug information as JSON.""" + print(json.dumps(info(), sort_keys=True, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/swig/python/requests/help.pyc b/swig/python/requests/help.pyc new file mode 100644 index 0000000000000000000000000000000000000000..797bbe337f443380457b7e4430721cff3bf84b1e GIT binary patch literal 3461 zcmcgvUvC@75uZI$q)7d>Y%5Lw0PDIgnbszXBvk@8D2fJdVYiWlQ_=*4fWz@_C7yKL zJKyceA!0wdZ~YMMQ@=nzLD7eNgrc9L&qe#2xjX$a&{vbEib(U&+5fIHEJfCcYwiDR;wm zkA&|DUy=QbOnGvoKk-3aht9fmw$c*4mgv(-hjw47c8pu;(s_r9Z}~pX2K4gU)F~7w z!s6%OlKn(<^hC#BZ>qm1Q+=8G`^_mt!zxQiJXtfKJt%MW6fwc(i;QnZtb6oW zkD8^UhkDdlz+Blldes>I`8+9g8!P%nR-Bi5W=eNm6(9F-dANM66RY#Ea7k39Veyc) z=S4OPXX#Q@$C)YZ2qr;{K7rxSYWIP9T4c7i97n2Ptbwo#C`wLipO*8iN@M8Oab}H( zb6G7ZtDN{P%HSQ`PB{;A(>gQC;C9x9izAT#D*!N9HHJrQ=9FEAg}CpEb0q;ZnGCwM6sKN**JI1>mAE(jc|8)AU+6ghEScT z^-QxJ>4LOhmhP5p%9odkn%I*}%v^+L$b2?S0y0hIIm`D5*^1`RBeb zyyB(Y)r+j6ui!-nJs<}F3CIK>=|X}h|7+O5YF63_)SDX<08%X9;#vZ&SpKTdOJAbW-Jx@+-B!?q z;jV=!7{t<6DH#g<0rwdG*3d!fI^46}?29+RLrvU7hXZY)!~Sh_kZ}tg&c8!@Y%Yo) zgvPfSLpjLHAEWuLv8D(eXEvu`o!6Y2;kCLokqqNFHw($0CTxAaNuMi}&nYO8(G;aN zFiVc*2VeVA={SB54xj8F9sNG|!xR7L>A`-m|HWs&e&YL_3_j0G2G^_nFH} za4KIid>ez-jMiUcJ{!X73XlSUlH1_Ck@~`CyPLz;3z^Y)pk~PPqJ1mWEJmyAo~gO4 zncX8J{|6X}^RMngCf+8}F!=K+e}TSyhK9V3>ZlEM$J;>PSDPIMnQd_UYUuUA8>)9O z+T~w&2V>pgIsR@mJ<}Z(u{8cjvEfG(X9G~jDFz-~)N6S(;idsDfSA|H!<$ASg^tDy zUgdje4pGD1@{zpWq}=ga?|LSMrG9pFus@NIErGScxj`Cnwj=;z>wq;x`yx?_gou*x zIxF#nWKD6k$V>l2P{RMbsLa(Ryd})%n^@pITcDSeCQq^`2$+j!={sy5`!WbnY=S`2 zIKYdRpAA9aV}|^Xxsgoc8sh(ioBP~oZaA?7N9sKLDTa=7FAt;h@YIx(CeA1Pwl0!c zokWa2PZ#{UuCtY|(I0UmStrTMzVkVV8k_kQ0Gq+6Yvx;W;wtogvXK7|e#uZ$K19<) e_;R(xx9&X-=Q{}39==27bq4na9}QO4)&Bq=0YT{i literal 0 HcmV?d00001 diff --git a/swig/python/requests/hooks.py b/swig/python/requests/hooks.py new file mode 100644 index 0000000..32b32de --- /dev/null +++ b/swig/python/requests/hooks.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +""" +requests.hooks +~~~~~~~~~~~~~~ + +This module provides the capabilities for the Requests hooks system. + +Available hooks: + +``response``: + The response generated from a Request. +""" +HOOKS = ['response'] + + +def default_hooks(): + return dict((event, []) for event in HOOKS) + +# TODO: response is the only one + + +def dispatch_hook(key, hooks, hook_data, **kwargs): + """Dispatches a hook dictionary on a given piece of data.""" + hooks = hooks or dict() + hooks = hooks.get(key) + if hooks: + if hasattr(hooks, '__call__'): + hooks = [hooks] + for hook in hooks: + _hook_data = hook(hook_data, **kwargs) + if _hook_data is not None: + hook_data = _hook_data + return hook_data diff --git a/swig/python/requests/hooks.pyc b/swig/python/requests/hooks.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a102e2bd5bc3a4e52aae69849a67dc87ebbd5d1 GIT binary patch literal 1359 zcmcgs!D<^Z5FM=(H(nBwltK@^=u$9+m>k+1LP%N~LLuOQ9a;z**7B}wt6s0xlGcf- z(@T2oH}o6&4gIA4KxdS7O+TPnR!r6~sR|!-P!|z)h_9coG;0h&! zA%iOhX#n5Q5N)6IA=r-3W{3nXg$Z099v#pWVV;g?`=Ly5hk+OWE(=wC1FnXp^ zX}KFoo`^#9Ri>Om!$2Ev>{Q9PPsZ)sIyq^D;k%hondoBG#@Ue8Ed=-kR)?=a-} zTw>CtjSpomjc_vM1EVKg@G5gFbQ_3z8TXfh8XDiznVz9={``1s$Kdpy0lwX4fR1)T zRFOvUmc|Pd3xMlgxMQ$D)&K?pd}LE33UC=MXg5)S&){frYu^!nawc>4;3B`hMv)vw zrIp4;McL0(5~VsRCm3d<8=a@<7zrbz#7N<^L2inuP{m%qR9U)rFnhf}A4bc9tQ5~# ztC-sc?r=oZ+!p5eDeXyc>J_v#)Kir>5AMUo#d&uH&TIc4q1z%1av;jg#UA$V5+$&N zNU!4{pyy=&f&w`&HmPLyP?g{_76PZNnwlFx)-eow`aS@2;>+Z{Il%23nx0<2g1a?X z;ESO(_>S&%Sgcd~j~iglNWTkUdPeUjT!(Sprtg9S1aYctAzU)TRu;ZRIT5LJF3gs&U80Ut4z zb6+aYlcU;_7E@|RLE{@?hSo16hYQi>N%bMC+CElUD~>#b=ZMAMH3+uZHml>vq>Ejr0Kpb~GH*{$_J1ADzAFD4naMz=U-`Fwrs3n5ytWj&!{{WQQVY>hT literal 0 HcmV?d00001 diff --git a/swig/python/requests/models.py b/swig/python/requests/models.py new file mode 100644 index 0000000..4041cac --- /dev/null +++ b/swig/python/requests/models.py @@ -0,0 +1,948 @@ +# -*- coding: utf-8 -*- + +""" +requests.models +~~~~~~~~~~~~~~~ + +This module contains the primary objects that power Requests. +""" + +import collections +import datetime +import sys + +# Import encoding now, to avoid implicit import later. +# Implicit import within threads may cause LookupError when standard library is in a ZIP, +# such as in Embedded Python. See https://github.com/requests/requests/issues/3578. +import encodings.idna + +from urllib3.fields import RequestField +from urllib3.filepost import encode_multipart_formdata +from urllib3.util import parse_url +from urllib3.exceptions import ( + DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) + +from io import UnsupportedOperation +from .hooks import default_hooks +from .structures import CaseInsensitiveDict + +from .auth import HTTPBasicAuth +from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar +from .exceptions import ( + HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, + ContentDecodingError, ConnectionError, StreamConsumedError) +from ._internal_utils import to_native_string, unicode_is_ascii +from .utils import ( + guess_filename, get_auth_from_url, requote_uri, + stream_decode_response_unicode, to_key_val_list, parse_header_links, + iter_slices, guess_json_utf, super_len, check_header_validity) +from .compat import ( + cookielib, urlunparse, urlsplit, urlencode, str, bytes, + is_py2, chardet, builtin_str, basestring) +from .compat import json as complexjson +from .status_codes import codes + +#: The set of HTTP status codes that indicate an automatically +#: processable redirect. +REDIRECT_STATI = ( + codes.moved, # 301 + codes.found, # 302 + codes.other, # 303 + codes.temporary_redirect, # 307 + codes.permanent_redirect, # 308 +) + +DEFAULT_REDIRECT_LIMIT = 30 +CONTENT_CHUNK_SIZE = 10 * 1024 +ITER_CHUNK_SIZE = 512 + + +class RequestEncodingMixin(object): + @property + def path_url(self): + """Build the path URL to use.""" + + url = [] + + p = urlsplit(self.url) + + path = p.path + if not path: + path = '/' + + url.append(path) + + query = p.query + if query: + url.append('?') + url.append(query) + + return ''.join(url) + + @staticmethod + def _encode_params(data): + """Encode parameters in a piece of data. + + Will successfully encode parameters when passed as a dict or a list of + 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary + if parameters are supplied as a dict. + """ + + if isinstance(data, (str, bytes)): + return data + elif hasattr(data, 'read'): + return data + elif hasattr(data, '__iter__'): + result = [] + for k, vs in to_key_val_list(data): + if isinstance(vs, basestring) or not hasattr(vs, '__iter__'): + vs = [vs] + for v in vs: + if v is not None: + result.append( + (k.encode('utf-8') if isinstance(k, str) else k, + v.encode('utf-8') if isinstance(v, str) else v)) + return urlencode(result, doseq=True) + else: + return data + + @staticmethod + def _encode_files(files, data): + """Build the body for a multipart/form-data request. + + Will successfully encode files when passed as a dict or a list of + tuples. Order is retained if data is a list of tuples but arbitrary + if parameters are supplied as a dict. + The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) + or 4-tuples (filename, fileobj, contentype, custom_headers). + """ + if (not files): + raise ValueError("Files must be provided.") + elif isinstance(data, basestring): + raise ValueError("Data must not be a string.") + + new_fields = [] + fields = to_key_val_list(data or {}) + files = to_key_val_list(files or {}) + + for field, val in fields: + if isinstance(val, basestring) or not hasattr(val, '__iter__'): + val = [val] + for v in val: + if v is not None: + # Don't call str() on bytestrings: in Py3 it all goes wrong. + if not isinstance(v, bytes): + v = str(v) + + new_fields.append( + (field.decode('utf-8') if isinstance(field, bytes) else field, + v.encode('utf-8') if isinstance(v, str) else v)) + + for (k, v) in files: + # support for explicit filename + ft = None + fh = None + if isinstance(v, (tuple, list)): + if len(v) == 2: + fn, fp = v + elif len(v) == 3: + fn, fp, ft = v + else: + fn, fp, ft, fh = v + else: + fn = guess_filename(v) or k + fp = v + + if isinstance(fp, (str, bytes, bytearray)): + fdata = fp + else: + fdata = fp.read() + + rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) + rf.make_multipart(content_type=ft) + new_fields.append(rf) + + body, content_type = encode_multipart_formdata(new_fields) + + return body, content_type + + +class RequestHooksMixin(object): + def register_hook(self, event, hook): + """Properly register a hook.""" + + if event not in self.hooks: + raise ValueError('Unsupported event specified, with event name "%s"' % (event)) + + if isinstance(hook, collections.Callable): + self.hooks[event].append(hook) + elif hasattr(hook, '__iter__'): + self.hooks[event].extend(h for h in hook if isinstance(h, collections.Callable)) + + def deregister_hook(self, event, hook): + """Deregister a previously registered hook. + Returns True if the hook existed, False if not. + """ + + try: + self.hooks[event].remove(hook) + return True + except ValueError: + return False + + +class Request(RequestHooksMixin): + """A user-created :class:`Request ` object. + + Used to prepare a :class:`PreparedRequest `, which is sent to the server. + + :param method: HTTP method to use. + :param url: URL to send. + :param headers: dictionary of headers to send. + :param files: dictionary of {filename: fileobject} files to multipart upload. + :param data: the body to attach to the request. If a dictionary is provided, form-encoding will take place. + :param json: json for the body to attach to the request (if files or data is not specified). + :param params: dictionary of URL parameters to append to the URL. + :param auth: Auth handler or (user, pass) tuple. + :param cookies: dictionary or CookieJar of cookies to attach to this request. + :param hooks: dictionary of callback hooks, for internal usage. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> req.prepare() + + """ + + def __init__(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + + # Default empty dicts for dict params. + data = [] if data is None else data + files = [] if files is None else files + headers = {} if headers is None else headers + params = {} if params is None else params + hooks = {} if hooks is None else hooks + + self.hooks = default_hooks() + for (k, v) in list(hooks.items()): + self.register_hook(event=k, hook=v) + + self.method = method + self.url = url + self.headers = headers + self.files = files + self.data = data + self.json = json + self.params = params + self.auth = auth + self.cookies = cookies + + def __repr__(self): + return '' % (self.method) + + def prepare(self): + """Constructs a :class:`PreparedRequest ` for transmission and returns it.""" + p = PreparedRequest() + p.prepare( + method=self.method, + url=self.url, + headers=self.headers, + files=self.files, + data=self.data, + json=self.json, + params=self.params, + auth=self.auth, + cookies=self.cookies, + hooks=self.hooks, + ) + return p + + +class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): + """The fully mutable :class:`PreparedRequest ` object, + containing the exact bytes that will be sent to the server. + + Generated from either a :class:`Request ` object or manually. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> r = req.prepare() + + + >>> s = requests.Session() + >>> s.send(r) + + """ + + def __init__(self): + #: HTTP verb to send to the server. + self.method = None + #: HTTP URL to send the request to. + self.url = None + #: dictionary of HTTP headers. + self.headers = None + # The `CookieJar` used to create the Cookie header will be stored here + # after prepare_cookies is called + self._cookies = None + #: request body to send to the server. + self.body = None + #: dictionary of callback hooks, for internal usage. + self.hooks = default_hooks() + #: integer denoting starting position of a readable file-like body. + self._body_position = None + + def prepare(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + """Prepares the entire request with the given parameters.""" + + self.prepare_method(method) + self.prepare_url(url, params) + self.prepare_headers(headers) + self.prepare_cookies(cookies) + self.prepare_body(data, files, json) + self.prepare_auth(auth, url) + + # Note that prepare_auth must be last to enable authentication schemes + # such as OAuth to work on a fully prepared request. + + # This MUST go after prepare_auth. Authenticators could add a hook + self.prepare_hooks(hooks) + + def __repr__(self): + return '' % (self.method) + + def copy(self): + p = PreparedRequest() + p.method = self.method + p.url = self.url + p.headers = self.headers.copy() if self.headers is not None else None + p._cookies = _copy_cookie_jar(self._cookies) + p.body = self.body + p.hooks = self.hooks + p._body_position = self._body_position + return p + + def prepare_method(self, method): + """Prepares the given HTTP method.""" + self.method = method + if self.method is not None: + self.method = to_native_string(self.method.upper()) + + @staticmethod + def _get_idna_encoded_host(host): + import idna + + try: + host = idna.encode(host, uts46=True).decode('utf-8') + except idna.IDNAError: + raise UnicodeError + return host + + def prepare_url(self, url, params): + """Prepares the given HTTP URL.""" + #: Accept objects that have string representations. + #: We're unable to blindly call unicode/str functions + #: as this will include the bytestring indicator (b'') + #: on python 3.x. + #: https://github.com/requests/requests/pull/2238 + if isinstance(url, bytes): + url = url.decode('utf8') + else: + url = unicode(url) if is_py2 else str(url) + + # Remove leading whitespaces from url + url = url.lstrip() + + # Don't do any URL preparation for non-HTTP schemes like `mailto`, + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. + if ':' in url and not url.lower().startswith('http'): + self.url = url + return + + # Support for unicode domain names and paths. + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) + + if not scheme: + error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?") + error = error.format(to_native_string(url, 'utf8')) + + raise MissingSchema(error) + + if not host: + raise InvalidURL("Invalid URL %r: No host supplied" % url) + + # In general, we want to try IDNA encoding the hostname if the string contains + # non-ASCII characters. This allows users to automatically get the correct IDNA + # behaviour. For strings containing only ASCII characters, we need to also verify + # it doesn't start with a wildcard (*), before allowing the unencoded hostname. + if not unicode_is_ascii(host): + try: + host = self._get_idna_encoded_host(host) + except UnicodeError: + raise InvalidURL('URL has an invalid label.') + elif host.startswith(u'*'): + raise InvalidURL('URL has an invalid label.') + + # Carefully reconstruct the network location + netloc = auth or '' + if netloc: + netloc += '@' + netloc += host + if port: + netloc += ':' + str(port) + + # Bare domains aren't valid URLs. + if not path: + path = '/' + + if is_py2: + if isinstance(scheme, str): + scheme = scheme.encode('utf-8') + if isinstance(netloc, str): + netloc = netloc.encode('utf-8') + if isinstance(path, str): + path = path.encode('utf-8') + if isinstance(query, str): + query = query.encode('utf-8') + if isinstance(fragment, str): + fragment = fragment.encode('utf-8') + + if isinstance(params, (str, bytes)): + params = to_native_string(params) + + enc_params = self._encode_params(params) + if enc_params: + if query: + query = '%s&%s' % (query, enc_params) + else: + query = enc_params + + url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) + self.url = url + + def prepare_headers(self, headers): + """Prepares the given HTTP headers.""" + + self.headers = CaseInsensitiveDict() + if headers: + for header in headers.items(): + # Raise exception on invalid header value. + check_header_validity(header) + name, value = header + self.headers[to_native_string(name)] = value + + def prepare_body(self, data, files, json=None): + """Prepares the given HTTP body data.""" + + # Check if file, fo, generator, iterator. + # If not, run through normal process. + + # Nottin' on you. + body = None + content_type = None + + if not data and json is not None: + # urllib3 requires a bytes-like body. Python 2's json.dumps + # provides this natively, but Python 3 gives a Unicode string. + content_type = 'application/json' + body = complexjson.dumps(json) + if not isinstance(body, bytes): + body = body.encode('utf-8') + + is_stream = all([ + hasattr(data, '__iter__'), + not isinstance(data, (basestring, list, tuple, collections.Mapping)) + ]) + + try: + length = super_len(data) + except (TypeError, AttributeError, UnsupportedOperation): + length = None + + if is_stream: + body = data + + if getattr(body, 'tell', None) is not None: + # Record the current file position before reading. + # This will allow us to rewind a file in the event + # of a redirect. + try: + self._body_position = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body + self._body_position = object() + + if files: + raise NotImplementedError('Streamed bodies and files are mutually exclusive.') + + if length: + self.headers['Content-Length'] = builtin_str(length) + else: + self.headers['Transfer-Encoding'] = 'chunked' + else: + # Multi-part file uploads. + if files: + (body, content_type) = self._encode_files(files, data) + else: + if data: + body = self._encode_params(data) + if isinstance(data, basestring) or hasattr(data, 'read'): + content_type = None + else: + content_type = 'application/x-www-form-urlencoded' + + self.prepare_content_length(body) + + # Add content-type if it wasn't explicitly provided. + if content_type and ('content-type' not in self.headers): + self.headers['Content-Type'] = content_type + + self.body = body + + def prepare_content_length(self, body): + """Prepare Content-Length header based on request method and body""" + if body is not None: + length = super_len(body) + if length: + # If length exists, set it. Otherwise, we fallback + # to Transfer-Encoding: chunked. + self.headers['Content-Length'] = builtin_str(length) + elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None: + # Set Content-Length to 0 for methods that can have a body + # but don't provide one. (i.e. not GET or HEAD) + self.headers['Content-Length'] = '0' + + def prepare_auth(self, auth, url=''): + """Prepares the given HTTP auth data.""" + + # If no Auth is explicitly provided, extract it from the URL first. + if auth is None: + url_auth = get_auth_from_url(self.url) + auth = url_auth if any(url_auth) else None + + if auth: + if isinstance(auth, tuple) and len(auth) == 2: + # special-case basic HTTP auth + auth = HTTPBasicAuth(*auth) + + # Allow auth to make its changes. + r = auth(self) + + # Update self to reflect the auth changes. + self.__dict__.update(r.__dict__) + + # Recompute Content-Length + self.prepare_content_length(self.body) + + def prepare_cookies(self, cookies): + """Prepares the given HTTP cookie data. + + This function eventually generates a ``Cookie`` header from the + given cookies using cookielib. Due to cookielib's design, the header + will not be regenerated if it already exists, meaning this function + can only be called once for the life of the + :class:`PreparedRequest ` object. Any subsequent calls + to ``prepare_cookies`` will have no actual effect, unless the "Cookie" + header is removed beforehand. + """ + if isinstance(cookies, cookielib.CookieJar): + self._cookies = cookies + else: + self._cookies = cookiejar_from_dict(cookies) + + cookie_header = get_cookie_header(self._cookies, self) + if cookie_header is not None: + self.headers['Cookie'] = cookie_header + + def prepare_hooks(self, hooks): + """Prepares the given hooks.""" + # hooks can be passed as None to the prepare method and to this + # method. To prevent iterating over None, simply use an empty list + # if hooks is False-y + hooks = hooks or [] + for event in hooks: + self.register_hook(event, hooks[event]) + + +class Response(object): + """The :class:`Response ` object, which contains a + server's response to an HTTP request. + """ + + __attrs__ = [ + '_content', 'status_code', 'headers', 'url', 'history', + 'encoding', 'reason', 'cookies', 'elapsed', 'request' + ] + + def __init__(self): + self._content = False + self._content_consumed = False + self._next = None + + #: Integer Code of responded HTTP Status, e.g. 404 or 200. + self.status_code = None + + #: Case-insensitive Dictionary of Response Headers. + #: For example, ``headers['content-encoding']`` will return the + #: value of a ``'Content-Encoding'`` response header. + self.headers = CaseInsensitiveDict() + + #: File-like object representation of response (for advanced usage). + #: Use of ``raw`` requires that ``stream=True`` be set on the request. + # This requirement does not apply for use internally to Requests. + self.raw = None + + #: Final URL location of Response. + self.url = None + + #: Encoding to decode with when accessing r.text. + self.encoding = None + + #: A list of :class:`Response ` objects from + #: the history of the Request. Any redirect responses will end + #: up here. The list is sorted from the oldest to the most recent request. + self.history = [] + + #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". + self.reason = None + + #: A CookieJar of Cookies the server sent back. + self.cookies = cookiejar_from_dict({}) + + #: The amount of time elapsed between sending the request + #: and the arrival of the response (as a timedelta). + #: This property specifically measures the time taken between sending + #: the first byte of the request and finishing parsing the headers. It + #: is therefore unaffected by consuming the response content or the + #: value of the ``stream`` keyword argument. + self.elapsed = datetime.timedelta(0) + + #: The :class:`PreparedRequest ` object to which this + #: is a response. + self.request = None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def __getstate__(self): + # Consume everything; accessing the content attribute makes + # sure the content has been fully read. + if not self._content_consumed: + self.content + + return dict( + (attr, getattr(self, attr, None)) + for attr in self.__attrs__ + ) + + def __setstate__(self, state): + for name, value in state.items(): + setattr(self, name, value) + + # pickled objects do not have .raw + setattr(self, '_content_consumed', True) + setattr(self, 'raw', None) + + def __repr__(self): + return '' % (self.status_code) + + def __bool__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __nonzero__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __iter__(self): + """Allows you to use a response as an iterator.""" + return self.iter_content(128) + + @property + def ok(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + try: + self.raise_for_status() + except HTTPError: + return False + return True + + @property + def is_redirect(self): + """True if this Response is a well-formed HTTP redirect that could have + been processed automatically (by :meth:`Session.resolve_redirects`). + """ + return ('location' in self.headers and self.status_code in REDIRECT_STATI) + + @property + def is_permanent_redirect(self): + """True if this Response one of the permanent versions of redirect.""" + return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + + @property + def next(self): + """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" + return self._next + + @property + def apparent_encoding(self): + """The apparent encoding, provided by the chardet library.""" + return chardet.detect(self.content)['encoding'] + + def iter_content(self, chunk_size=1, decode_unicode=False): + """Iterates over the response data. When stream=True is set on the + request, this avoids reading the content at once into memory for + large responses. The chunk size is the number of bytes it should + read into memory. This is not necessarily the length of each item + returned as decoding can take place. + + chunk_size must be of type int or None. A value of None will + function differently depending on the value of `stream`. + stream=True will read data as it arrives in whatever size the + chunks are received. If stream=False, data is returned as + a single chunk. + + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. + """ + + def generate(): + # Special case for urllib3. + if hasattr(self.raw, 'stream'): + try: + for chunk in self.raw.stream(chunk_size, decode_content=True): + yield chunk + except ProtocolError as e: + raise ChunkedEncodingError(e) + except DecodeError as e: + raise ContentDecodingError(e) + except ReadTimeoutError as e: + raise ConnectionError(e) + else: + # Standard file-like object. + while True: + chunk = self.raw.read(chunk_size) + if not chunk: + break + yield chunk + + self._content_consumed = True + + if self._content_consumed and isinstance(self._content, bool): + raise StreamConsumedError() + elif chunk_size is not None and not isinstance(chunk_size, int): + raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size)) + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks + + if decode_unicode: + chunks = stream_decode_response_unicode(chunks, self) + + return chunks + + def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None): + """Iterates over the response data, one line at a time. When + stream=True is set on the request, this avoids reading the + content at once into memory for large responses. + + .. note:: This method is not reentrant safe. + """ + + pending = None + + for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode): + + if pending is not None: + chunk = pending + chunk + + if delimiter: + lines = chunk.split(delimiter) + else: + lines = chunk.splitlines() + + if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: + pending = lines.pop() + else: + pending = None + + for line in lines: + yield line + + if pending is not None: + yield pending + + @property + def content(self): + """Content of the response, in bytes.""" + + if self._content is False: + # Read the contents. + if self._content_consumed: + raise RuntimeError( + 'The content for this response was already consumed') + + if self.status_code == 0 or self.raw is None: + self._content = None + else: + self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes() + + self._content_consumed = True + # don't need to release the connection; that's been handled by urllib3 + # since we exhausted the data. + return self._content + + @property + def text(self): + """Content of the response, in unicode. + + If Response.encoding is None, encoding will be guessed using + ``chardet``. + + The encoding of the response content is determined based solely on HTTP + headers, following RFC 2616 to the letter. If you can take advantage of + non-HTTP knowledge to make a better guess at the encoding, you should + set ``r.encoding`` appropriately before accessing this property. + """ + + # Try charset from content-type + content = None + encoding = self.encoding + + if not self.content: + return str('') + + # Fallback to auto-detected encoding. + if self.encoding is None: + encoding = self.apparent_encoding + + # Decode unicode from given encoding. + try: + content = str(self.content, encoding, errors='replace') + except (LookupError, TypeError): + # A LookupError is raised if the encoding was not found which could + # indicate a misspelling or similar mistake. + # + # A TypeError can be raised if encoding is None + # + # So we try blindly encoding. + content = str(self.content, errors='replace') + + return content + + def json(self, **kwargs): + r"""Returns the json-encoded content of a response, if any. + + :param \*\*kwargs: Optional arguments that ``json.loads`` takes. + :raises ValueError: If the response body does not contain valid json. + """ + + if not self.encoding and self.content and len(self.content) > 3: + # No encoding set. JSON RFC 4627 section 3 states we should expect + # UTF-8, -16 or -32. Detect which one to use; If the detection or + # decoding fails, fall back to `self.text` (using chardet to make + # a best guess). + encoding = guess_json_utf(self.content) + if encoding is not None: + try: + return complexjson.loads( + self.content.decode(encoding), **kwargs + ) + except UnicodeDecodeError: + # Wrong UTF codec detected; usually because it's not UTF-8 + # but some other 8-bit codec. This is an RFC violation, + # and the server didn't bother to tell us what codec *was* + # used. + pass + return complexjson.loads(self.text, **kwargs) + + @property + def links(self): + """Returns the parsed header links of the response, if any.""" + + header = self.headers.get('link') + + # l = MultiDict() + l = {} + + if header: + links = parse_header_links(header) + + for link in links: + key = link.get('rel') or link.get('url') + l[key] = link + + return l + + def raise_for_status(self): + """Raises stored :class:`HTTPError`, if one occurred.""" + + http_error_msg = '' + if isinstance(self.reason, bytes): + # We attempt to decode utf-8 first because some servers + # choose to localize their reason strings. If the string + # isn't utf-8, we fall back to iso-8859-1 for all other + # encodings. (See PR #3538) + try: + reason = self.reason.decode('utf-8') + except UnicodeDecodeError: + reason = self.reason.decode('iso-8859-1') + else: + reason = self.reason + + if 400 <= self.status_code < 500: + http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url) + + elif 500 <= self.status_code < 600: + http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url) + + if http_error_msg: + raise HTTPError(http_error_msg, response=self) + + def close(self): + """Releases the connection back to the pool. Once this method has been + called the underlying ``raw`` object must not be accessed again. + + *Note: Should not normally need to be called explicitly.* + """ + if not self._content_consumed: + self.raw.close() + + release_conn = getattr(self.raw, 'release_conn', None) + if release_conn is not None: + release_conn() diff --git a/swig/python/requests/models.pyc b/swig/python/requests/models.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26dd0c512c9451744b246e9f53c03cd445176411 GIT binary patch literal 30772 zcmeI5dvG1sec#XC3xEI!5ES?jDN*8zHbsacA?jg0V2Kt*QWh-zi|{?^4y~$NJxj^rXxYoF9Pq@m2 zzaMq2N!Q-&Dx3ZNm}^bB_Oz=^yY?1W+2YzWt}^4=TU}+Vud&IsZgcHfSDEF0+%+a# zYny9tca`n_e$usexb{w0+3D{$yVmWly~|a0`THr?+U?qRxXK-_eW$D3>Dqf-WsiS0 z?OJ!a_T8>>w`=cpmA$SVx=QHU_qfVEuD#Dy_PO>4T;&6<{XtjxpnqqJYwdUKdtK#T z*FNAX2Yl&_Yt6a#eXeq!Yaeu#gRXtQtK9F}hg{{5Yae!%!>&E=D)X-WfU7*<+DBaF zh-*LSDi6B$L$30WZ)K}%J?z?#xXL50{UKNRkZV8cDv!GMW3KX;Yd`KPkGu90uJVLy zFSyErYk$~PKJ400y2_KT{gkUbPf@z)8h5$)1$zJt-CaC*$u;)ojf6$%%YwbrbN2`&mq;d)_{wUW z_S5-xw-L9}$xp8TH#vD`rJ062Ty4c+z1!*6nw>Q4uf$<5X|`+0TG+jCDX#ZbR_lko z?zK1xqrB0{=J)uwI2Z7#{uD{}9^=rP$ z1XU8ex{Z->&I66D|2P4_w`PlCYtf3T2ft3y6tL%clx(c zelhM>{j=%{V~YLoDC(`{<-9bvN$qHE)cjz?FE-P(*|~VSz7n@<{Yjpm>Rhe0nvGYY z7y26H@s-ui<+yQDlTJndrafSJ<4)h^wRkY2H@ck;Ys{qi%If^-eiGN(JV{sEG^SOU zgT^^qihj4+Ve+oV)wG|`lohUanzqc%v|3B+&E}l?*55*M5fDtP%gt8YskP%`4raZ*iN%{mA%=+>pQ+o`Vhmu;#659-j*{tntLf z*Ra*RV5`6wRy+3P{x}c0O?$0o-1)@z9f(2-AjGfLL4dvpR=f9Fuh}~+kZ2r! z^y(u=)-Jv#bP;hMWIUCh@2wdOs@tNePw}~Qr#?S2R+=eI1Y^NOY1)2I2U|<^e8~iV zwq#o=@r%VE`X#r_e3x9ZTg!Kvnc)|!rJ_T_MZVT};8*+luWCZ5%4(cA|M%T%thFt- zS}r>#kp|K=%`~@K(vq7>eoQwPb5OY6((Q@!jSK=BqweyAOTJ)mu*v#Z(nPB(-!One z)+y_Y9a`lPpBl+4{IT+vhAWKN$bhmdUvT_Cdu7p`1z~}p25(K$PHnO5bNC4)NZbBEZT{$RDGALHmzwyNg9&4i57#@hq(mnMfQj1{Q+Wq0Mvpl-vRy*?W-T_?^@2BI~a^ga4?1B@q~$h);! zqH0Fbel6%vXPpyi;Y**~kc7=w|9?W(&Yd<|M!iO^=9KQSMAycDZjt8+-rk;ZI7w8Z6FlGN6sC)601*Dl(%%R{;Lk~eY^>TNX)wEa^3JK$=wW5>!j*gQUD_QRQUn~As$N%d24;Tm1 zbSBHzdErm=G43~(@d%T1#$$tSQ;jDQ)A~Sg?cV zGgfCuX*L)u?LthPD%}%o4Q?yVmb^kL0I8z=wc~2lR=-;H)&p+!41h$1>aRtQb7N2g z=kGV`NJ=Z+M)WMDk;LD@>{xCCMB?Z$pA~?n5-XUK9W!^DE}E%D&q?E7uM-KDp3xgp zBVyBu8m16=d*0iWl%@D+`Rjt6{1WJ-pCW+;!;&sJcX^Xb_KEhx$0^(iK^8AJ2!lQY zd8j#JbTMntZ9&J>0iH-DmWquKCf} zN4TWsr3XkD@AvtE<`(A!^F|2FU=%&it*3&F z5tEe?QM^c`kQD@su0ul`e%z0$P)lU9Yve=CZ0Oh!fS_F&P?*{4mncYO&2#0MU>lU+ zcBn!D-s-M_x9kLKdxqf<$o9|*fjoV-GwVhG>&ufaIf7skFuc>}fPRlIDPk!mzWl>L zV=sxXHoL3o5R9UO7>pKdG>ZGH2?k0j0n&D4s8o$GzAm5!Sf8!6QhNjk9B|G>LxgCB zZ`vXxal3mpj-KY;mdqBxUL7n<1lGFfGRelShpbvCcEc<3Rf_N?J;~B!kXcZUe9*s`J@j%0c;lPEwt%{rK}U-lUe5IQfAQ3 z1lU)kabpbv_)ynkz%YOFWna=LTDYm;=n|B1rCDE*wvA!9uVw^~bmMBAWbH4Q5*T{! zw-Cydo89C#D1+^+8n&8++&)E<4G+NC!%QArFxvpOS~Jcshgq?jd)F%_2;BU_8@YV9 zkPEa>+#8n1%HJJG{ULUSZf$)hB<(ENFilUOItqM^NyrADWa>e9YMHr|6(j2@la$M< z2+~p~OiRXi41d8u(npF5d#zeMUN>l&Hy1*srjuxXzwd{`IjDjSThIpP}7cUjF1wNEUvA_Rb%*@76^?#H_?cj|=Z- zkp!?nKt(Q(yJS{YX4wu#WyipRkd+_I%e@)dqz~19Ms^U@N0%qXR^Z#Isq_*6&CiQs4-rF+f6JAED?jVbdg-ug zf*rN0X!`Vo3>v(dPOIqqjD-?Ze*Tj|)2BWe3L#w>(*zC{0 zKX4i#z6XTPNgg(b<4qLGpg$vHe}!hHMtFRAjNFDoLA1sf|BTDDTlX#i_uxKRS~SIf zAZpr(t5y6})v6~eS2c)hO4Q_F5F3TUQIF4lgUe*(v7KY+ExT@?C`Z>Rt8>{uq31JP z=|3b{Cx4n#Q(-wX-}gWACxYmZ{0Y3jjRXsHk6LEj#lZEL^620dKzoywL-xllg8`RM zOt`msIxRDL9>GE4vk(zAja!WbKY*%Wf|ITHxpEqF^X zYS%ieNF{5xNbvB2%MUDk3`srdu*`EBhaSYG5MCtIr1KKO=aNF8iL#)D@DmRmIg(2< zVjJsN$Fmf`yCH~G(~6Wa=esf{u_$9AjWRfB@GSWHK%dV*TL)$p87w?)fLD55Iyy4ve1&LxX1F#0sW>J8w@ktoU?%#d+UNRxibN~cOD1`3x)xQ=tB zmr0lv)OENAh$klyj0#(X{4XVc&kc^2>>&&bZ%K9o(=u@p`Rc8*ugpFC%B)t_n2CX^ zKQLd2X=kiJu~DEcz zXKLQMvTPa6%9_{H@~tZ{5lv!qUc;0Gj@93V zM}muYi(oq`eYa-u|Ai=KZ1X7%Pm;ip2&P+u?$44Lh+rPF1Ca?qIZ#cWl)P7Lh>rM3 zc8eeejX=W@fuI^5;9ML7mQ|7qWy)cj+5fy;;l#?y)BeXb)9SB- z$(4hB(78!(b(aP?&SgOPJ!T(rzy#t4k-z93n{R{#<9)1v;zP;?qi{AW>=63^OUo;0 z@=bi8vg{FoyFBKS*R37GEr97fMrz8J3bZXaBOQ&FqA0X!a^U; zcJ^WT-)yV8RZxZzNx}hd@3vZs8xd=hZg3 z^jiV4J~PEzTBEe2rOadDlK&o%zeEH%7NR@?P8A3Pv0%AmxAl}ATc&S8wP+{D9LIr~mfm2!{Kd3O_uB0XPmO3^jpe~D@`Pq_I%&%3+=7D+N zk(XFxO7c7UT=K0FS`8VZQh0Z#VrFFGklpvs{zzfb;4b=+0#ToOgw${ zKsdJrWJvdrydQCudDbWdF=>yRzi`2BWsY1-Pw-|IGi}E9H;&ws+*k+~F`!#ebrAqJ zAHEzXE45x4u60*2+t)DiXNJu;j@Hk9nF&+&^pWQPw(BI&dG`EJ&X4$Ct?@L-D>K177=X`7G|SsDel8Z zD6|x_Z?1Yg@ku|GJJ%cLM93o%_ect+%}_15n1x1QqObKMv7^Wgh@xE4Pb&FwB_B~D zwI#BS?Nd$+%ofLUEHnPemSR1!xsAQy?rZ9MX2pq zux)HAC?l;(VkO?9ta!g^DEnA&ds$()ip}s*7lYqBN;`ym?rB z3HikPVOXY)AitJT^Q?Fy)XPut zv42wVTU(QDrAY~a0!r~(UB+)mK@zAJY)+|h(W&H|=8SvEg6G7teBh+SaZ@s>t!XE< zm=0{2Ec+0O83j(c%8c%8y%q0R9t%a$J{>?GBw$&+Q(ev_6 ztXK%MHRcJoB$iNI?l&Y;sk_jB$y9KqC0SP0Em)-)YI%&dn~hqY%x8aYv zE8h;_)2xnqMEis*Scqu=!%pZ3vWIm{(K&yv!mOWD^ouvZ4Up?DP19-5bwuah4=2nq zDVO7XDtd~?khp%^WAuO=m; z)74w6DHer!vy5OLS3ut37h?9{WR4iW`zO7P9-NU0d>OC!$!sr>Mb4%7+|;@2hp%0` zcG!HfSRH)ua>GQ?Ea3030{*NZ|KJ&m0KA)qjOb^vJ8k09uWP7=*NxS7FCF4o;uv5B z6Vqy0IE)VzTvQ`3Dru;~CXyGKIxLfs^d}SO^*JxlZ=vWIA>&Pg*|V5Ky)*D1PBjTlAyQRT$xOnC2keU6P< zJ{FSsV(LxLwOAm}`i|+HNXh+5Obh;)nh>F6w-4NzjZL0YTLT+Q|2{)6z9#yoKDkZs znbJ16k)i~5pnFUO`{86;gPp;o;sQ&%M#RCkmBrV@({`4&Qu|KhU3bI7*i2I1kw>s= zg>@PAl<`qm>9=h>CLxDg$#kGOc-k>V+Gv|F4}ugxAv&(}m|-H6ilA$7vtzfmy~pc0 zY7xn@llz?fo8T-DPMgCbl{Au}Dn9jLM9E?%!VB!DYJ|9la-*HM!x{1kncoY?G&FqD zhP}_7Ja)pwlp~AYvhgcCjQ%l+-$$e#7!VIZlV-%Q0B9YGH8KeKM|zWM;~3#D^RWO9 zmn)tu{aAT-aG-1=sl|MWzZdKIWp1>dFa%~Fx3{P4o;mp)2F3uB!{UT8Jt1&dm?Li` zKX1|oG~4SUEwe`%IIyS+zNf^fIBH_?7H}bWF;a|^p%=})=k4XYc-QaWQY*F2nkQjKp=9icCP^}lcElR3@#8%BF3;wxeW0(80d~%DHdzOqFnF8O1#rKquOUv8Jbsnt` zVXaai)sHpvVkL`&wrs18J+U*Bt*GblvM_oUY93)2u}5=(3zE_&jJbp6xGX^Pb&EC5 zr{8a}yqWvvZB@2$d3m*C5k@{d)$>S&Y05JtpYhVtaSNbXTFP2IX=kG970(W?95;Ey-5G=TYqz*P^LABDw-vf=z<%6y!l4G$xLld;3 zGMe3B&hr*ud|Y!P;^{`U6>f1(WN8p+5WTM3t4eHT*Oap`gSVBFc{;kF#H+ATF*Y+f@#@6psgo1a zQ#&WN8%xQ(#dWINKQWtUxYEaHB_0l%H7<O@#0p?@cM0*A$nofG6W}Vv&@u>30l~$JoKKp1>Nq*Z)faw zXMVfYZg0&`Y0zQK!dOF)as+wkZV6UQ=$yLI3MPHK@mMcdcTWpfJxosp7Oy5Oc zBe9(~g%-tB**O!2=%zhZ*=x~{eqGf?^S$|~OfIQi^VZ9Mq2k|A@^vM~28`N|b1Px2 z&tW0PFqGl+lYTAwm#X;R!Yqfu?dE+_dOi9DCE|sC#+J#MA}X`T zO%S~SQ@4Is)aUcL8_V{lyrbT2BFX9C2zfgMM+jZ5s?%w;dQ-m#w;M153zVtKA1nII zj>gYu5aPM6Jc02;rVx|S)b&C}`#3k(4@xfcfPLcp9y6?)ZQX0clF?9v2`9QT&5;tO zF99F&hEtZ^8(r4DA%uEhV2vC>I*kt6=`foP%=;wK` zu_z?5wpyi&*(`oRvnVR;IObq`d8?-kLMB1+ajsOYQHY(ak&676k4KOG9$NlJuZVS3-(-&Pq3<8kAhHjJL^#@q_@K07o|vNO1Fvn*-nm&2uLz6a-rL8RjWT+ z0L%Eh`S@Q0i-*oz3M|p@11z@+R7CpNLEr7X9w*&u^-J#oErMkuEefRbq{WNanVNry z;$tlw`#v%Oq-LiXC{!pWS*!sPnof_JZ+@B=Jer7B+o3%fSH4BFU@ovfREnD*?m~{!4024&}p+hg(ZpZnT9b zUekM;+^vEz;rOoz!c3lox_T9 zvw=8ZExd*&*L(B9P*b2S)I2(Q;#73< z_?hbIGsn)Hx*J=rY^X4A+OqonTkkO+6nV(oP6mzK2Qe#{%9Q)v86i+u zxD1H|DG-|>u{n#bV5fI>8WTII4A!#4JaN@r(3yMlk!)5TJ2h-G^KsZGR3iFqJ-J1b zqF9l9G(IL7uhj1jX2_1ntqUn++L@YdVJ4!-Ee);LHSG#g)f4e9l|oERw{ITq_!C z5r(O)MBXmVQIDuiH~|&f6Q<4A4WC5II;-sqI%;4!+q#F3F{#_ zfcI^LopYRT=g|m%BElY0;P640Ion{`0>2deMd&hiPmX@$kkW}#I!~QJkNv@d03s+4 z3d7y|0#+UEDk4)0_ouj+%?+c8@J{=$ku#<%(?}%7>RmjVLmG*`l0O$^i0;z!J4pPN zbBmt&uc|S$P>BIJ2d?KuN14FspN=|CXd-N0wawY9{zf8U`;dbdDoL zPMrU{7Lklw4~&D89<_+oQFnV5@Cu&1YFk^pHJT_YxSwrSL4JM8(WC>1@nGc(Zd{XQuOTi)w5UEpGx;X z8Q}kg^&XPci1b7P%dCZR8(aUTl;@bG*Seiyx#LVy+1a9%n7X?b6zEcC3+XyO9Cke`EOBpHDE-BBQ=Rinr(6 z+3_M7c8a{FAcdG|$3$-^&a`OBoO1X$n{63)%w>>q$>@)H%i8pf2+)-C$iR);02Htt z8|s;knmOaa3`78; zKLrucJRqh3dK8kPssVjyhXjWcK+dfJvflc*Aes__+pfGJVe>7X=G$NCDUI;Imt>E8 zO}Gl$tMVX|^&yiW_o;W8Tqg-CWW8189dhQnidNZl-p=BniA2GXHG7jsUCms zmBr_)r%zQ*8f%-oHEM^cJO^3aEE-V<)8lX}-OY87?f$m@JRY3)^aXB2bG+Zk2NAOr ztnj|U`s=`UNiUE@*7_-1EZ(slY8+PxoT!4)P{0F7c&j8iU+ zYiTLdF69a-N(Ev?lQ)550egH(T4&M*7YV_$C}?a;F~T(>wX9b~d)Yo8of;;4v!w3m z+2i3uk3RUQTs4CB7JsdR^X?=NYnxm>*9dBjtI$4<6hpQz+QaO9*vw;>JKbx9H1bp` zkPd&V$&W-!e!L>aYCRv!A#405?MB3YX(=ftacN0fIVYVaO=Nk7|%CQyE!EB$E_ zPvE8y(mgVf!QAHakVXjYwl!>xs4I_xv{Z(Typ_hJ5l`U?cn8W+U>XyzSOfr3R@_67yX~$089YCr6qk~US}YtK$g_pbO167X7*0QSBulH z7lZ=pSV7YLj-W33rQ`v15wn=|)n>zbKWNR);$F1BEn`L^BaV^9o8PTr8}xmNoaf}~ zl5GJs`{OHqhx>`aA54n=f~o@`G@Zu}*PEbtx?!MbTVSBG8J*uWHwpkk>Bl%!ZF-bF z?qWYeJ%Q|Tt`r8JfncVFLh1vBoe9R+N3d+r=%KFcu0NqzixcPP%^t+w027e`(_Um- z1-OOC(*%kr1|ymnWsk{&w%L)pjEz6eH-~`>+n%iQS;R6@%Vo0@4=-;4U8dluib-fm z+_C^QKmBGz{-DKG333cX;%M7*wnq#V&b`L-P_=lc2{9yB^S%T)DlC18f z`Tc2l+=pdYa|@`~7W!{z#O_a<=TIo~il^?G5(W zHRcHlvojzl&vBy#=T-X~Mvw?3z_(B@B-VQo&)6DL-dpUC&h>05)h7f9Sydjd<3%k( zbO8Yo1&Dk0H`EZQIBYc&j(V6q_)9%9_L}ICX^1)uK>oi%F3L7|sHIi?^{3XFq!nbF z+O?%TEP4H3b}*3!z^h$^rwlQ;gNsr~!_#I5_C{W9<(E^j6H}j#4K|c;o;iC|o0wJS z4;Fnf)dDJ}!6`zwlWp>ThgpnF!T3$(enE-&(op#3DA2pHFrlve1HpuJWj8j#HpCsU zm&G|_o2Yo%`Pi>3_d80iD*0DReoM*kD)~Jn*OdH$l7FLQK}k)CJju~_l>A2}|4GRo zDFJ#i^-7Uzr_P*=hIK2=P4uTqOa}Z5qV$PuJ+h6lAc+8)y_M5Fp z$Ze8OUdq1c*rd4BTW2Loc#EwB3pf*$wHwKM<k-F`u0kJum^s|c@9^`7 z({9%7loDAQ?Tw*Ni75KRF~l^zad=iaGYN0k8-j}}hE6+enLjhwY^DB84Ti_e>{+q$^ig(g|93xP^(=Jglpx^ik3KJVy1sO5jJMm4w- zC!am`$_r3o)Rpv0NVCtQa>GG4b~Obxts zFQ^&yL+8ad2s)#+n%>*0r^SkwWIE?YNNX99eY_%V= self.max_redirects: + raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp) + + # Release the connection back into the pool. + resp.close() + + # Handle redirection without scheme (see: RFC 1808 Section 4) + if url.startswith('//'): + parsed_rurl = urlparse(resp.url) + url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url) + + # The scheme should be lower case... + parsed = urlparse(url) + url = parsed.geturl() + + # Facilitate relative 'location' headers, as allowed by RFC 7231. + # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + # Compliant with RFC3986, we percent encode the url. + if not parsed.netloc: + url = urljoin(resp.url, requote_uri(url)) + else: + url = requote_uri(url) + + prepared_request.url = to_native_string(url) + + self.rebuild_method(prepared_request, resp) + + # https://github.com/requests/requests/issues/1084 + if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): + # https://github.com/requests/requests/issues/3490 + purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding') + for header in purged_headers: + prepared_request.headers.pop(header, None) + prepared_request.body = None + + headers = prepared_request.headers + try: + del headers['Cookie'] + except KeyError: + pass + + # Extract any cookies sent on the response to the cookiejar + # in the new request. Because we've mutated our copied prepared + # request, use the old one that we haven't yet touched. + extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) + merge_cookies(prepared_request._cookies, self.cookies) + prepared_request.prepare_cookies(prepared_request._cookies) + + # Rebuild auth and proxy information. + proxies = self.rebuild_proxies(prepared_request, proxies) + self.rebuild_auth(prepared_request, resp) + + # A failed tell() sets `_body_position` to `object()`. This non-None + # value ensures `rewindable` will be True, allowing us to raise an + # UnrewindableBodyError, instead of hanging the connection. + rewindable = ( + prepared_request._body_position is not None and + ('Content-Length' in headers or 'Transfer-Encoding' in headers) + ) + + # Attempt to rewind consumed file-like object. + if rewindable: + rewind_body(prepared_request) + + # Override the original request. + req = prepared_request + + if yield_requests: + yield req + else: + + resp = self.send( + req, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + allow_redirects=False, + **adapter_kwargs + ) + + extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + + # extract redirect url, if any, for the next loop + url = self.get_redirect_target(resp) + yield resp + + def rebuild_auth(self, prepared_request, response): + """When being redirected we may want to strip authentication from the + request to avoid leaking credentials. This method intelligently removes + and reapplies authentication where possible to avoid credential loss. + """ + headers = prepared_request.headers + url = prepared_request.url + + if 'Authorization' in headers: + # If we get redirected to a new host, we should strip out any + # authentication headers. + original_parsed = urlparse(response.request.url) + redirect_parsed = urlparse(url) + + if (original_parsed.hostname != redirect_parsed.hostname): + del headers['Authorization'] + + # .netrc might have more auth for us on our new host. + new_auth = get_netrc_auth(url) if self.trust_env else None + if new_auth is not None: + prepared_request.prepare_auth(new_auth) + + return + + def rebuild_proxies(self, prepared_request, proxies): + """This method re-evaluates the proxy configuration by considering the + environment variables. If we are redirected to a URL covered by + NO_PROXY, we strip the proxy configuration. Otherwise, we set missing + proxy keys for this URL (in case they were stripped by a previous + redirect). + + This method also replaces the Proxy-Authorization header where + necessary. + + :rtype: dict + """ + proxies = proxies if proxies is not None else {} + headers = prepared_request.headers + url = prepared_request.url + scheme = urlparse(url).scheme + new_proxies = proxies.copy() + no_proxy = proxies.get('no_proxy') + + bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy) + if self.trust_env and not bypass_proxy: + environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) + + proxy = environ_proxies.get(scheme, environ_proxies.get('all')) + + if proxy: + new_proxies.setdefault(scheme, proxy) + + if 'Proxy-Authorization' in headers: + del headers['Proxy-Authorization'] + + try: + username, password = get_auth_from_url(new_proxies[scheme]) + except KeyError: + username, password = None, None + + if username and password: + headers['Proxy-Authorization'] = _basic_auth_str(username, password) + + return new_proxies + + def rebuild_method(self, prepared_request, response): + """When being redirected we may want to change the method of the request + based on certain specs or browser behavior. + """ + method = prepared_request.method + + # http://tools.ietf.org/html/rfc7231#section-6.4.4 + if response.status_code == codes.see_other and method != 'HEAD': + method = 'GET' + + # Do what the browsers do, despite standards... + # First, turn 302s into GETs. + if response.status_code == codes.found and method != 'HEAD': + method = 'GET' + + # Second, if a POST is responded to with a 301, turn it into a GET. + # This bizarre behaviour is explained in Issue 1704. + if response.status_code == codes.moved and method == 'POST': + method = 'GET' + + prepared_request.method = method + + +class Session(SessionRedirectMixin): + """A Requests session. + + Provides cookie persistence, connection-pooling, and configuration. + + Basic Usage:: + + >>> import requests + >>> s = requests.Session() + >>> s.get('http://httpbin.org/get') + + + Or as a context manager:: + + >>> with requests.Session() as s: + >>> s.get('http://httpbin.org/get') + + """ + + __attrs__ = [ + 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', + 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', + 'max_redirects', + ] + + def __init__(self): + + #: A case-insensitive dictionary of headers to be sent on each + #: :class:`Request ` sent from this + #: :class:`Session `. + self.headers = default_headers() + + #: Default Authentication tuple or object to attach to + #: :class:`Request `. + self.auth = None + + #: Dictionary mapping protocol or protocol and host to the URL of the proxy + #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to + #: be used on each :class:`Request `. + self.proxies = {} + + #: Event-handling hooks. + self.hooks = default_hooks() + + #: Dictionary of querystring data to attach to each + #: :class:`Request `. The dictionary values may be lists for + #: representing multivalued query parameters. + self.params = {} + + #: Stream response content default. + self.stream = False + + #: SSL Verification default. + self.verify = True + + #: SSL client certificate default, if String, path to ssl client + #: cert file (.pem). If Tuple, ('cert', 'key') pair. + self.cert = None + + #: Maximum number of redirects allowed. If the request exceeds this + #: limit, a :class:`TooManyRedirects` exception is raised. + #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is + #: 30. + self.max_redirects = DEFAULT_REDIRECT_LIMIT + + #: Trust environment settings for proxy configuration, default + #: authentication and similar. + self.trust_env = True + + #: A CookieJar containing all currently outstanding cookies set on this + #: session. By default it is a + #: :class:`RequestsCookieJar `, but + #: may be any other ``cookielib.CookieJar`` compatible object. + self.cookies = cookiejar_from_dict({}) + + # Default connection adapters. + self.adapters = OrderedDict() + self.mount('https://', HTTPAdapter()) + self.mount('http://', HTTPAdapter()) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def prepare_request(self, request): + """Constructs a :class:`PreparedRequest ` for + transmission and returns it. The :class:`PreparedRequest` has settings + merged from the :class:`Request ` instance and those of the + :class:`Session`. + + :param request: :class:`Request` instance to prepare with this + session's settings. + :rtype: requests.PreparedRequest + """ + cookies = request.cookies or {} + + # Bootstrap CookieJar. + if not isinstance(cookies, cookielib.CookieJar): + cookies = cookiejar_from_dict(cookies) + + # Merge with session cookies + merged_cookies = merge_cookies( + merge_cookies(RequestsCookieJar(), self.cookies), cookies) + + # Set environment's basic authentication if not explicitly set. + auth = request.auth + if self.trust_env and not auth and not self.auth: + auth = get_netrc_auth(request.url) + + p = PreparedRequest() + p.prepare( + method=request.method.upper(), + url=request.url, + files=request.files, + data=request.data, + json=request.json, + headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict), + params=merge_setting(request.params, self.params), + auth=merge_setting(auth, self.auth), + cookies=merged_cookies, + hooks=merge_hooks(request.hooks, self.hooks), + ) + return p + + def request(self, method, url, + params=None, data=None, headers=None, cookies=None, files=None, + auth=None, timeout=None, allow_redirects=True, proxies=None, + hooks=None, stream=None, verify=None, cert=None, json=None): + """Constructs a :class:`Request `, prepares it and sends it. + Returns :class:`Response ` object. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query + string for the :class:`Request`. + :param data: (optional) Dictionary, bytes, or file-like object to send + in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the + :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the + :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the + :class:`Request`. + :param files: (optional) Dictionary of ``'filename': file-like-objects`` + for multipart encoding upload. + :param auth: (optional) Auth tuple or callable to enable + Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) ` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Set to True by default. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol or protocol and + hostname to the URL of the proxy. + :param stream: (optional) whether to immediately download the response + content. Defaults to ``False``. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param cert: (optional) if String, path to ssl client cert file (.pem). + If Tuple, ('cert', 'key') pair. + :rtype: requests.Response + """ + # Create the Request. + req = Request( + method=method.upper(), + url=url, + headers=headers, + files=files, + data=data or {}, + json=json, + params=params or {}, + auth=auth, + cookies=cookies, + hooks=hooks, + ) + prep = self.prepare_request(req) + + proxies = proxies or {} + + settings = self.merge_environment_settings( + prep.url, proxies, stream, verify, cert + ) + + # Send the request. + send_kwargs = { + 'timeout': timeout, + 'allow_redirects': allow_redirects, + } + send_kwargs.update(settings) + resp = self.send(prep, **send_kwargs) + + return resp + + def get(self, url, **kwargs): + r"""Sends a GET request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('GET', url, **kwargs) + + def options(self, url, **kwargs): + r"""Sends a OPTIONS request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('OPTIONS', url, **kwargs) + + def head(self, url, **kwargs): + r"""Sends a HEAD request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return self.request('HEAD', url, **kwargs) + + def post(self, url, data=None, json=None, **kwargs): + r"""Sends a POST request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('POST', url, data=data, json=json, **kwargs) + + def put(self, url, data=None, **kwargs): + r"""Sends a PUT request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PUT', url, data=data, **kwargs) + + def patch(self, url, data=None, **kwargs): + r"""Sends a PATCH request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PATCH', url, data=data, **kwargs) + + def delete(self, url, **kwargs): + r"""Sends a DELETE request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('DELETE', url, **kwargs) + + def send(self, request, **kwargs): + """Send a given PreparedRequest. + + :rtype: requests.Response + """ + # Set defaults that the hooks can utilize to ensure they always have + # the correct parameters to reproduce the previous request. + kwargs.setdefault('stream', self.stream) + kwargs.setdefault('verify', self.verify) + kwargs.setdefault('cert', self.cert) + kwargs.setdefault('proxies', self.proxies) + + # It's possible that users might accidentally send a Request object. + # Guard against that specific failure case. + if isinstance(request, Request): + raise ValueError('You can only send PreparedRequests.') + + # Set up variables needed for resolve_redirects and dispatching of hooks + allow_redirects = kwargs.pop('allow_redirects', True) + stream = kwargs.get('stream') + hooks = request.hooks + + # Get the appropriate adapter to use + adapter = self.get_adapter(url=request.url) + + # Start time (approximately) of the request + start = preferred_clock() + + # Send the request + r = adapter.send(request, **kwargs) + + # Total elapsed time of the request (approximately) + elapsed = preferred_clock() - start + r.elapsed = timedelta(seconds=elapsed) + + # Response manipulation hooks + r = dispatch_hook('response', hooks, r, **kwargs) + + # Persist cookies + if r.history: + + # If the hooks create history then we want those cookies too + for resp in r.history: + extract_cookies_to_jar(self.cookies, resp.request, resp.raw) + + extract_cookies_to_jar(self.cookies, request, r.raw) + + # Redirect resolving generator. + gen = self.resolve_redirects(r, request, **kwargs) + + # Resolve redirects if allowed. + history = [resp for resp in gen] if allow_redirects else [] + + # Shuffle things around if there's history. + if history: + # Insert the first (original) request at the start + history.insert(0, r) + # Get the last request made + r = history.pop() + r.history = history + + # If redirects aren't being followed, store the response on the Request for Response.next(). + if not allow_redirects: + try: + r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs)) + except StopIteration: + pass + + if not stream: + r.content + + return r + + def merge_environment_settings(self, url, proxies, stream, verify, cert): + """ + Check the environment and merge it with some settings. + + :rtype: dict + """ + # Gather clues from the surrounding environment. + if self.trust_env: + # Set environment's proxies. + no_proxy = proxies.get('no_proxy') if proxies is not None else None + env_proxies = get_environ_proxies(url, no_proxy=no_proxy) + for (k, v) in env_proxies.items(): + proxies.setdefault(k, v) + + # Look for requests environment configuration and be compatible + # with cURL. + if verify is True or verify is None: + verify = (os.environ.get('REQUESTS_CA_BUNDLE') or + os.environ.get('CURL_CA_BUNDLE')) + + # Merge all the kwargs. + proxies = merge_setting(proxies, self.proxies) + stream = merge_setting(stream, self.stream) + verify = merge_setting(verify, self.verify) + cert = merge_setting(cert, self.cert) + + return {'verify': verify, 'proxies': proxies, 'stream': stream, + 'cert': cert} + + def get_adapter(self, url): + """ + Returns the appropriate connection adapter for the given URL. + + :rtype: requests.adapters.BaseAdapter + """ + for (prefix, adapter) in self.adapters.items(): + + if url.lower().startswith(prefix): + return adapter + + # Nothing matches :-/ + raise InvalidSchema("No connection adapters were found for '%s'" % url) + + def close(self): + """Closes all adapters and as such the session""" + for v in self.adapters.values(): + v.close() + + def mount(self, prefix, adapter): + """Registers a connection adapter to a prefix. + + Adapters are sorted in descending order by prefix length. + """ + self.adapters[prefix] = adapter + keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] + + for key in keys_to_move: + self.adapters[key] = self.adapters.pop(key) + + def __getstate__(self): + state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + return state + + def __setstate__(self, state): + for attr, value in state.items(): + setattr(self, attr, value) + + +def session(): + """ + Returns a :class:`Session` for context-management. + + :rtype: Session + """ + + return Session() diff --git a/swig/python/requests/sessions.pyc b/swig/python/requests/sessions.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6afe743482eae9b14c3c2d53716e7df08d261dea GIT binary patch literal 22678 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' % (self.name) + + def __getitem__(self, key): + # We allow fall-through here, so values default to None + + return self.__dict__.get(key, None) + + def get(self, key, default=None): + return self.__dict__.get(key, default) diff --git a/swig/python/requests/structures.pyc b/swig/python/requests/structures.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9fa28b8a3f96a218bd54f5d0c819bbe582bf89f6 GIT binary patch literal 6008 zcmd5=?Q$bW744C1t)=V|NJ7Asg6dQfqz$&%A3#xyvxV^nSV$adcA+YcwnpQbwl(%> zW_G$|sJ6?gzR=e95csJx}7ZFSUELAt3-pw2eb3HmzfE2Um2_4(1J zN^dFCk=Ct6>n+anc+lnapCRkj=Gn|xXNT6+v&7A6V|#yp`LEY|7`s?62WdBnovzAD zQ|qvqqnG^`e}`FsnFq|=YsfyUQ&XGtVU{@eCh7;VHIE8w3Y)p?!mxdTy@meYBH43f z2H1fKc}u0QQ3zi_0vm(?ltkE;LWcrj3(##!VQVglqb{YuuAWLo3P+fyD=oKG+LOW^ z6+Rx^=A!?G==XJk{q1JU4eIeY#U97w-8?%tx;#EJi5vEM8h?+bRc@xHa8}28uBXOL z$`s`y)n#Ss*kxs5b$KF#$K#~Tb9~Ik;ioefALr)NxT><^bUfCv)t3g7;Fs(5Ef!A7 z>S{b5>iyi7GDlUH7g=i9ms9vr=FHS$h~LjXzCSlt*gOsZX}j}4WFh3rs2 znMlQ}Ti4kC^w`uEDmAhO1%N%XuJhPB&e+Uh+>W3dkFjt)fS6odB&TLuquMdq6 z4nF?#6ApdVSgqgFPwJVMGpElp>jv1zU5;N_s2L}d|E{c|%$QuGR3|2eMcFU<#0>83 znj$Gv;O##JjYNR8fhiXYjb6n0OjH`<^Zvp7vyYq4@D=R70xOO7lkcG6G_KR!ST9k~ zVNzZSCHx3o#8aa$LDsU)PO}2^zXHWdSbAd{oUUM9)R%!OltR~8n_bUa>K_68u7V?_lRF%2 zAPmZ9n3XYA3WnrYvgC1~2>98h0kpg59%ZT&KxIVQ53{aBUW0aEnqnU-ON7d{Y zq#LDWG81nzx-0>zwi8Hal+-4M;Nb|WQI%D@$FnR?cYk^D^LtmPqsGB63riCE6>&MNLDT=IdbU#sa4^_+ks&>MkCJE^8qk-yQ!McspX#4Si!{+B5i-I`h z=_)+}HteyAv|hb>e5VaQQrzPUUdHzpI=_bRqgUzj{|Q-Y;5VqbU#%dcIWkcfqPZWS zz__8o=ZX68MF86s-6b4OIx<w9;CZ0_8azYXwKRDQQr?_7&G4Ss z5f9Fkyr%G{I4DedGwimc;NGbz5CYT>_D~VscjmO@mc{AF?yPt*;p+NnN^b-AgIFSp ze%WSkF+7DV3Q!b~3^Baz>^Mr52`pz$`mx2JSt2@Fdd@qYHwQA% z@x;k&6Pt@STDf^Rj+tLOLVo4GgY2+$i_45jeQbhTNVtu@zXjBY3^F(Gv0#3W*?+au-`!SCfx=J!kZpr$mWnH z8YXU45WS585P>LULW2loSOq1X5CLBJV~h@ei0meDdFNi63eKI68FOrh0}^f?dGZ<& zMMBvqnwIG-XVp7Wgu77`in2IW$V+<2gCOJtA$1%wHWQMDnx%J{y@zbcPbsY_oEB2i zb6Tpav)yUk?sPZ1?fL&!x7%$C)=$dvd{({s?Sm1G!JEb6?E^0z-|+T(T%>F+%cgmzS8vlorl`P8t%W9VzwpJQB1d*4|uH{SR#a zfj1pN!6|O$L=iHNv3%ngh=Pe`alm$(fro' string by the localhost entry and the corresponding + # canonical entry. + proxyOverride = proxyOverride.split(';') + # now check if we match one of the registry values. + for test in proxyOverride: + if test == '': + if '.' not in host: + return True + test = test.replace(".", r"\.") # mask dots + test = test.replace("*", r".*") # change glob sequence + test = test.replace("?", r".") # change glob char + if re.match(test, host, re.I): + return True + return False + + def proxy_bypass(host): # noqa + """Return True, if the host should be bypassed. + + Checks proxy settings gathered from the environment, if specified, + or the registry. + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + + +def dict_to_sequence(d): + """Returns an internal sequence dictionary update.""" + + if hasattr(d, 'items'): + d = d.items() + + return d + + +def super_len(o): + total_length = None + current_position = 0 + + if hasattr(o, '__len__'): + total_length = len(o) + + elif hasattr(o, 'len'): + total_length = o.len + + elif hasattr(o, 'fileno'): + try: + fileno = o.fileno() + except io.UnsupportedOperation: + pass + else: + total_length = os.fstat(fileno).st_size + + # Having used fstat to determine the file length, we need to + # confirm that this file was opened up in binary mode. + if 'b' not in o.mode: + warnings.warn(( + "Requests has determined the content-length for this " + "request using the binary size of the file: however, the " + "file has been opened in text mode (i.e. without the 'b' " + "flag in the mode). This may lead to an incorrect " + "content-length. In Requests 3.0, support will be removed " + "for files in text mode."), + FileModeWarning + ) + + if hasattr(o, 'tell'): + try: + current_position = o.tell() + except (OSError, IOError): + # This can happen in some weird situations, such as when the file + # is actually a special file descriptor like stdin. In this + # instance, we don't know what the length is, so set it to zero and + # let requests chunk it instead. + if total_length is not None: + current_position = total_length + else: + if hasattr(o, 'seek') and total_length is None: + # StringIO and BytesIO have seek but no useable fileno + try: + # seek to end of file + o.seek(0, 2) + total_length = o.tell() + + # seek back to current position to support + # partially read file-like objects + o.seek(current_position or 0) + except (OSError, IOError): + total_length = 0 + + if total_length is None: + total_length = 0 + + return max(0, total_length - current_position) + + +def get_netrc_auth(url, raise_errors=False): + """Returns the Requests tuple auth for a given url from netrc.""" + + try: + from netrc import netrc, NetrcParseError + + netrc_path = None + + for f in NETRC_FILES: + try: + loc = os.path.expanduser('~/{0}'.format(f)) + except KeyError: + # os.path.expanduser can fail when $HOME is undefined and + # getpwuid fails. See http://bugs.python.org/issue20164 & + # https://github.com/requests/requests/issues/1846 + return + + if os.path.exists(loc): + netrc_path = loc + break + + # Abort early if there isn't one. + if netrc_path is None: + return + + ri = urlparse(url) + + # Strip port numbers from netloc. This weird `if...encode`` dance is + # used for Python 3.2, which doesn't support unicode literals. + splitstr = b':' + if isinstance(url, str): + splitstr = splitstr.decode('ascii') + host = ri.netloc.split(splitstr)[0] + + try: + _netrc = netrc(netrc_path).authenticators(host) + if _netrc: + # Return with login / password + login_i = (0 if _netrc[0] else 1) + return (_netrc[login_i], _netrc[2]) + except (NetrcParseError, IOError): + # If there was a parsing error or a permissions issue reading the file, + # we'll just skip netrc auth unless explicitly asked to raise errors. + if raise_errors: + raise + + # AppEngine hackiness. + except (ImportError, AttributeError): + pass + + +def guess_filename(obj): + """Tries to guess the filename of the given object.""" + name = getattr(obj, 'name', None) + if (name and isinstance(name, basestring) and name[0] != '<' and + name[-1] != '>'): + return os.path.basename(name) + + +def from_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. Unless it can not be represented as such, return an + OrderedDict, e.g., + + :: + + >>> from_key_val_list([('key', 'val')]) + OrderedDict([('key', 'val')]) + >>> from_key_val_list('string') + ValueError: need more than 1 value to unpack + >>> from_key_val_list({'key': 'val'}) + OrderedDict([('key', 'val')]) + + :rtype: OrderedDict + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + return OrderedDict(value) + + +def to_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. If it can be, return a list of tuples, e.g., + + :: + + >>> to_key_val_list([('key', 'val')]) + [('key', 'val')] + >>> to_key_val_list({'key': 'val'}) + [('key', 'val')] + >>> to_key_val_list('string') + ValueError: cannot encode objects that are not 2-tuples. + + :rtype: list + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + if isinstance(value, collections.Mapping): + value = value.items() + + return list(value) + + +# From mitsuhiko/werkzeug (used with permission). +def parse_list_header(value): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + :rtype: list + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +# From mitsuhiko/werkzeug (used with permission). +def parse_dict_header(value): + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict: + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + :param value: a string with a dict header. + :return: :class:`dict` + :rtype: dict + """ + result = {} + for item in _parse_list_header(value): + if '=' not in item: + result[item] = None + continue + name, value = item.split('=', 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +# From mitsuhiko/werkzeug (used with permission). +def unquote_header_value(value, is_filename=False): + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + :param value: the header value to unquote. + :rtype: str + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != '\\\\': + return value.replace('\\\\', '\\').replace('\\"', '"') + return value + + +def dict_from_cookiejar(cj): + """Returns a key/value dictionary from a CookieJar. + + :param cj: CookieJar object to extract cookies from. + :rtype: dict + """ + + cookie_dict = {} + + for cookie in cj: + cookie_dict[cookie.name] = cookie.value + + return cookie_dict + + +def add_dict_to_cookiejar(cj, cookie_dict): + """Returns a CookieJar from a key/value dictionary. + + :param cj: CookieJar to insert cookies into. + :param cookie_dict: Dict of key/values to insert into CookieJar. + :rtype: CookieJar + """ + + return cookiejar_from_dict(cookie_dict, cj) + + +def get_encodings_from_content(content): + """Returns encodings from given content string. + + :param content: bytestring to extract encodings from. + """ + warnings.warn(( + 'In requests 3.0, get_encodings_from_content will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + charset_re = re.compile(r']', flags=re.I) + pragma_re = re.compile(r']', flags=re.I) + xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') + + return (charset_re.findall(content) + + pragma_re.findall(content) + + xml_re.findall(content)) + + +def get_encoding_from_headers(headers): + """Returns encodings from given HTTP Header Dict. + + :param headers: dictionary to extract encoding from. + :rtype: str + """ + + content_type = headers.get('content-type') + + if not content_type: + return None + + content_type, params = cgi.parse_header(content_type) + + if 'charset' in params: + return params['charset'].strip("'\"") + + if 'text' in content_type: + return 'ISO-8859-1' + + +def stream_decode_response_unicode(iterator, r): + """Stream decodes a iterator.""" + + if r.encoding is None: + for item in iterator: + yield item + return + + decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace') + for chunk in iterator: + rv = decoder.decode(chunk) + if rv: + yield rv + rv = decoder.decode(b'', final=True) + if rv: + yield rv + + +def iter_slices(string, slice_length): + """Iterate over slices of a string.""" + pos = 0 + if slice_length is None or slice_length <= 0: + slice_length = len(string) + while pos < len(string): + yield string[pos:pos + slice_length] + pos += slice_length + + +def get_unicode_from_response(r): + """Returns the requested content back in unicode. + + :param r: Response object to get unicode content from. + + Tried: + + 1. charset from content-type + 2. fall back and replace all unicode characters + + :rtype: str + """ + warnings.warn(( + 'In requests 3.0, get_unicode_from_response will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + tried_encodings = [] + + # Try charset from content-type + encoding = get_encoding_from_headers(r.headers) + + if encoding: + try: + return str(r.content, encoding) + except UnicodeError: + tried_encodings.append(encoding) + + # Fall back: + try: + return str(r.content, encoding, errors='replace') + except TypeError: + return r.content + + +# The unreserved URI characters (RFC 3986) +UNRESERVED_SET = frozenset( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~") + + +def unquote_unreserved(uri): + """Un-escape any percent-escape sequences in a URI that are unreserved + characters. This leaves all reserved, illegal and non-ASCII bytes encoded. + + :rtype: str + """ + parts = uri.split('%') + for i in range(1, len(parts)): + h = parts[i][0:2] + if len(h) == 2 and h.isalnum(): + try: + c = chr(int(h, 16)) + except ValueError: + raise InvalidURL("Invalid percent-escape sequence: '%s'" % h) + + if c in UNRESERVED_SET: + parts[i] = c + parts[i][2:] + else: + parts[i] = '%' + parts[i] + else: + parts[i] = '%' + parts[i] + return ''.join(parts) + + +def requote_uri(uri): + """Re-quote the given URI. + + This function passes the given URI through an unquote/quote cycle to + ensure that it is fully and consistently quoted. + + :rtype: str + """ + safe_with_percent = "!#$%&'()*+,/:;=?@[]~" + safe_without_percent = "!#$&'()*+,/:;=?@[]~" + try: + # Unquote only the unreserved characters + # Then quote only illegal characters (do not quote reserved, + # unreserved, or '%') + return quote(unquote_unreserved(uri), safe=safe_with_percent) + except InvalidURL: + # We couldn't unquote the given URI, so let's try quoting it, but + # there may be unquoted '%'s in the URI. We need to make sure they're + # properly quoted so they do not cause issues elsewhere. + return quote(uri, safe=safe_without_percent) + + +def address_in_network(ip, net): + """This function allows you to check if an IP belongs to a network subnet + + Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 + returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 + + :rtype: bool + """ + ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0] + netaddr, bits = net.split('/') + netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0] + network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask + return (ipaddr & netmask) == (network & netmask) + + +def dotted_netmask(mask): + """Converts mask from /xx format to xxx.xxx.xxx.xxx + + Example: if mask is 24 function returns 255.255.255.0 + + :rtype: str + """ + bits = 0xffffffff ^ (1 << 32 - mask) - 1 + return socket.inet_ntoa(struct.pack('>I', bits)) + + +def is_ipv4_address(string_ip): + """ + :rtype: bool + """ + try: + socket.inet_aton(string_ip) + except socket.error: + return False + return True + + +def is_valid_cidr(string_network): + """ + Very simple check of the cidr format in no_proxy variable. + + :rtype: bool + """ + if string_network.count('/') == 1: + try: + mask = int(string_network.split('/')[1]) + except ValueError: + return False + + if mask < 1 or mask > 32: + return False + + try: + socket.inet_aton(string_network.split('/')[0]) + except socket.error: + return False + else: + return False + return True + + +@contextlib.contextmanager +def set_environ(env_name, value): + """Set the environment variable 'env_name' to 'value' + + Save previous value, yield, and then restore the previous value stored in + the environment variable 'env_name'. + + If 'value' is None, do nothing""" + value_changed = value is not None + if value_changed: + old_value = os.environ.get(env_name) + os.environ[env_name] = value + try: + yield + finally: + if value_changed: + if old_value is None: + del os.environ[env_name] + else: + os.environ[env_name] = old_value + + +def should_bypass_proxies(url, no_proxy): + """ + Returns whether we should bypass proxies or not. + + :rtype: bool + """ + get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper()) + + # First check whether no_proxy is defined. If it is, check that the URL + # we're getting isn't in the no_proxy list. + no_proxy_arg = no_proxy + if no_proxy is None: + no_proxy = get_proxy('no_proxy') + netloc = urlparse(url).netloc + + if no_proxy: + # We need to check whether we match here. We need to see if we match + # the end of the netloc, both with and without the port. + no_proxy = ( + host for host in no_proxy.replace(' ', '').split(',') if host + ) + + ip = netloc.split(':')[0] + if is_ipv4_address(ip): + for proxy_ip in no_proxy: + if is_valid_cidr(proxy_ip): + if address_in_network(ip, proxy_ip): + return True + elif ip == proxy_ip: + # If no_proxy ip was defined in plain IP notation instead of cidr notation & + # matches the IP of the index + return True + else: + for host in no_proxy: + if netloc.endswith(host) or netloc.split(':')[0].endswith(host): + # The URL does match something in no_proxy, so we don't want + # to apply the proxies on this URL. + return True + + # If the system proxy settings indicate that this URL should be bypassed, + # don't proxy. + # The proxy_bypass function is incredibly buggy on OS X in early versions + # of Python 2.6, so allow this call to fail. Only catch the specific + # exceptions we've seen, though: this call failing in other ways can reveal + # legitimate problems. + with set_environ('no_proxy', no_proxy_arg): + try: + bypass = proxy_bypass(netloc) + except (TypeError, socket.gaierror): + bypass = False + + if bypass: + return True + + return False + + +def get_environ_proxies(url, no_proxy=None): + """ + Return a dict of environment proxies. + + :rtype: dict + """ + if should_bypass_proxies(url, no_proxy=no_proxy): + return {} + else: + return getproxies() + + +def select_proxy(url, proxies): + """Select a proxy for the url, if applicable. + + :param url: The url being for the request + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs + """ + proxies = proxies or {} + urlparts = urlparse(url) + if urlparts.hostname is None: + return proxies.get(urlparts.scheme, proxies.get('all')) + + proxy_keys = [ + urlparts.scheme + '://' + urlparts.hostname, + urlparts.scheme, + 'all://' + urlparts.hostname, + 'all', + ] + proxy = None + for proxy_key in proxy_keys: + if proxy_key in proxies: + proxy = proxies[proxy_key] + break + + return proxy + + +def default_user_agent(name="python-requests"): + """ + Return a string representing the default user agent. + + :rtype: str + """ + return '%s/%s' % (name, __version__) + + +def default_headers(): + """ + :rtype: requests.structures.CaseInsensitiveDict + """ + return CaseInsensitiveDict({ + 'User-Agent': default_user_agent(), + 'Accept-Encoding': ', '.join(('gzip', 'deflate')), + 'Accept': '*/*', + 'Connection': 'keep-alive', + }) + + +def parse_header_links(value): + """Return a dict of parsed link headers proxies. + + i.e. Link: ; rel=front; type="image/jpeg",; rel=back;type="image/jpeg" + + :rtype: list + """ + + links = [] + + replace_chars = ' \'"' + + for val in re.split(', *<', value): + try: + url, params = val.split(';', 1) + except ValueError: + url, params = val, '' + + link = {'url': url.strip('<> \'"')} + + for param in params.split(';'): + try: + key, value = param.split('=') + except ValueError: + break + + link[key.strip(replace_chars)] = value.strip(replace_chars) + + links.append(link) + + return links + + +# Null bytes; no need to recreate these on each call to guess_json_utf +_null = '\x00'.encode('ascii') # encoding to ASCII for Python 3 +_null2 = _null * 2 +_null3 = _null * 3 + + +def guess_json_utf(data): + """ + :rtype: str + """ + # JSON always starts with two ASCII characters, so detection is as + # easy as counting the nulls and from their location and count + # determine the encoding. Also detect a BOM, if present. + sample = data[:4] + if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): + return 'utf-32' # BOM included + if sample[:3] == codecs.BOM_UTF8: + return 'utf-8-sig' # BOM included, MS style (discouraged) + if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): + return 'utf-16' # BOM included + nullcount = sample.count(_null) + if nullcount == 0: + return 'utf-8' + if nullcount == 2: + if sample[::2] == _null2: # 1st and 3rd are null + return 'utf-16-be' + if sample[1::2] == _null2: # 2nd and 4th are null + return 'utf-16-le' + # Did not detect 2 valid UTF-16 ascii-range characters + if nullcount == 3: + if sample[:3] == _null3: + return 'utf-32-be' + if sample[1:] == _null3: + return 'utf-32-le' + # Did not detect a valid UTF-32 ascii-range character + return None + + +def prepend_scheme_if_needed(url, new_scheme): + """Given a URL that may or may not have a scheme, prepend the given scheme. + Does not replace a present scheme with the one provided as an argument. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme) + + # urlparse is a finicky beast, and sometimes decides that there isn't a + # netloc present. Assume that it's being over-cautious, and switch netloc + # and path if urlparse decided there was no netloc. + if not netloc: + netloc, path = path, netloc + + return urlunparse((scheme, netloc, path, params, query, fragment)) + + +def get_auth_from_url(url): + """Given a url with authentication components, extract them into a tuple of + username,password. + + :rtype: (str,str) + """ + parsed = urlparse(url) + + try: + auth = (unquote(parsed.username), unquote(parsed.password)) + except (AttributeError, TypeError): + auth = ('', '') + + return auth + + +# Moved outside of function to avoid recompile every call +_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$') +_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$') + + +def check_header_validity(header): + """Verifies that header value is a string which doesn't contain + leading whitespace or return characters. This prevents unintended + header injection. + + :param header: tuple, in the format (name, value). + """ + name, value = header + + if isinstance(value, bytes): + pat = _CLEAN_HEADER_REGEX_BYTE + else: + pat = _CLEAN_HEADER_REGEX_STR + try: + if not pat.match(value): + raise InvalidHeader("Invalid return character or leading space in header: %s" % name) + except TypeError: + raise InvalidHeader("Value for header {%s: %s} must be of type str or " + "bytes, not %s" % (name, value, type(value))) + + +def urldefragauth(url): + """ + Given a url remove the fragment and the authentication part. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url) + + # see func:`prepend_scheme_if_needed` + if not netloc: + netloc, path = path, netloc + + netloc = netloc.rsplit('@', 1)[-1] + + return urlunparse((scheme, netloc, path, params, query, '')) + + +def rewind_body(prepared_request): + """Move file pointer back to its recorded starting position + so it can be read again on redirect. + """ + body_seek = getattr(prepared_request.body, 'seek', None) + if body_seek is not None and isinstance(prepared_request._body_position, integer_types): + try: + body_seek(prepared_request._body_position) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect.") + else: + raise UnrewindableBodyError("Unable to rewind request body for redirect.") diff --git a/swig/python/requests/utils.pyc b/swig/python/requests/utils.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b99479a829d8e4c5dd693342aff6d43172528def GIT binary patch literal 26811 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 delta 1016 zcmZ{iOKTKC5XYtx{BnleMN*+Fmq*o7Fg|K8s31&91GYM!S zf)TtL`rtwEEP{dr!J|iSdi01QIp-C`Eh$3HT4QcxhNBi{1>QC0`D} zHK@vFAj;~Yc`%FZNnX)?QWM6QSX1B3q3+nAjTHGADsKwfOw)rTHHbEnd=gU)S>1O5 zBprwg$+2(_Q5ZEB!YH=eW)#=s)#$&_atO(|gMWd6&b2_SK3MDfaM%dnBhe!aQ4qE` zrRJQS>>dzx%{`GrLt<2n;wE?Ui95iZeC?Ktn)5Vv1xu6belA^7y}5!IR3o_`J$nlA zzC43SP~7nsnBt^5pPwB4yX7r<^u0x|E!}Q(!mr15jsHG>ON^<`!qgzjdAm`#N;D`~ z@?&5JYe6G!)WbktWwvScvC!j=BL+80!n4%RLT|qwfaC0t!;mq^3}hBE$KnyEPaTk; zz^NkKjv=h1Wm~3YsprKugW(iVz444?OZLq@vz-^o;-^T=9eDC}_6ESCi=*)78;9eH>j( e7oI+ftZ`0TT@KCxEh@1%!buc(Jlg-n{?T90dZB>; diff --git a/swig/python/test.py b/swig/python/test.py index f50400a..44a4723 100644 --- a/swig/python/test.py +++ b/swig/python/test.py @@ -12,8 +12,10 @@ print "AreaD8 - Input Data ID : " + dataid swat = access.getModelServiceByID("5acf6bde18f9e109f0aafa38") recordid = swat.invoke([access.createDataConfigurationItem("851a1985-a3f6-4c13-be53-f1c765022929", "D8FlowDirection", dataid)]) record = access.getModelServiceRunningRecordByID(recordid) -record.waitForFinished() +instance = access.getModelServiceInstanceByGUID(record.guid) +instance.wait4Status(4, 7200, True) print "AreaD8 has been finished" +record.refresh() for index,item in enumerate(record.outputs): dat = access.getDataByID(item.dataid) dat.save("E:\\DemoData\\GeoModeling\\udx_zip_d8\\AreaD8_" + item.eventname + ".zip") diff --git a/swig/python/test2.py b/swig/python/test2.py new file mode 100644 index 0000000..f058b15 --- /dev/null +++ b/swig/python/test2.py @@ -0,0 +1,8 @@ +from setup import OGMSService_DEBUG + + +server = OGMSService_DEBUG.CreateServer("127.0.0.1", 8060) +access = server.getServiceAccess() +mis = access.getModelServiceInstanceByGUID("3c5a3eb6-5872-4105-b653-5e242e131b9e") +if mis != None: + mis.wait4Status(4, 7200, True) \ No newline at end of file diff --git a/swig/python/utils.py b/swig/python/utils.py index 77180de..5d4ec13 100644 --- a/swig/python/utils.py +++ b/swig/python/utils.py @@ -27,4 +27,8 @@ class HttpHelper: @staticmethod def Request_put_sync(ip, port, path): - pass \ No newline at end of file + conn = httplib.HTTPConnection(ip, port) + conn.request("PUT", path) + res = conn.getresponse() + jsData = json.loads(res.read()) + return jsData \ No newline at end of file diff --git a/swig/python/utils.pyc b/swig/python/utils.pyc index 03126a490d4e9c082b159e5b2f9bea946bae403c..02d5fc0497e5424507156cda40107da86bd98a44 100644 GIT binary patch delta 92 zcmcc2eS?Rc`7SV06Eh+v<*hbd>W k0u#^VZWdlXE}#$tlMtf-BM+k}yf*VLozR&18nS+&=jS0wM YV4AGV>clAmWNCo7KuL$m>sVI-0JK97!~g&Q diff --git a/test/test.cpp b/test/test.cpp index 08aed12..50cc5bc 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -26,23 +26,25 @@ int main() } // upload data NJGIS::SERVICE::INjData* pData = pServiceAccess->getDataServiceByID("gd_b3f13f70-4891-11e8-b000-3571b206c6be"); + pData->saveAs("E:\\DemoData\\GeoModeling\\udx_zip_d8\\tmp.zip"); + - if(pData != NULL) - { - std::cout << pData->getID() << " - " << pData->getSize() << " - " << pData->getGenarationDateTime() << " - " << pData->getTag() << std::endl; - NJGIS::SERVICE::INjModelService* pMservice = pServiceAccess->getModelServiceByOID("5ac9dbcdbe7b8d12c484952e"); - NJGIS::SERVICE::INjDataConfiguration * pDataconfig = pServiceAccess->createDataConfig(); - pDataconfig->insertData("04579ee0-5983-4d75-bdc9-a1a460229aa0","LoadHydroResponseUnit",pData->getID()); - std::string recordid; - // invoke model service - if(pMservice->invoke(pDataconfig, recordid) == 1 ) - { - std::cout << "Invoke successfully! Model Service Record ID is : [" << recordid << "]" << std::endl; - NJGIS::SERVICE::INjModelServiceRecord* pRecord = pServiceAccess->getModelServiceRecordByID(recordid.c_str()); - NJGIS::SERVICE::INjModelServiceInstance* pInstance = pServiceAccess->getModelServiceInstanceByGUID(pRecord->getGUID()); - pInstance->wait4Status(NJGIS::SERVICE::NjModelInstanceStatus::INSTA_FINISHED, 7200, true); - } - } + //if(pData != NULL) + //{ + // std::cout << pData->getID() << " - " << pData->getSize() << " - " << pData->getGenarationDateTime() << " - " << pData->getTag() << std::endl; + // NJGIS::SERVICE::INjModelService* pMservice = pServiceAccess->getModelServiceByOID("5ac9dbcdbe7b8d12c484952e"); + // NJGIS::SERVICE::INjDataConfiguration * pDataconfig = pServiceAccess->createDataConfig(); + // pDataconfig->insertData("04579ee0-5983-4d75-bdc9-a1a460229aa0","LoadHydroResponseUnit",pData->getID()); + // std::string recordid; + // // invoke model service + // if(pMservice->invoke(pDataconfig, recordid) == 1 ) + // { + // std::cout << "Invoke successfully! Model Service Record ID is : [" << recordid << "]" << std::endl; + // NJGIS::SERVICE::INjModelServiceRecord* pRecord = pServiceAccess->getModelServiceRecordByID(recordid.c_str()); + // NJGIS::SERVICE::INjModelServiceInstance* pInstance = pServiceAccess->getModelServiceInstanceByGUID(pRecord->getGUID()); + // pInstance->wait4Status(NJGIS::SERVICE::NjModelInstanceStatus::INSTA_FINISHED, 7200, true); + // } + //} } } diff --git a/utils/NxHttp.cpp b/utils/NxHttp.cpp index cd5bc44..707b0c9 100644 --- a/utils/NxHttp.cpp +++ b/utils/NxHttp.cpp @@ -1,5 +1,6 @@ #include "NxHttp.h" #include "curl/curl.h" +#include size_t NJGIS::SERVICE::NjHttpHelper::req_reply( void *ptr, size_t size, size_t nmemb, void *stream ) { @@ -196,4 +197,41 @@ int NJGIS::SERVICE::NjHttpHelper::request_put_json_sync( const char* url, Json:: { return -2; } -} \ No newline at end of file +} + +int NJGIS::SERVICE::NjHttpHelper::download( const char* url, const char* path ) +{ + FILE* fp = fopen(path, "wb"); + if (!fp) { + printf("!!! Failed to create file on the disk\n"); + return false; + } + + // init curl + CURL *curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NJGIS::SERVICE::NjHttpHelper::req_reply_file); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + + CURLcode rc = curl_easy_perform(curl); + if (rc) { + return -1; + } + + long res_code = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code); + if (!((res_code == 200 || res_code == 201) && rc != CURLE_ABORTED_BY_CALLBACK)) { + return -2; + } + + curl_easy_cleanup(curl); + fclose(fp); + + return 1; +} + +size_t NJGIS::SERVICE::NjHttpHelper::req_reply_file( void *ptr, size_t size, size_t nmemb, FILE *stream ) +{ + return fwrite(ptr, size, nmemb, stream); +} diff --git a/utils/NxHttp.h b/utils/NxHttp.h index 3126ca4..e74c09f 100644 --- a/utils/NxHttp.h +++ b/utils/NxHttp.h @@ -38,9 +38,16 @@ namespace NJGIS //! Request -PUT static int request_put_json_sync(const char* url, Json::Value &value); + /* Other */ + //! Download + static int download(const char* url, const char* path); + private: //! reply static size_t req_reply(void *ptr, size_t size, size_t nmemb, void *stream); + + //! file reply + static size_t req_reply_file(void *ptr, size_t size, size_t nmemb, FILE *stream); }; } } -- Gitee From 7e13cd1eb6ecf9ae783aed5fb39102b2dc1ee8b0 Mon Sep 17 00:00:00 2001 From: Franklin_Zhang Date: Mon, 7 May 2018 16:48:00 +0800 Subject: [PATCH 04/17] add CommonMethod in utils Signed-off-by: Franklin_Zhang --- swig/python/data.py | 10 +++--- swig/python/data.pyc | Bin 2031 -> 2356 bytes swig/python/modelserivce.py | 8 +++-- swig/python/modelserivce.pyc | Bin 2319 -> 2364 bytes swig/python/modelserviceinstance.py | 11 +++--- swig/python/modelservicerecord.py | 16 +++++---- swig/python/runninglog.py | 5 +-- swig/python/server.py | 45 +++++++++++++++++------- swig/python/server.pyc | Bin 5290 -> 5917 bytes swig/python/test.py | 42 ++++++++++------------ swig/python/test2.py | 16 +++++---- swig/python/utils.py | 52 ++++++++++++++++++++++------ swig/python/utils.pyc | Bin 1624 -> 2570 bytes 13 files changed, 129 insertions(+), 76 deletions(-) diff --git a/swig/python/data.py b/swig/python/data.py index 321e8a2..78eabcf 100644 --- a/swig/python/data.py +++ b/swig/python/data.py @@ -1,6 +1,7 @@ import urllib from utils import HttpHelper +from utils import CommonMethod from base import Service class Data(Service): @@ -15,8 +16,8 @@ class Data(Service): def isExist(self): jsData = HttpHelper.Request_get_sync(self.ip, self.port, "/geodata/json/" + self.id) - if jsData["result"] == "suc" : - if jsData["result"]["data"] == "": + if CommonMethod.getJsonValue(jsData, "result") == "suc" : + if CommonMethod.getJsonValue(jsData, "data") == "": return False return True return False @@ -26,8 +27,9 @@ class Data(Service): return 1 class DataConfigrationItem: - def __init__(self, stateid, eventname, dataid, destoryed = False, requested = False, optional = False): + def __init__(self, stateid, statename, eventname, dataid, destoryed = False, requested = False, optional = False): self.stateid = stateid + self.statename = statename self.eventname = eventname self.dataid = dataid self.destoryed = destoryed @@ -36,5 +38,5 @@ class DataConfigrationItem: @staticmethod def MakeUpDataItem(jsData): - dat = DataConfigrationItem(jsData["StateId"], jsData["Event"], jsData["DataId"], bool(jsData["Destroyed"])) + dat = DataConfigrationItem(jsData["StateId"], jsData["StateName"], jsData["Event"], jsData["DataId"], bool(jsData["Destroyed"])) return dat \ No newline at end of file diff --git a/swig/python/data.pyc b/swig/python/data.pyc index 274e707edcfd387107c5c9659bdebc4c96b3f02a..0a30e8bd95bc8ec15fe40bd08349ed24b8232c53 100644 GIT binary patch delta 1025 zcmYjQ%T5$Q6us52nVtbfFg!#BL9p3C!a_r02+62`2`p+1YA=Qi(=E=>Jsqd26G<>E zh94lE_#>M52`*gt4X#}nz{HoX(1UFvvr!tyQZTNK%JWKl2tFYlPV%lT94 z?U61~U6*ACnouEgj0O6&Z^)WFchKvLQEAO?Byzi%L%~E;*YmA zh6{mB;RH|kzF#gjoyI6Cg8>Pq0=43kv$lFtg5&$#6U2_;Cc6Rt&IU3E`w_Pz4LeNS zZKiQib!$te_PB_g1>6D50p2(&x zjXb4ILvR;Q^#%1^^aOXqptMF~9U8YUG@5u98W+5!i5X@z)*ob9a$(#!r-~ylT)PJ~ zkVV$2FpVN_@kBzUybi#kMj3GNb}PlV5XohDybWe-Hw>N_^#h(zU`(0h$do?U?LPtP5fnNEh!R431pv(m`c6 zl-B-=^pt55QKW!>zz?8HfhZ#}?*@fC?Q=W3J2UUh-q+SeBM*Ns*7kmV9}MZ=6Y}>N z57VFL_nw4wBxxW?Xi1f%w}Ny;GomR`e-M$5NvEWf>m{}Y^@?o%EN#_d0sev8UZA*}UE1Rf`TBP9|gD1q;3J&2DK+cbp8i z@386nOTm3nU{fst%fKQ4i5Buu;AnVM*>@AIHqf?R#7BibLM&Qo!3Gt+{07hbEq%13 fu~FE#l2V#Vp*rPnrQ?32{W|`Ede9WjpmXyt>`Pz% diff --git a/swig/python/modelserivce.py b/swig/python/modelserivce.py index 563c570..3ff3298 100644 --- a/swig/python/modelserivce.py +++ b/swig/python/modelserivce.py @@ -1,6 +1,7 @@ import time from utils import HttpHelper +from utils import CommonMethod from base import Service from data import DataConfigrationItem @@ -29,7 +30,7 @@ class ModelService(Service): def invoke(self, list_data): path = "/modelser/" + self.id + "?ac=run&inputdata=[" for index, item in enumerate(list_data): - path += "{\"StateId\":\"" + item.stateid + "\",\"Event\":\"" + item.eventname + "\",\"DataId\":\"" + item.dataid + "\",\"Destoryed\":\"" + str(item.destoryed) + "\"}" + path += "{\"StateId\":\"" + item.stateid + "\",\"StateName\":\"" + item.statename + "\",\"Event\":\"" + item.eventname + "\",\"DataId\":\"" + item.dataid + "\",\"Destoryed\":\"" + str(item.destoryed) + "\"}" path += "]" jsData = HttpHelper.Request_get_sync(self.ip, self.port, path) recordid = -1 @@ -42,8 +43,9 @@ class ModelService(Service): jsData = HttpHelper.Request_get_sync(self.ip, self.port, path) if jsData["result"] == "suc": jsMs = jsData["data"] - self.status = int(jsMs["ms_status"]) - self.limitation = int(jsMs["ms_limited"]) + self.status = int(CommonMethod.getJsonValue(jsMs, "ms_status")) + self.limitation = int(CommonMethod.getJsonValue(jsMs, "ms_limited")) return 1 return -1 + diff --git a/swig/python/modelserivce.pyc b/swig/python/modelserivce.pyc index 129a64ab0e6728aeb781ea845a7efc03c584344f..8ab12021dae8e21e0d2ff9047ab5f716baffbcb6 100644 GIT binary patch delta 281 zcmeAd+9Sly{F#?)pXBR}?7Nv&4l*z>q%bnnFfe2>Fo>rxF^JbPF;pZnlmNvT8JZax zTw;SKKVvqmuVG=xVg;&TXAm!8V*v5kLDJ$W91P;-Ks|+W4B<6Q3@MxpAYKUvLl!64 zR4y>d%>a~ZW@e~mWk}&-s0A7TWNH-29Zu-7E$I{6LP9j#6+*Vo9oBVs7f>?JVhxJd@>F)j5knVtGKZ#g43ujNX%- u*gi0-Og3iM5>f+d3ep4;B`iQ9tJt@A@&i_n$=lhz*|b4Y2AerJ*ckx@RyyVY delta 217 zcmdlZ)Gx%&{F#?4Fo>rxF^JbPF;s*xlmNvT8JZax zTw*;YKVvpbFJWbJurr980~Hp^F@)DJF{E%XfOsYB3|Smtqd37N7XwhP znVF%Ml_7~Mu*AyY#$hvCnvCLv8e)`8>BIL0{eV6Ef724eEJ{t*JFWGInc2s^BFL{DwU6Q{aK(2ZZlCy_eaIT@;dK&)Gg_db&^dIp;g4yZWEi zrTgpuYtRybh$T_y^Kc{|2HHP#Sbe~{}8)lsQ#&u zp2#VL*ujcyVyk{zk^EnV{DN$rR^{nm4YWO}%9)Yv5B_ZSD{{IZr;Ac7%3)1Tu&s-7 z1|izm*_saUR6cqj8RnhzscWCQoam-=lD|m|YvGfI+~QADZk^WkBlLofV@;=HEOCqx ziw~A(*_By#b(US5WiQRL>m?Qox;)EXQMNIj8Xc}uf(@DKc5U{Pmr5*F+?ZvX%9aPb zP6-Dr3pbu6e0d~1yDFy*df{PHPB6X^gFSyAn-1Ati$S{Uu7GZ(j9@s-)}iZXTb(2+ zY7pnv4U?jvce-I$9Wp``s_&*Q)Q{jcupwaqk|BoBFNa~)Nv(>9p-nq+qN9Xyq_0!| znscOKaXhftBsPb6;@zGd84oENM5i>&Z7+7kXnf2SS?9+(3bSEaEVGjf2T7+m=;vuc z|E5L*Xl#8)7shFC`~qN844og_g-M*og^d(XIEu~F*g2p~i<1XMjf%1u+^6D5H#f4+>p|+fpA7jWR*mn*? z0;c9*jf8IljUM_oI zNnQi-VT6VRUniNyCZS}vpZTy1Ugt|jVek!*79G?FpCXQnqu`qqy$PZr#mEcZplA!^ z;!(x5&qdYUY|F#cjgmU7&rn%m;xqZt@NpiU@~GPOjRzAP%Xi7up!F_&v-MA zm}dFSQkhwX3#@pH*UJ`Xbnm)p+{c-lH@C)47l|nb=zA1UJJ7a1;oBpNJV-OD@o77} z%nJ=Y1qLm&HT}+owD$nUZ@|xdjZ);Ti6;c_@Err$I{~s5-yxRc7myeUMsrRuKEK>O ze)ktU+uuirk_Wtw4Ecf469eIfny3f-5e;k)OKF4Jwn_#b;j_uVG>FFsXf9xam_#jTKqvlU=O1!YDzW*zrKcGQj5FXm&P z_^&9fM(?Bc(eTfGRpnGV=)1y0_g(b%wG~~2m8p)L^gEI7TA&On!8akDnm6#v=?9(S ziBCQc`GzXz>Jb+Q0cNw|fSRyWyL)^e)4dIu;|npXrfRNMz6<1DHw_>7T*3sk{{rS5 zf&a-k>KXD?$v-Ip0l|8N2@Ldc6ZR$;`05FkCjyK)*nZqZn3nv0L;j`NR&qMR|V1JV;mdKb26$_ zh!FFTPDK&!R`iNsH_%9-L;I5i*SzBhECF}1HCcIZhm+B<6ij*Q3UE910;&{NUftXR ztGRf8^D>-Xz5EQX9n}(Z3BIo9B(-X&XS*=eqgBX5;xMscsFx7Ix6wcN9?4rIKPLG( z$v#O4GBugD&U@w2z);Ll8jv;9tTxx1Yt07!EjQ~5YP_$qc^7^3kLWQrA%!FsQy3%RiRdca1k(J;7P^!Itc!IUF6 zTQOIScl-~jM~8$f4xsXja+}8(>U}(pmZjUY^tAFGxL_AV;cZyNiStDXH%hbC5)vX0zU`d7LB@V|<2b7BAh delta 1933 zcmZux&2Jl35T9pz*WO)!Y+~ob2~}uXD$@i~6`=-7XlY$YjS|qS#D__ny53E2WIK&_ zQ?(E)s=|p|_0I4IaIJ*+1CY3I;ST@_aRCmM5JxV|@9oA*D{Q^lnR)Nc$8TodS1*6_ z;%xfwg1zJY(QH%vOY`?Kui(2!v*!;p)HA4Qkno7S40TQFWvQ8sWP`dn>RHsZBH5&_ zO+AO2P9$fko2OoZnuSQtX}L(vBFh%}25kxQZ2E%ei0I>Hi9F|6o7dVr)Gm2~Zqy2o zen0j2q^Jua)K=>5e2#-GAkY*O5^cdW%WI0)RbIh4)yhsQH$8K>C=S?BhN{Cf-G4%1 zh7QtnB&dG#XWB^7FhfIwLW2&7c2b(A>A)b*pejBlRlRJ&<`ULQSUX{zgw2CJB(D&u zic}3vZMsBN4gl8OXlpF`jI*zD!d6BXCiI2)_T+zsDJ>k8X~?Eiw3DR+6WNKqRr;_` z>?FnTO{*uF**K+sGnSUIA$d{gg7f$G{UF@j_QTEK zLBB0+C>?BDO#J?S&mXixU#8S;bIJt#(o#e7f{CK^0`;qNMU}GCi!c^|keC&waD^?Z z;(JjMZ5%XsP4d!Zv$<^Z>PxqhGKKont{npUOjHFxAG3fyW&wT70{WN*^vnWz{=~>L z7bDLckmnDO=g%?nF&iVFp*1gop7#>ySxBHy6Oc{=Xij83C^22q@CN>1X(!n2FG=oZ zQVpvkYZ@q)NX~;KsAgDP-|aJ?(4S^f12__BbK3&bjwjDRwQ#K33DzQ@eS4}h!`c9j zNX*4R|De9MzjdLLm={?DDJjo+^_8c+%a^c&7J1e)V(0|}xK=+ppNo05n*XOdGN~hL zb1!u;gtDkM3JVRyCjmok)Kkx78~H<$5~+po9E5`;V|fvKXVg!H`{L~5Mv)t5|7QOO1qUEBSz(+#3G56AAb0$&Ps zX>#HO0uRTT91rrnPTL>&?cISV(`s+>#EdS29w^-bD2&uG-(v8tpViIx2H)QA`fnnw Spu!|C@+p_!z|lW7dGTLer!H#% diff --git a/swig/python/test.py b/swig/python/test.py index 44a4723..2beb7af 100644 --- a/swig/python/test.py +++ b/swig/python/test.py @@ -2,27 +2,21 @@ from setup import OGMSService_DEBUG server = OGMSService_DEBUG.CreateServer("127.0.0.1", 8060) -print str(server.connect()) -access = server.getServiceAccess() -list_ms = access.getModelServicesList() -for index, item in enumerate(list_ms): - print "ID : " + item.id + " - Name : " + item.name + " - Type : " + item.type -dataid = access.uploadDataByFile("aread8_input", "E:\\DemoData\\GeoModeling\\udx_zip_d8\\d8.tif") -print "AreaD8 - Input Data ID : " + dataid -swat = access.getModelServiceByID("5acf6bde18f9e109f0aafa38") -recordid = swat.invoke([access.createDataConfigurationItem("851a1985-a3f6-4c13-be53-f1c765022929", "D8FlowDirection", dataid)]) -record = access.getModelServiceRunningRecordByID(recordid) -instance = access.getModelServiceInstanceByGUID(record.guid) -instance.wait4Status(4, 7200, True) -print "AreaD8 has been finished" -record.refresh() -for index,item in enumerate(record.outputs): - dat = access.getDataByID(item.dataid) - dat.save("E:\\DemoData\\GeoModeling\\udx_zip_d8\\AreaD8_" + item.eventname + ".zip") - -# conn = httplib.HTTPConnection("127.0.0.1:8060") -# conn.request("GET", "/modelser/json/all") -# res = conn.getresponse() -# strData = res.read() -# jsData = json.loads(strData) -# print jsData['result'] \ No newline at end of file +server.connect() +if server.connect() : + access = server.getServiceAccess() + list_ms = access.getModelServicesList() + for index, item in enumerate(list_ms): + print "ID : " + item.id + " - Name : " + item.name + " - Type : " + item.type + dataid = access.uploadDataByFile("aread8_input", "E:\\DemoData\\GeoModeling\\udx_zip_d8\\d8.tif") + print "AreaD8 - Input Data ID : " + dataid + swat = access.getModelServiceByID("5acf6bde18f9e109f0aafa38") + recordid = swat.invoke([access.createDataConfigurationItem("851a1985-a3f6-4c13-be53-f1c765022929", "D8FlowDirection", dataid)]) + record = access.getModelServiceRunningRecordByID(recordid) + instance = access.getModelServiceInstanceByGUID(record.guid) + instance.wait4Status(4, 7200, True) + print "AreaD8 has been finished" + record.refresh() + for index,item in enumerate(record.outputs): + dat = access.getDataByID(item.dataid) + dat.save("E:\\DemoData\\GeoModeling\\udx_zip_d8\\AreaD8_" + item.eventname + ".zip") \ No newline at end of file diff --git a/swig/python/test2.py b/swig/python/test2.py index f058b15..1d6c23b 100644 --- a/swig/python/test2.py +++ b/swig/python/test2.py @@ -1,8 +1,10 @@ -from setup import OGMSService_DEBUG +import httplib +import urllib - -server = OGMSService_DEBUG.CreateServer("127.0.0.1", 8060) -access = server.getServiceAccess() -mis = access.getModelServiceInstanceByGUID("3c5a3eb6-5872-4105-b653-5e242e131b9e") -if mis != None: - mis.wait4Status(4, 7200, True) \ No newline at end of file +try : + conn = httplib.HTTPConnection("127.0.0.1", 8060) + conn.request("GET", "/ping") + res = conn.getresponse() + print res.read() +except Exception, e: + print "Error in requesting!" \ No newline at end of file diff --git a/swig/python/utils.py b/swig/python/utils.py index 5d4ec13..d01636a 100644 --- a/swig/python/utils.py +++ b/swig/python/utils.py @@ -6,19 +6,25 @@ import requests class HttpHelper: @staticmethod def Request_get_sync(ip, port, path): - conn = httplib.HTTPConnection(ip, port) - conn.request("GET", path) - res = conn.getresponse() - jsData = json.loads(res.read()) - return jsData + try : + conn = httplib.HTTPConnection(ip, port) + conn.request("GET", path) + res = conn.getresponse() + jsData = json.loads(res.read()) + return jsData + except Exception, e : + return "Error" @staticmethod def Request_get_stream_sync(ip, port, path): - conn = httplib.HTTPConnection(ip, port) - conn.request("GET", path) - res = conn.getresponse() - jsData = res.read() - return jsData + try : + conn = httplib.HTTPConnection(ip, port) + conn.request("GET", path) + res = conn.getresponse() + jsData = res.read() + return jsData + except Exception, e : + return "Error" @staticmethod @@ -31,4 +37,28 @@ class HttpHelper: conn.request("PUT", path) res = conn.getresponse() jsData = json.loads(res.read()) - return jsData \ No newline at end of file + return jsData + +class CommonMethod: + @staticmethod + def IsGUID(statevalue): + if isinstance(statevalue, (str, unicode)) : + if len(statevalue) == 36: + strs = statevalue.split('-') + for index, item in enumerate(strs): + if len(item) == 0: + return False + return True + else : + return False + else: + return False + + @staticmethod + def getJsonValue(jsobject, key): + if jsobject == "" or isinstance(jsobject, (str, unicode)): + return "" + if key in jsobject: + return jsobject[key] + else: + return "" \ No newline at end of file diff --git a/swig/python/utils.pyc b/swig/python/utils.pyc index 02d5fc0497e5424507156cda40107da86bd98a44..7db62cf903c0620d61a3a6b580dff7082c3f797c 100644 GIT binary patch literal 2570 zcmb_dU2hvz5S_bgJ0^AO(hnejc&I95fvDgSgb<1olD4WC1LrI~wBn{?P>w>`!-W_OIAW-W^y|1Gz9D-}If86)1oj+5ZOZU*aYGt@ zMfO*vip3na!~m7ylT_d|?;d!{t<90A1)Eh>Rtg68i0lG}JbUi1puasDJ?xi7VH2N~ zg-%!Y<-$7eFJbzH^_6w=vTzp0z<7s6JTfoi)ag)V90HZF2 zdi)`J7sl>m9(NWyBtSe<2(Mx49SA!$gfy6q9`(73ZfG)cWKbKWUcK#shJGGb@yuyf z?PR%i7j}U-EM1tFu8#i~G>c$Mpb;m$L|o0?Lg#-f%^vTl%kSZ%Q60ATMV9#(wJ8|m zIs@JY=bi9g7?!hDF<;cE+``?C`6a=!ChF>?Wz%U9&+K%n+&P`j%5;%aWdb@BYnIF` z3NMYA7}0f#k0?HYIJH)L=PTq02MGh^Xim#?FLgWJhTh*VXS1?+!264Y%lISo>uByv z2>UO{9CXb+3A2EZPN%=f`rjo zHVw?@7y!5ceZM8u4R)Ze4f)(Fa9lk==$0u+-7|ggbUok0GpFF}+rtZcz%sz=at}}9 zuY~J+=#JSc0cbJkDc`L@jXtILjN&VbI}oS0Ywvs@Mnr>0D&L|$uADiRmMF@LD#vSI rKQH<+w=r|_$U7}DJ?G3;%***KQlx*Znc^oVu98a!k1hU!>$m>~(Kz$l delta 413 zcmeAYxxpjN{F#?aLho@@G6NJa18D~!E_RYp_nN zs+l~6C7IRTHAI7bayw%blLp)5kBkKx1u+6i4OSo#1mXvQlm@YY2(TCjkfi}KB8U@2fXol#1`#|U zf)_;a0STbxj+56gOAGM>ImO7X;F)}%S%(`*^JFoWJVuGhtt{1yOq2hxC@K?Yyf0@# zX-Rx>WnQw(YgP)V1MFYr(_^1Tr@Y153oXjMM=Ro`t gke7;53rkarONxUSfciWpzv2|)0SWT}gAE9o0Ef6fCIA2c -- Gitee From b9df616d80134ec3d222ce3f6f9ec112383fd396 Mon Sep 17 00:00:00 2001 From: Franklin_Zhang Date: Mon, 7 May 2018 17:12:37 +0800 Subject: [PATCH 05/17] build __init__.py to make python as a package Signed-off-by: Franklin_Zhang --- swig/python/__init__.py | 7 ++++++- swig/python/data.pyc | Bin 2356 -> 2356 bytes swig/python/modelserivce.pyc | Bin 2364 -> 2447 bytes swig/python/modelserviceinstance.pyc | Bin 3858 -> 3965 bytes swig/python/modelservicerecord.pyc | Bin 2211 -> 2358 bytes swig/python/runninglog.pyc | Bin 1748 -> 1931 bytes swig/python/server.pyc | Bin 5917 -> 6133 bytes swig/python/setup.py | 7 ------- swig/python/setup.pyc | Bin 658 -> 0 bytes swig/python/utils.pyc | Bin 2570 -> 2626 bytes 10 files changed, 6 insertions(+), 8 deletions(-) delete mode 100644 swig/python/setup.py delete mode 100644 swig/python/setup.pyc diff --git a/swig/python/__init__.py b/swig/python/__init__.py index fcd657b..a609579 100644 --- a/swig/python/__init__.py +++ b/swig/python/__init__.py @@ -1,2 +1,7 @@ -from setup import OGMSService_DEBUG +from server import Server +from data import DataConfigrationItem +class OGMSService_DEBUG: + @staticmethod + def CreateServer(ip, port): + return Server(ip, port) \ No newline at end of file diff --git a/swig/python/data.pyc b/swig/python/data.pyc index 0a30e8bd95bc8ec15fe40bd08349ed24b8232c53..a8fc10c4d3621b05ec5da86bd92ea06c8426c370 100644 GIT binary patch delta 21 dcmdlYv_*)W`7{}R9Htwn5002}W2n7HD delta 21 dcmdlYv_*)W`7K9SN&fHBK5DY^!xB{`~eR`@&1Na zd#@Kwza?Y}u>vJPQb41COe5C!zDC0!^AY>(8>AY0gv7^ZpbKor0TRMyE$AIjg%wV@ z(#o<{b1lt3wvwN2gUE9?bnE_j>z*BUOTlWWIjSVZUok)fuBRq1f2eOn#;xe1@Fkzx zQAW)dYsCH17c}8^%>tddFJ^JMgN`RcM^6-TjojeCM@J#i=z8c9I>1iw{K`DJD!Tt> zsvJr3F~PX2`tw^N$r=GK*s9=BN-iDy)XXjMp36V?)BIh#)!eE#j#4`)!9$E%L97wM zj9|{4`#Zz4Y_>xNsE;BFsl<$&4yt8ohFuW6cGtnWJ5{BMh%i(fES76U_dSRv@2g7c b_w{yaJqaHdh$>s)hxHdCzv6|QoTs`2=$upG delta 443 zcmX|+&q~8U5XNV+*-g?v5Smi0si&$$s-OoC-g=Z?tPunwQq)ukv??UM)q_-em9hul z!JG6d^+kLG!HW-|Gex^Fzn%G*op1KZdn@_kyO^6*Kcg%7JA&>eMS3#vH}(YdO^8gu z7$7#GC!wz(QdCRmnsAK}D|iGL0h~q_#0bZMH5u1m-&=^NbHO>CQB@)7ALSS)L(O>czSM^wJ;hmnU{oNi64Ysb{3&0pS{BVV&`xlbbB`SS}L+-ZQK)HW-`w!|GH5N>i5r zSVSLP%%O*#KC;*I^Zo|6?&t@*-QtPtnJR)pr|jedt}|}Tl75%I0x-yuUOL}su3uiH a-4IC+YYc-SXxyQ`bxH+(UNBs;b;U365mqW;Fyo7dp;!OPveu}@C zIzkIMa#1FGu_;^LOYm;% zv0bT~qfd8W123}$x}L;fBL*J8BMqvbK_sB8tCcuxq6=U?d0;WoTr@zKP__=ZbaHJn zb;JhYKsiNrIelPHQtgQW>)VfGG$}Licn3u59)YZz1IPbfozlQ7iBdxYDov?0Ocu3{ z+lH-?ySsm#)MM({Y#8{Qlu_-u{LBse&kp zTErc>VD-4v-71!#fYY;uTbJgqOwUdiu1!rg+KzVQ{Q)Pmvf2Ou delta 972 zcmb`F&ubG=5Xa|jn(Xh*BDPH$jjX>^NG&8A00TSPY&9jY-3s?PSS+4no2ST(2a2vZ?i zk75yrs}VQUj^l`1fCIR4)C-hbB3GWyykxfgk~zaXS?GGe3i4Uk8)nEWcK1MQO)Pab z;$@!4Eg$Fw_9|47BlqOJY?D>wx9pSIeK^<;l@2Kh%pjG4f4hM808o)EA4p#}*%9UN zp?t3U|H-L?jM`C0gl%z5UN%0LlRA_Tb&rDR0ybI^M+LbqXU*}P2how6X2C8%ECPMV z(YKX&H>`{CK!jqgGa)r=kiC<`)^YY$hE{j@f;Kg(WvRGHw3JIWxpbqGFsNZBM>-X^ z7{SCMVN=6_+;9_}p>!HCxG~e49^H9MBA?pJpVq+epNc2>*Fq8Q=AUE^3<9n~)mI%Y z-~ZbMv?sZ?(2RdS8^&m>K!eXV_J^UW2G zswBY@<=jGWb!O?p+`?RN@%*`TT+*6Wq~YAGRF(CV`Z@?kte^SJVh(fF>S4Xi|M1uu zV%ZU;o0lKm$*EIH;+R>UwCy0IeqaEA6FvmMuRwcMw?%zfHRYj2`233dYelfWb}3S{JtSMR~hI4WVav>e-A+AkL!o09+l diff --git a/swig/python/modelservicerecord.pyc b/swig/python/modelservicerecord.pyc index fe4c039400eaecdd9be8e8b21bb2bc4976198202..dc4ee48897cedfbf501e3b5edf74539a406e8fc9 100644 GIT binary patch delta 743 zcmZ`$O=}ZT6g_voCrQU-lBPl$AxdGuO+^I3g~4=H6m+DDK`DciM2CE!^DISDx`=-u zyp4PRKm~EHYyX3PLGTCYy)nfIao*fBk8{qw@4mSoDxbrK`E#StuKege$MP}x+vdpo z^G5qBklGj$MlQN8D0R@Y&?lrW-T^b( zD*dlkb#1MEJ+nViP2Y4b-Kz4BjcWp~fQ)=Gv_Vhp=accHWca41gncS=|zyJ!UN<}JBPgJs5_HA;cYvzl+dcI8Tl<{?J)cX$V z7laJxxX@}!yHnbma*E|1>Z0`@k^Tc2JR*Y!GQ!{*e~EK zPfK*82%{483`S*S7Wi&F>G%(JCq5ONzR7(iHqp~Il_za%+8vvF=ek|x=ZHC=%aSF> zCrPS1gG6`IvvDuZ%d=9E#%O8haIE9J9rBt7ho8GTjzmxtC<)961ZGyfs)wAmNhxA~9)Y}V4CU-fie)&B6QgO|uR~8d<&XerQ4~QEJ1&scI*ft_6;vz)?O0i5KV;3w zwE_DQ_Xp&VYcBZ@{a*$81KRhv)kZnjvX>&cGbD%a4Hf@=eKWfC*Ki{LePVn+!sG8l zr1&?IiwtW$lH5oU$uJU=#*(%rZOI=Zmm36w|`n6WA_TdKfps{*s5N?Ss$Tw^T*Jy5^5foOq=!r9z~HWP$# zs5N)u%AhZg^6@mVio$t6p1Qzosl&>wsMj8hbMJI*FiMo&fUn zJ%L0=72dZBZ>(Jhu#vnHS$r$UyHa8s5RPRAKrl(LVco0&Z{F5`V+1sw2JpsH1KyYo z;5tWUm>pO^z<1?^-Vsu_Z+ULJO~K>ZTNFDGdJ~E3bKY&82ZSqkrTvs^8d&XZnx9eJ zfzX+2Kc~41p}0+|Wf|-j^nFS36~xt`#yj^|nL}0)G$!?&^Ac?Vv@O#CaCQClY$?Zu zOA?*@Nm5klGKXoo!!nxwMsS8^6O2auM%b_U>Klj;C9C#7#+-JKv(&Suj_G#0@r{i- lKHbXk8BV0_TZSz67Vf(1S67B&{6pP?hXm9!`Igy^{sqU5e{KK( delta 711 zcmX|9J#Q015PiFQw<3v+ag@Y4KmwEk_XtoBLP&%TQY=u!f(UbW0UO_0_|{SiTP}c# za%&`h0TKnjgN8pr7l|JLZ_ZXuH*danciznIm)7s*6Z5yZ{`2HdFU9IJ)DJ1u9wFne zFamlsG_nYp!6)D&aMV+hd)AG)Zt#!a;g88pwXNtnEg&bkNFWa1)f*Lswtl>Efq`zF zUkiPGylB#|#D_{{uN=2Vc|@rS!dqajaQYe^n6b3N!7GQC8gu>zUSVd0Ng_%wl|kZl z9gmQ3hos_V$}(Uvk1$gh8idlk=m<$KMe}l6>x<&4z$h=>maL(`Z42xWy3&%{ z73dJW+(bH_mfj^2yDV^p(4{P)xnAo)P;eo*)q+~l#RyuVp~g%qjoLQJ6pEw-=|+)C z;civ@;6f-C?N*`U!iC^kp&Ki9=R#BvMDV_sn3?I~J?5Ob@7{OMx$pkLUx!TfN8Gwu z{r1AlAbM-NaRU`pXx8bYr0O(%4JtY`5IhAI74THJszB{82D~Qt1r_F3&^Mr=!Xm;* z;Q@{_tHFW}?NA*&U50Xy0iGcf-Gb^EOhYKflrbhWOcA4tYOiTo%{N;Y;VhPjXeZ@F zb`&~M7>~m4C`?3QG6cC$Dh!+8r6unAUz;N`g5iFH7JI^Hz{`dpH`En{F$u#7dj%sB zhRHrb+98(SXnSyM?TdB+_qhlxpTpagvOij%nLb~g(md^Hu!(N^rK%yrk=g%(XDPZro^ zKGp!JC~{YU=b*w4YHi0`Fdz-lPiq(gQu;31?wplk(E)o3W3+7VHAJIsj-J~q*-0!Z zjC5Y2^W(hgTQuVw>D!cd;q)5pWW~6On4nF1<@7f>dnG2XC5s6`O`&v~l=Zfg(xUC8 zoWL*{B$3nT$sy!`MN_;Co^O5@=O`baV#${6ep-#EENPsZmCcC%v1S0gLa&+b{Yshl_yPVzGGD4Ps)5d$ETycfDO-$}Ds6rqR;wGM8% z7pN}H31G{Xs3#GZIs$cKTJN(1r6Tkvc}LpVpEdYmLGSJm!@N$bsX>R`;32A?7%BQi z`fMMgRJtc2`~@690|(K&;a;L21%4+&I&9Q3TMz k4CXZvRutQ1u?bz=GM^gNOZ+)TdhcT_F+N4#dx!D#KX5|z?*IS* delta 1104 zcmY*XOK1~e5T4oH>^o`NB#lu@D?Zwj-g>N{B56_4AXc!&J~l|JjW*drD;r`dg5YsZ zKCwzc@By~qMG(Cyh~QDE=*^2FQUpB+&TNu)bJ*GW=AZwYneU(9`|s{E)Qz}(B>DZh zkwPr3?Z9=!Uo>lMqonHA0t8QioTtJC1szEgd zehj8{2x8#HV2Ok5>)`1j!92|7p#+f}Bg`=%Fq%0}VM-C-Gohazt6jBCK3j4d^nC8L zLbnyhTVbLVwza}!1ajl;QCI`7BgAI2HfN+H!jo?en~vTAFB5@0n%N4i5Jm|*B_f2; zU{-=oBuXE(otR(S(1vlBZvjBDG&fT$kNd>}GV)zE=ZpSOY*D5(vXwVlcOFtclH1|y-5~=31tyiDG~2FAbiX$`tSnP$+v(NJ+Y&};l^C<<5qkD%|;)3doLF* zNC&>krs9|BXyQ(06ek55{K;7;!ZrGrxMD4ad(Fgjz3nnu^tbI8ok%XbW_=covn_gO z=TAw`DwJ0ulZZAA31xz&%i@Sk^=ZBO08PY&nlATGFWYZyYN$Ip7c0mBeHtxv^w4tZ zAbsmd$3;xQZq%^{$H-3o!IPw>kLx3ne~zwZ2kCygi-}&P*YOP9&V1N&mX9jJ2k2r7 g`(%#7n3!=fvIzxGZt8^z_J`?n=L4MJfR97}0e6qp?EnA( diff --git a/swig/python/setup.py b/swig/python/setup.py deleted file mode 100644 index a609579..0000000 --- a/swig/python/setup.py +++ /dev/null @@ -1,7 +0,0 @@ -from server import Server -from data import DataConfigrationItem - -class OGMSService_DEBUG: - @staticmethod - def CreateServer(ip, port): - return Server(ip, port) \ No newline at end of file diff --git a/swig/python/setup.pyc b/swig/python/setup.pyc deleted file mode 100644 index 3e5a41ffbfc1f1f624cb2882e1d5fae37d513d08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 658 zcmb_ZT}s115S~riD#bzt!7JoR@JSF6X(~mf6%u@~1VTvG8pt2nsUql8J%RV~G#)^| z*@zxMmz{6+V|Ql0nRP!#!?&0BWlG=6g+GItBS40&s30m8Efp!@4iyfSE-hVfm$Ct6 zJ$fbD5Zx|&l=Ug}wh)_tVtEQD9sok!KIpdNd*IWA6ThzR@>QE~URM{aOWwuB^=ux> z<2=>z^n7wN`;q40b^y41OQqe7R~?w delta 70 zcmX>k(j~&q{F#?4nCHz#_HZ`Fyv^}!j~OMH7#J9wfw))(NYpSg)G#n)voREjOs?mU WWn`GVhNGB`4JgCFv{{o=k`Vwz4-PK? -- Gitee From 8a277d90e8ea2f366ab66aaa635f5a68c374c430 Mon Sep 17 00:00:00 2001 From: Franklin_Zhang Date: Sun, 20 May 2018 14:20:03 +0800 Subject: [PATCH 06/17] add CPP timeout in running add Python start a service and test add paging in get model service list add testing all service in server add more wrapping methods in C Signed-off-by: Franklin_Zhang --- src/NxModelServiceInstance.cpp | 12 +-- src/NxModelServiceRecord.cpp | 1 + swig/python/__init__.pyc | Bin 0 -> 667 bytes swig/python/modelserivce.py | 40 +++++++++ swig/python/modelserivce.pyc | Bin 2447 -> 3972 bytes swig/python/modelserviceinstance.py | 22 ++++- swig/python/modelserviceinstance.pyc | Bin 3965 -> 4652 bytes swig/python/server.py | 64 +++++++++++++-- swig/python/server.pyc | Bin 6133 -> 6349 bytes swig/python/test.py | 28 +++---- swig/python/test2.py | 64 ++++++++++++--- swig/python/utils.py | 5 +- swig/python/utils.pyc | Bin 2626 -> 2765 bytes wrap/include/NxServiceAPI_C.h | 54 +++++++++++++ wrap/src/NxServiceAPI_C.cpp | 117 +++++++++++++++++++++++++++ 15 files changed, 370 insertions(+), 37 deletions(-) create mode 100644 swig/python/__init__.pyc diff --git a/src/NxModelServiceInstance.cpp b/src/NxModelServiceInstance.cpp index 79ffc65..8686945 100644 --- a/src/NxModelServiceInstance.cpp +++ b/src/NxModelServiceInstance.cpp @@ -4,6 +4,7 @@ #include "../utils/NxHttp.h" #include "../utils/NxCommon.h" #include "json/json.h" +#include const char* NJGIS::SERVICE::NjModelServiceInstance::getCurrentState() { @@ -147,13 +148,14 @@ int NJGIS::SERVICE::NjModelServiceInstance::refresh() return -1; } -int NJGIS::SERVICE::NjModelServiceInstance::wait4Status( NJGIS::SERVICE::NjModelInstanceStatus status, double timeout /*= 0*/, bool log ) +int NJGIS::SERVICE::NjModelServiceInstance::wait4Status( NJGIS::SERVICE::NjModelInstanceStatus status, double timeout /*= 7200*/, bool log ) { - int steps = (int)timeout; - int step = 0; - while(this->_status != status && step < steps) + time_t time_now; + time(&time_now); + time_t time_end = time_now + timeout; + while(this->_status != status && time_now < time_end) { - step ++; + time(&time_now); NJGIS::SERVICE::NjCommonLibrary::sleep(2); this->refresh(); if(log) diff --git a/src/NxModelServiceRecord.cpp b/src/NxModelServiceRecord.cpp index c3685ee..841f9b7 100644 --- a/src/NxModelServiceRecord.cpp +++ b/src/NxModelServiceRecord.cpp @@ -2,6 +2,7 @@ #include "../utils/NxHttp.h" #include "NxDataFactory.h" #include +#include const char* NJGIS::SERVICE::NjModelServiceRecord::getID() diff --git a/swig/python/__init__.pyc b/swig/python/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d64b0e8389a5c86dec8f1b7758b8a0ba742d002 GIT binary patch literal 667 zcmb_Z%}N6?5T0b)D#bzt#aGyqCqWPq=~jwLE9~OIWg#q^SOfc0HlreVt2bX(@Bwrt zTl4`mWWJe?WM;lhg3rMg$1(N?X8Ml0+7^@EB7B zAzw!ZyTTs1RnuZf9z3`sip)tivlunnWQ(ggxpJd3nOAH^ocv}12W`3xJ{r`omWOF9C}hU`mton$qs2gMP;b6jyd~R)!(GWtb!$Y rIRmli3UdqpW6uAWpN^l1rXP!WY(DY7RQUIwb}v5T>W(Fi#aMm=LPd@& literal 0 HcmV?d00001 diff --git a/swig/python/modelserivce.py b/swig/python/modelserivce.py index 3ff3298..8b4c769 100644 --- a/swig/python/modelserivce.py +++ b/swig/python/modelserivce.py @@ -4,6 +4,7 @@ from utils import HttpHelper from utils import CommonMethod from base import Service from data import DataConfigrationItem +from modelservicerecord import ModelServiceRunningRecord class ModelService(Service): @@ -48,4 +49,43 @@ class ModelService(Service): return 1 return -1 + def start(self): + jsData = HttpHelper.Request_put_sync(self.ip, self.port, '/modelser/' + self.id + '?ac=start') + if CommonMethod.getJsonValue(jsData, 'result') == 'suc': + return 1 + return -1 + def testify(self): + path = "/modelser/testify/" + self.id + jsData = HttpHelper.Request_get_sync(self.ip, self.port, path) + if jsData["status"] == 1: + title = None + testifies = jsData["testifies"] + for index, item in enumerate(testifies): + title = item["title"] + break + if title == None: + return -2 #! Error in read testify title + jsData = HttpHelper.Request_put_sync(self.ip, self.port, "/modelser/testify/" + self.id + "?path=" + title) + if jsData["status"] == 1: + inputs = jsData["dataInputs"][0]['inputs'] + list_data = [] + for index, item in enumerate(inputs): + list_data.append(DataConfigrationItem(item["StateId"], "", item["Event"], item["DataId"])) + recordid = self.invoke(list_data) + if recordid != -1: + jsData = HttpHelper.Request_get_sync(self.ip, self.port, "/modelserrun/json/" + recordid) + msr = None + if jsData["result"] == "suc": + jsMsr = jsData["data"] + msr = ModelServiceRunningRecord(self.ip, self.port, CommonMethod.getJsonValue(jsMsr, "_id"), CommonMethod.getJsonValue(CommonMethod.getJsonValue(jsMsr, "msr_ms"), "_id"), CommonMethod.getJsonValue(jsMsr, "msr_guid"), int(CommonMethod.getJsonValue(jsMsr, "msr_status"))) + msr.wait4Finished() + msr.refresh() + if msr.status == 1: + return 1 + else: + return -5 #Error in running model service + return -4 #! Record can not be found + return -3 #! Error in read testify files + return -1 #! Error in read testify files + diff --git a/swig/python/modelserivce.pyc b/swig/python/modelserivce.pyc index cb9899125bca8be9f1a978b3ac0da84bb3267316..c0ca2d545b4afadedefa62564b9a40a774337431 100644 GIT binary patch delta 1666 zcmZuxOK%%h6h7DEdHIo;w23_pG>AewBtYDNo$sD=zdm$-Vcz(o zT=@JJ-E7n3XW;)Gv~+iGeszgRTD0lVmP>0c329Sk(rrP~q5DK5qEFTeBn35mckjWi zW4^#joIXUD~Xrqq``ZvnI!YNV^PrX&4

YXBe-{zO`REGRyWHz|V89#^5t7Wk1_Zv6#K>)P`*iCx>RDy^EG!1}LJA zpgu6C(O?1C%u`k7s5&xeAV`_iv8WHJ3>xJ)#*G{$7fG7bfTj&iekCnn!}=DBm4-<@ zbzxp;wa=%jm8g${r}0G0B>D%xanP_xRRBS_(+gA8-0rDndM|EIV&oAWJg*C02lyPv zIL;;LdaVwE2#C*F=8gj(aa`0yUg)?>u$i5X`*)FjZ=D@J5t3+NP+te+4f1sN6;cQ@ zPa{E>KC9BFIU1NWfXm`gJxpHR`G7v^LnYD@e90-*P=Y%4M82_h6A=j_+Em4SEhHqy zSvm3`mLioB7g zFLr(bPuydH`VMb0zzUb-G;J7^JQhj}_pf}yxxzChL|Gav1-s{P#*7a3k!E`cEQ_Ry z&%~=r)G1THNb)cz$k^O>&g!f=Foc;yIj5&iO=k1rDtkb7Wa-lj)S2eG6ws?7YiJ%d zVwCYTQjUveC7l88r<_9eM7QtN1Fi_2W)KR=rQH#b(?msTGmQQoBL7mZ#|zsnb?3a| z^pGvpx*8+>(g+sc0JhP#;sk7{mI|**)C|UWtM_)pSm{}pc%{@y{Vb=X7uP#!H?HsJ ze{hu74-H^5l6v`8nl!gk#d*u!^&b38hz+E*>ZQ@2;2ZtLMWajQe_sRMm!E)@ZX5;+ z=mcC2`h?c@b{NZm4-H;p81ls6X-NgAcxD;!MJrOvm!mjJ?}XCl$~pL=u=ys#8HQIG z78%}RIKgldp!gh+*D7_=>uJL85ot)zq8FaaV&hC!cg$;(OFIXz9wJc|^P(awQ4k)Q zDM~2gMR;c5^TbIp4bKAl6^ypg^7w4w+u4WCi?e)Z;|Sm2-f4y_*;mf0$2Z2J>UYW# z?qRp+7F^3OW{;iv3BD99kK&yA?-k=GKhbY}p!G7b(~Yd_&Qw^KQmz6L`ZN9oihMUX delta 318 zcmZpX?-!P4{>;mDs_<=8G6NJa18D~!E>4>$9U#rdkjl!C#>kMu&d|cZ(9FOP8O6bn z!pIP;!7*`K(qw5yWk%)6_KYelLBSf#n=2WwGP1A%HBa_s4wzib>CP6!3gmHZe$Tv* zk&$ikI@VGF37|lbB#_Wx2eHH_8?#Mkl$(5-?G(2(NI(We$WC6sZXgOWDF}!ef>c2S zMCatE>`GE1AigM&&|m?v#6g5Qh|rp>$Pv$|Ik}NTf=PpQvOJ%H0LTSFIv~ObNN6xj zF5vVM3j*om1ma?lC2WkGBAnbBoRjzR=?lmL1%g1K09FH5?>#x0UyzRrD8|DizzBxS E0M=YGdH?_b diff --git a/swig/python/modelserviceinstance.py b/swig/python/modelserviceinstance.py index 1ecfbb3..34b7b21 100644 --- a/swig/python/modelserviceinstance.py +++ b/swig/python/modelserviceinstance.py @@ -52,13 +52,33 @@ class ModelServiceInstance(Service): return False def wait4Status(self, status, timeout = 7200, log = False): - while self.status != status: + time_end = time.time() + timeout + time_now = time.time() + while self.status != status and time_now < time_end: if log: newlogs = self.getNewLogs() for index, item in enumerate(newlogs): print item.type + " - " + item.state + " - " + item.event + " - " + item.message time.sleep(2) self.refresh() + time_now = time.time() + return 1 + + def wait4StateEvent(self, statename, eventname, timeout = 7200, log = False): + time_end = time.time() + timeout + time_now = time.time() + if statename == "": + statename = None + if eventname == "": + eventname = None + while (statename != None or self.state != statename) and (eventname != None or self.event != eventname) and time_now < time_end: + if log: + newlogs = self.getNewLogs() + for index, item in enumerate(newlogs): + print item.type + " - " + item.state + " - " + item.event + " - " + item.message + time.sleep(2) + self.refresh() + time_now = time.time() return 1 def refresh(self): diff --git a/swig/python/modelserviceinstance.pyc b/swig/python/modelserviceinstance.pyc index 15f2b403261a7f61c0631755f30063ab987ed673..2fb05de241286fd5889e55a7c6a6055d5fab80e9 100644 GIT binary patch delta 1063 zcmZ{i&rcIk5XZl>-R}0a-B$cnK|v#;E22muF&LE?q-ug3wkAa4k5qS63beLeg~K*I zNc;obc=S$;7sJtuCSLtB^yooNJefH2TBROLGvCgeH}Acf`RuQuH%IKmcPD+_`tjDD zBC5xiXl~R(kb4Vi)01|97Y|Zy9AyDBo zATm&BncM4D66>!J@irkMEGN)-hbW22#4@zck(WBbkn=4I>qUeKM3%gI`Sv7k8EDyP zr4Xf1G2s*D3gRYFU|+k|writsXN3QhjQ?kLayFu08UQ}yq zUca0h5ZND7z7&5`yW4wt3EDwf8X}9epH7oQX^z~N3es$H@eEtDk2>9SW}M&|CwpdW z$!K{N%LW<~@Og>^Zl76ngGC)QB)I-jCj)I}(e%5M@1n_)oPl6!w)GZ+Ff=vZ;%AbY z8v7<1Uvz@0so9zuW3_v!rO;A{6e^ZLD2T^@U3b31ZTty$sJ-r`miR9<3-xPQ@J*Cl z8PvQd8fVqM_6R$g<$SFgctXz;Cf)&&T_Q(Cj)}M;$5~vNv?d!0<7QY6gKBv-@ODak zROE!nn8-5X$*ypj1#H?}I-A`MRRy3E$hvB1cZ$%i}U=HgGzA)1cAI)|-Oyz5QGeYpXejK^~2 qK`Gy&d`6{|Ex){z?^BK|*LWlGX71dcX>resToAb^ayI^%d;S~hx~=;F delta 400 zcmYL@!Ak-`7{%YWyY4!xyKY9T6_kb05)w%Ssh6U#4%I;qg5)LikfEh+;9;eMMVD>^ zo$5abA|$#69r{x`21Vzf86jeLKi<6gzQ^3Ber62y+cNJuACE?s=#X#F?sOOzK*dBo zf*O;4K&V7fEP3YenO^mC1Ar>DDb&3d=v^WJ8bCleR?)daAlMv*gaOdk&?~@K5NNV( ztGbE<1^p2EIszRH6*Yn@od);MhW@P%cYCLuLAeF^Wbh=Lu-huiH5DaK6F=DJ50L~v zWlM&<`A1ED%MxPniOum()*W|53W}3XQJSP>vdA93MGuMjqwSMcou}=0S|7$^1qx-v z@E)%^E?NA{Nm8EQIP;X|FV2)M-#qXyrIeDZmQYu=>lBNyFf-(dnauKR5f&GCc`P@Z Vmv&7eE0L2}k&q3evLaXFi@#_TM~DCb diff --git a/swig/python/server.py b/swig/python/server.py index 87f5445..0d543b0 100644 --- a/swig/python/server.py +++ b/swig/python/server.py @@ -1,5 +1,7 @@ import requests import json +import time +import os from utils import HttpHelper from utils import CommonMethod @@ -14,8 +16,13 @@ class ServiceAccess(Service): def __init__(self, ip, port): Service.__init__(self, ip, port) - def getModelServicesList(self): - jsData = HttpHelper.Request_get_sync(self.ip, self.port, "/modelser/json/all") + def getModelServicesList(self, start = 0, count = -1): + query = '' + if count < 1: + query = '' + else: + query = ("?start=" + str(start) + "&count=" + str(count)) + jsData = HttpHelper.Request_get_sync(self.ip, self.port, "/modelser/json/all" + query) mslist = [] if CommonMethod.getJsonValue(jsData, "result") == "suc": jsMss = CommonMethod.getJsonValue(jsData, "data") @@ -26,8 +33,11 @@ class ServiceAccess(Service): user = CommonMethod.getJsonValue(item, "ms_user") if user == "": user = { "u_name" : "", "u_email" : "" } - ms = ModelService(self.ip, self.port, CommonMethod.getJsonValue(item, "_id"), CommonMethod.getJsonValue(model, "m_name"), CommonMethod.getJsonValue(model, "m_type"), CommonMethod.getJsonValue(model, "m_url"), CommonMethod.getJsonValue(model, "p_id"), CommonMethod.getJsonValue(model, "m_id"), CommonMethod.getJsonValue(model, "m_register"), CommonMethod.getJsonValue(item, "ms_des"), CommonMethod.getJsonValue(item, "mv_num"), int(CommonMethod.getJsonValue(item, "ms_platform")), CommonMethod.getJsonValue(item, "ms_update"), CommonMethod.getJsonValue(item, "ms_img"), CommonMethod.getJsonValue(user, "u_name"), CommonMethod.getJsonValue(user, "u_email"), int(CommonMethod.getJsonValue(item, "ms_status")), int(CommonMethod.getJsonValue(item, "ms_limited")), int(CommonMethod.getJsonValue(item, "ms_permission"))) - mslist.append(ms) + try: + ms = ModelService(self.ip, self.port, CommonMethod.getJsonValue(item, "_id"), CommonMethod.getJsonValue(model, "m_name"), CommonMethod.getJsonValue(model, "m_type"), CommonMethod.getJsonValue(model, "m_url"), CommonMethod.getJsonValue(model, "p_id"), CommonMethod.getJsonValue(model, "m_id"), CommonMethod.getJsonValue(model, "m_register"), CommonMethod.getJsonValue(item, "ms_des"), CommonMethod.getJsonValue(item, "mv_num"), int(CommonMethod.getJsonValue(item, "ms_platform")), CommonMethod.getJsonValue(item, "ms_update"), CommonMethod.getJsonValue(item, "ms_img"), CommonMethod.getJsonValue(user, "u_name"), CommonMethod.getJsonValue(user, "u_email"), int(CommonMethod.getJsonValue(item, "ms_status")), int(CommonMethod.getJsonValue(item, "ms_limited")), int(CommonMethod.getJsonValue(item, "ms_permission"))) + mslist.append(ms) + except ZeroDivisionError as ex: + print str(ex) return mslist def getModelServiceByID(self, msid): @@ -92,4 +102,48 @@ class Server(Service): def getServiceAccess(self): if self.connect() : return ServiceAccess(self.ip, self.port) - return None \ No newline at end of file + return None + + def testAllServices(self, count = -1): + success = [] + error = [] + count_done = 0 + currdir = os.path.abspath(os.curdir) + try: + if self.connect() : + access = self.getServiceAccess() + if count < 100: + list_ms = access.getModelServicesList() + for index, item in enumerate(list_ms): + print 'Service ID: [' + item.id + '] Name [' + item.name + '] start to test!' + count_done = count_done + 1 + time.sleep(5) + if item.testify() == 1: + print 'Service ID: [' + item.id + '] Name [' + item.name + '] test successfully!' + success.append(item.id) + else: + print 'Service ID: [' + item.id + '] Name [' + item.name + '] test fail!' + error.append(item.id) + else: + index = int(count / 100) + for num in range(0, (index + 1)): + list_ms = access.getModelServicesList(num*100, 100) + for index, item in enumerate(list_ms): + print 'Service ID: [' + item.id + '] Name [' + item.name + '] start to test!' + count_done = count_done + 1 + time.sleep(5) + if item.testify() == 1: + print 'Service ID: [' + item.id + '] Name [' + item.name + '] test successfully!' + success.append(item.id) + else: + print 'Service ID: [' + item.id + '] Name [' + item.name + '] test fail!' + error.append(item.id) + except Exception, e: + print e.message + + logfile = open(currdir + '/TestLog.log', "w") + logfile.write("Finished : " + str(count_done) + "\n") + logfile.write("Success : " + str(success) + "\n") + logfile.write("Error : " + str(error) + "\n") + + logfile.close() \ No newline at end of file diff --git a/swig/python/server.pyc b/swig/python/server.pyc index 4a75f69b76584e21812061b481b7008917f1fe9f..47aa7299202a073ca594e04efad41c6387dee551 100644 GIT binary patch delta 1657 zcmZux&2Jl35TDt#cfB9BH?|WeZHW;y(L!kog0_e%Ewm|ZkW!%+iL`;xn(UIUquO+L z8>M0`w@Q1hke;}Jkl@4_g}(sQV-H+7fW!p}i8EA4a0oMx5ZhHOy`SbcZ@%AnA0K=4 zQbGTtXm2jUyWbSP!%zo+vviVo2tt5mgaF_k2^s_>6Y6kJgJm6poYLnY$SWZafuRHg z0#gYl1O+7&Ah48Rfmrly`A_Y28EIKBq9hRQ&~KF!7wL@CIY%d1)qpd0b;u~G2I~Ov z!Cg&zlFLW|GK4LJdXR%UGfgpaNfBBaWB@I4CsajdI@Gsx=;mMzpqq!Zmxq=C8C@E% zMM+Fp*C4*CrF;4U>$?VQ{(z|o8JQu>t$dH~k=BH60d`GQgKTO+W^s`m=po$v6xuLg zW2-H?Bg`pPuxr!WTmr}aYFf9*LZ;K$jFvc31O24@Ju*>)WrM8^`+9U2NJ{WO=H5_qJd0;=~!CmE6 z6}k>&^lCI(N`Qb%v?96Gfpr_=B@MeSATJ1IL%49Ujc}RX=EWtNGr2ALhiKz2kpXQZ z^75GkXOgrTr?X0)UhUj!r?XPazacN?e{x;APkCjNG?vrGwbSVck>xP%%taef5_Q_= z1-5*s9q zV+AMZxFj>yQO6xPiX&LYvF#PJq{)x08W!ap>pD)!->pN=G{q2HsPLs{*C%FJJWi12 z2wKTPB3@?IEAp;)Uf#Fs_?-O0-f>E-EHilWYv;AuDHa_DZe6^}z!3zGOQ(MM}e4;lkUfOa{Dv)2u|z;Rt2nff>2GI()?03g(MN>7 zIplrUyMhlOd3I>hto; zT16|5%WrGHVN-rS+H&{}eKj+i!p+MoW8PFix`e9%TCXbl>WM?5;zI_mLPQ*HQqVUP luF*-@#z0H=D235|D9${Aw#wmsJ2N};%{TMj+s+?pP5mD5-d+7N z`AmC-vj_kKbnMFnS%66d3*a6Z3Rox&6)Z&>4zN^dIKgsA!v&U88g8&$($K(iOTz=^ zcuEs#<%N;qCLTHoI)ij~7b|GA2?0CI{%wTi^cjrJr`fv?u}*SdjPH@H#jhict$l}jV(wQfYZ+J0|J zh;oEhvZsb3Mr}!~%B7JtIsaZZ`JVq6>-HI|+r$qGCia4xQ7CCpR3PVpqQ+{F)_#>X zNU`x$lJ0)Yju57oZ&_LK$l2>42gG~lj>F5wwrkFt;-_Ltcgj5~<`M(qo4da07-!-U zbYTJ`n55$;n=y{N(1Av|UkfU+02c=tLJVOBUCenGv01$K9`&_wKxJqZU%l~U8=I#H zXcKhB_NZ;17z0 zfk(6p`HG~98uJ`ywTbS~I`)>IhJqMA5b}3xx_A@rzya|yd;(iUi+)^}%N%B67MQ2% zM&FRw(hWRYF6&Wj_?LlGS;&GlOH*GEpCW_JhbeYZPDLbL%1AVcZQ@3B5r@UQXbyGJ zXQYfX%*PKSyOv!ktjsTG%}FWYxzT{8*fF{rI+>}P;WWb#!xe@ZhB=XrO(~wRco_SP z*Mwb{!!GfmF4Hnie{EI)^pv8Qk{3D8CD$3`W6VvT)(zew@d59^bhi8Xp&Y`^QZ9ZWkWB_P@^i z0N~Qwq$iIF#``+J^_LR|G6#+TG8YmHju0{r5}Sh&I5^U)cd%3|e z$-F7S`m?=Joob*Log7>GmGk1pzm}+R#~B7*$NZ$2s^-Mhcr$ru)q>$jJ(S}-Ue#~i zZv70?mKc^9R`fUbKGxpf@jfA5(k=h6y2|nM3~Tzt&pX%1l%$K_7nHIfqwu1 delta 589 zcmZvYyGjF55Qb+qd&_P#YfL0+@P?NqO06Gx0NE6)(T`AI$Gz0{}EW9-r0;<9dsh zwT<#lkOeg|;M{`n5U{HQHWaAuHUR2wg5T95;d*sDlJ;sCHbd8>H}q&uN#|A8!sEk6 zl$7Gt(eXue+6-KSJf%ckRzjtXZg+yitq z=x9*?3#i2bcl!qPk-L3`;p%de>AnQ>C9xlC63@37uK4=4ASD* list = new std::vector; @@ -36,6 +42,14 @@ extern "C" NJGIS_SERVICE void* njgis_service_getModelServiceByIndex( void* list, return (*((std::vector*)list))[index]; } +extern "C" NJGIS_SERVICE void* njgis_service_createDataConfiguration( void* access ) +{ + return ((NJGIS::SERVICE::INjServiceAccess*)access)->createDataConfig(); +} + +////////////////////////////////////////////////////////////////////////// +/* INjModelService */ + extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceOID( void* ms ) { return ((NJGIS::SERVICE::INjModelService*)ms)->getServiceOID(); @@ -50,3 +64,106 @@ extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceType( void* ms { return ((NJGIS::SERVICE::INjModelService*)ms)->getServiceType(); } + +extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceDetailURL( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getServiceDetailURL(); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_getModelServicePID( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getServicePid(); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceMID( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getServiceMid(); +} + +extern "C" NJGIS_SERVICE bool njgis_service_getModelServiceRegistered( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getServiceRegister(); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceVersion( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getServiceVersion(); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceDescription( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getServiceDescription(); +} + +extern "C" NJGIS_SERVICE int njgis_service_getModelServicePlatform( void* ms ) +{ + return (int)((NJGIS::SERVICE::INjModelService*)ms)->getServicePlatform(); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceDeploymentTime( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getDeploymentTime(); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceIMG( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getImage(); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceDeployorName( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getServiceDeployorName(); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_getModelServiceDeployorEmail( void* ms ) +{ + return ((NJGIS::SERVICE::INjModelService*)ms)->getServiceDeployorEmail(); +} + +extern "C" NJGIS_SERVICE int njgis_service_getModelServiceStatus( void* ms ) +{ + return (int)((NJGIS::SERVICE::INjModelService*)ms)->getServiceStatus(); +} + +extern "C" NJGIS_SERVICE int njgis_service_getModelServiceLimitation( void* ms ) +{ + return (int)((NJGIS::SERVICE::INjModelService*)ms)->getServiceLimitation(); +} + +extern "C" NJGIS_SERVICE int njgis_service_getModelServicePermission( void* ms ) +{ + return (int)((NJGIS::SERVICE::INjModelService*)ms)->getServicePermission(); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_serviceInvoke( void* ms, void* config) +{ + std::string record; + if (((NJGIS::SERVICE::INjModelService*)ms)->invoke((NJGIS::SERVICE::INjDataConfiguration*)config, record) > 0) + { + return record.c_str(); + } + return ""; +} + +extern "C" NJGIS_SERVICE void njgis_service_serviceRefresh( void* ms ) +{ + ((NJGIS::SERVICE::INjModelService*)ms)->refresh(); +} + +////////////////////////////////////////////////////////////////////////// +/* INjDataConfiguration */ + +extern "C" NJGIS_SERVICE int njgis_service_getDataConfigurationCount( void* config ) +{ + return ((NJGIS::SERVICE::INjDataConfiguration*)config)->getCount(); +} + +extern "C" NJGIS_SERVICE int njgis_service_insertConfigurationData( void* config, char* state, char* eventname, char* dataid, bool destoryed, bool requested, bool optional ) +{ + return ((NJGIS::SERVICE::INjDataConfiguration*)config)->insertData(state, eventname, dataid, destoryed, requested, optional); +} + +extern "C" NJGIS_SERVICE const char* njgis_service_getConfigurationData( void* config, char* state, char* eventname ) +{ + return ((NJGIS::SERVICE::INjDataConfiguration*)config)->getDataID(state, eventname); +} -- Gitee From 336661eec940d7e3aec6685f6ae0e73b31349e1e Mon Sep 17 00:00:00 2001 From: Franklin_Zhang Date: Mon, 21 May 2018 01:06:06 +0800 Subject: [PATCH 07/17] add timeout in waiting Signed-off-by: Franklin_Zhang --- swig/python/modelserivce.py | 2 +- swig/python/modelserivce.pyc | Bin 3972 -> 4025 bytes swig/python/modelservicerecord.py | 2 +- swig/python/server.py | 2 ++ swig/python/server.pyc | Bin 6349 -> 7785 bytes 5 files changed, 4 insertions(+), 2 deletions(-) diff --git a/swig/python/modelserivce.py b/swig/python/modelserivce.py index 8b4c769..ed8fa5e 100644 --- a/swig/python/modelserivce.py +++ b/swig/python/modelserivce.py @@ -55,7 +55,7 @@ class ModelService(Service): return 1 return -1 - def testify(self): + def testify(self, timeout): path = "/modelser/testify/" + self.id jsData = HttpHelper.Request_get_sync(self.ip, self.port, path) if jsData["status"] == 1: diff --git a/swig/python/modelserivce.pyc b/swig/python/modelserivce.pyc index c0ca2d545b4afadedefa62564b9a40a774337431..2136e4a39f26f75d9c1afd17e83cec03f81074ec 100644 GIT binary patch delta 167 zcmZpX-zm?={F#^Q#hZ<64>_3xnI`{avtZ(7nyk##0HT(1l`*j~O_t?0W@2KR9K>C2 zTEoSVCBV?kz`zJ%2{NQGGh{O{6#ZrdGJ;bi7=rT{7*ZsGOeqMHpCMR7dh$K)w*tTa z|No!)2Soe@5*k92&#=o*{>Y}z5Ps&}wPUaC*p8Dp)Dm?iK8&b{3Iasokd~Hy2o4hSJ#DxP~k;=?#2Nc>I+11X@JTvdi`^@`s|IBZ1 zRg6D#);C4E(ZuXA_`k+q^wZ~+lOsZ);3&9&%en!_(7HlkqMLw|0Ey4gb`nl zf}6oz-~jm0S%8~8M05Y3rLP}8A}UNCs#=0d6Dt)O^x|Zg`HSd{$tSs26rG!VnKu<( znM{fmMb{@klrls&#}5|2p#1pLrPHq}?!|fO$8#(^z~Qox0@4-I3b%xH19u6I3ATw30w<~UmZe$+|+!2TaJVB8e$;ffMHA^I?h0nblioAELYlISFHFk;6X_P(Qd4ud&Kabe>gZYm5@ z7^Y?BgETrRlwA{LQPZp@P`-3|V8TtJEYq;i$-vd4Nn)~6kDc2J;V;MJ;FO$0jnK)> zN^ou3X&)2LWjWkEvnwh+FiXqW*FGUya>>2i^gd@Q&f!z>0_bV_hXS;ULrwdB^7-5koY3Nzolc5#;;cjdK9Z@D9*mSpAS z)YoeT-nZ9$7Vz0dB>TDUg&+G(uX^Re+3Jlb#mH!*dacp**pm2-Y7{rZxElAXu@}Xs zd}7d-QxGj`x1iN%x7qZfsI?me`=_Gpzm8VJ52nECbq;*D-+n3Rw_{0iC(5vV$M5;k zmgiQ_RwF^JXk_uPK20d7%;{nn_Cq#m%WTAQ7W+|b^6z#d-r|h{G;T#&mvh_P4P8I9 zw^+4>uKl`*=UM2XzN?4!n50%>pB2q0@VwjcNYV)_zqN0_AR}u6NI=-=wY@ma+Qq#l zhx+}VF5YGCjkagMcNlml^kdI{=Fn^g{m83HyKNz7pB9Idne|O4_k<%K+&UBJ@Al$N zx8L)06!Q^6v2bhXMr%0mqj<9$*=Ho>%aYPy(cA6n_D+X#vs-@PjXzpBKgvr8^Ewv< zvsI7y;z4wk1t_WCB{KNZo4!v`g)GX^0{=^@LS7*=+VVn;17mmM93q3N~V4BPcdvC!5N#QQSm?-NrO_7Wx7@sHNZ= z$h?CH{yc_aC!~;optIQ^IK%zse3xm?$Lh;c#D~6f(#7rpCWq^HUC-e0BAPvA$QW`C z!9gjI^06BbM(GB!3UU*|EWLuPirj**N;i?&$Q=l$^eQqJxd-8uZXxrL*C1-8+hY$P z0__gso{2sob#V@y0Xw3O)Wc-!|7{!hqaUK08nL)S4K-&Sb6QYW?l;kjy7ZSBt*M8= zV6>^88WE#Jy*FJVA&1j< Date: Mon, 21 May 2018 17:32:24 +0800 Subject: [PATCH 08/17] update time in testing service Signed-off-by: Franklin_Zhang --- swig/python/modelserivce.py | 22 +++++++++++++--------- swig/python/modelserviceinstance.py | 2 ++ swig/python/modelservicerecord.py | 9 +++++++-- swig/python/test2.py | 8 +++++--- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/swig/python/modelserivce.py b/swig/python/modelserivce.py index ed8fa5e..f0c62df 100644 --- a/swig/python/modelserivce.py +++ b/swig/python/modelserivce.py @@ -4,7 +4,7 @@ from utils import HttpHelper from utils import CommonMethod from base import Service from data import DataConfigrationItem -from modelservicerecord import ModelServiceRunningRecord +from modelserviceinstance import ModelServiceInstance class ModelService(Service): @@ -55,7 +55,7 @@ class ModelService(Service): return 1 return -1 - def testify(self, timeout): + def testify(self, timeout = 7200): path = "/modelser/testify/" + self.id jsData = HttpHelper.Request_get_sync(self.ip, self.port, path) if jsData["status"] == 1: @@ -78,13 +78,17 @@ class ModelService(Service): msr = None if jsData["result"] == "suc": jsMsr = jsData["data"] - msr = ModelServiceRunningRecord(self.ip, self.port, CommonMethod.getJsonValue(jsMsr, "_id"), CommonMethod.getJsonValue(CommonMethod.getJsonValue(jsMsr, "msr_ms"), "_id"), CommonMethod.getJsonValue(jsMsr, "msr_guid"), int(CommonMethod.getJsonValue(jsMsr, "msr_status"))) - msr.wait4Finished() - msr.refresh() - if msr.status == 1: - return 1 - else: - return -5 #Error in running model service + jsData = HttpHelper.Request_get_sync(self.ip, self.port, "/modelins/json/" + CommonMethod.getJsonValue(jsMsr, "msr_guid")) + mis = None + if jsData["result"] == "suc" and int(jsData["code"]) == 1 : + jsMis = jsData["data"] + mis = ModelServiceInstance(self.ip, self.port, str(CommonMethod.getJsonValue(jsMis, "state")), str(CommonMethod.getJsonValue(jsMis, "event")), str(CommonMethod.getJsonValue(jsMis, "guid")), str(CommonMethod.getJsonValue(jsMis, "start")), str(CommonMethod.getJsonValue(CommonMethod.getJsonValue(jsMis, "ms"), "_id"))) + if mis.wait4Status(4, timeout) < 0: + return -6 # Timeout + if mis.status == 4: + return 1 + else: + return -5 #Error in running model service return -4 #! Record can not be found return -3 #! Error in read testify files return -1 #! Error in read testify files diff --git a/swig/python/modelserviceinstance.py b/swig/python/modelserviceinstance.py index 34b7b21..ff6ef30 100644 --- a/swig/python/modelserviceinstance.py +++ b/swig/python/modelserviceinstance.py @@ -62,6 +62,8 @@ class ModelServiceInstance(Service): time.sleep(2) self.refresh() time_now = time.time() + if time_now >= time_end : + return -1 return 1 def wait4StateEvent(self, statename, eventname, timeout = 7200, log = False): diff --git a/swig/python/modelservicerecord.py b/swig/python/modelservicerecord.py index 45c1e58..5009ca1 100644 --- a/swig/python/modelservicerecord.py +++ b/swig/python/modelservicerecord.py @@ -19,11 +19,16 @@ class ModelServiceRunningRecord(Service): self.invokeerr = invokeerr self.logs = logs - def wait4Finished(self, timeout): + def wait4Finished(self, timeout = 7200): + currtime = time.time() + endtime = currtime + timeout self.refresh() - while self.status == 0: + while self.status == 0 and currtime < endtime: time.sleep(2) self.refresh() + currtime = time.time() + if endtime >= currtime: + return -1 return 1 def refresh(self): diff --git a/swig/python/test2.py b/swig/python/test2.py index c4aaff0..0a0be43 100644 --- a/swig/python/test2.py +++ b/swig/python/test2.py @@ -48,7 +48,9 @@ # logfile.close() -from __init__ import OGMSService_DEBUG +# from __init__ import OGMSService_DEBUG + +# server = OGMSService_DEBUG.CreateServer('172.21.212.7', 8060) +# server.testAllServices(5214) + -server = OGMSService_DEBUG.CreateServer('172.21.212.7', 8060) -server.testAllServices(5214) \ No newline at end of file -- Gitee From 9bfc3a4fd74e57f0bc9f042e27e768532bfbf43f Mon Sep 17 00:00:00 2001 From: Franklin_Zhang Date: Tue, 22 May 2018 00:27:39 +0800 Subject: [PATCH 09/17] update test logic Signed-off-by: Franklin_Zhang --- swig/python/modelserivce.py | 1 + swig/python/modelserivce.pyc | Bin 4025 -> 4288 bytes swig/python/modelserviceinstance.pyc | Bin 4652 -> 4677 bytes swig/python/modelservicerecord.pyc | Bin 2358 -> 2480 bytes swig/python/server.py | 12 +++++++----- swig/python/server.pyc | Bin 7785 -> 7981 bytes swig/python/test2.py | 9 +++++++++ 7 files changed, 17 insertions(+), 5 deletions(-) diff --git a/swig/python/modelserivce.py b/swig/python/modelserivce.py index f0c62df..4c7717f 100644 --- a/swig/python/modelserivce.py +++ b/swig/python/modelserivce.py @@ -84,6 +84,7 @@ class ModelService(Service): jsMis = jsData["data"] mis = ModelServiceInstance(self.ip, self.port, str(CommonMethod.getJsonValue(jsMis, "state")), str(CommonMethod.getJsonValue(jsMis, "event")), str(CommonMethod.getJsonValue(jsMis, "guid")), str(CommonMethod.getJsonValue(jsMis, "start")), str(CommonMethod.getJsonValue(CommonMethod.getJsonValue(jsMis, "ms"), "_id"))) if mis.wait4Status(4, timeout) < 0: + mis.kill() return -6 # Timeout if mis.status == 4: return 1 diff --git a/swig/python/modelserivce.pyc b/swig/python/modelserivce.pyc index 2136e4a39f26f75d9c1afd17e83cec03f81074ec..09c58153449cd239c99b82a89389a9c43047968c 100644 GIT binary patch delta 1081 zcmZuxOKTHR6#nkbGfu%8cc|BQ<8I$j(0s+5VMww;)TF+3}vSnd$%uE5*>GX z5~y%ohEAH!EslRn7A4RIYCz7H&;m6X>XA?yXiIb>@JWq8NfcBBb&1v+sQ{ncWHnIm zqu9F)9YZ^cuE6cp99AU!82mWeao9wuK+%u3ALB{e2v*Hf$3X7v!dx;zKuJ0#r6sUI zP)Y19h5(5^!2A(_Bx(uhBqOO5Wu?QLg#sIF6uJiIi0v-~POX|~C($8`Pd5`PgL(w5 z*Yb4pYKQ{{Jh|ai*l?CGhQl!&N@hDkEYoMqPK`pRP$N2Ns4;Zqky0JsI#o;eP3MTQ zz+lk-5o~Dt*ssxCI)Sr(jHzC?oN0z6xH^}IvS zJ6?!bcQ-f7W8^3@`*NP+xSVzy)vX;J>{|=NA&Z9Vg|utllIsNr_MM<-WyRefYtM~c x6)|x|nBt|#lQcv|7}5-u>>II%Tp7XBi-m3rr delta 748 zcmZ8f%Wl&^6g?h0wqwU}656JQMa2RsJ6cgBUgA++U4V*gAtY2(N+t?UNvhZm&B9g} z<_FO1`3Y7mkoW~Y0I_Akjzt#%g*#4w2#@CI&V8JFJaa#t{jg@JKOF1Zcf2)DZg~J6 z9`eqspcB0g+Z}&27=(ka-)SF4JgNK_ZPU5<6v8dq@kMb(S-0K*Pj&b~tMvXz*)^Bi zGA@fP+P7t1orx3u(lv*1AXAYta1CCjVSEmWj#NXg;Lfuqb{Vn~GIHtQB}!58X!saU zQdK;+&L692<|;B)Ffe#r#Q{U)Fv)1rxlG%lG6P-eWMaHk@EbG!%>{lFJrhZ}Xk=4W zrLY`$vU3$)UT9K=U#U6Jvyhsolgf-r%HS>zR7AR1vzy1|KdR*4Q6g!n6Jw*$#tLnx zNRy4khUB6PAk;t?+;foH;7iEa{P@qgES-xXnYmJARu^iU52TBf<$BTGLeE7GC@ERB zzg8Xd%bF-;1bh|20N@^(r)Q>%pmj#Pt9-nfsPt%iA*ZJS`f;?^j}volc1Prw4=ep~ zvY(9Na59}v!=Dm<5wsfOvvc>dMmfHm1b;)qIzi$P9PNk6=Dlzb#xFbEzaV4F1T8r* z{wjfZQN1CCC_2NC!psny!om=&!OFnE z;8)BHBo%ZOGMRvM=6@jA9K*@ZC@TfzGB64-@-WIVvH?j+MgvA(MlP@j%jOy`WhO?~ d%?o%6nHa-13-Nm~GA2)s6?n(UKiNm{0RU>t9t8jZ delta 109 zcmX@AvPOl2`7jU2Tcj0YySaqJgQVP*){U}0cj@GE8pk_x&CnM^=>b0H@? zqof#+#lR@Q$ipbd$Oa@O84VbD8Mzn*Hc#bJW@2>SypyMpi7{leHoq4mW8&m8fp?6& JlT!sB008!F7Nr0H diff --git a/swig/python/modelservicerecord.pyc b/swig/python/modelservicerecord.pyc index dc4ee48897cedfbf501e3b5edf74539a406e8fc9..4b714d753019211598315d98edf6c696366d19f6 100644 GIT binary patch delta 398 zcmYjLOHRWu5Pjn~ja#)+RiF_9ReUzta0M20iC~cmA@42foot6OchFggmCJiWR`@br-KS8Si)E#vz5xj7!pf0PgIx_ z=&$I1)5l%RPD^g7F!qrZupS0hV-Wc~{y1faR8~rV_@u;9BwOZ{OK+1rV3Z{nSu(kb z8%$( or5<^HmvcMrD>$rea1?jlr#W$j>C~Ies4mQ!dokP8bMI#H3+w_(W&i*H delta 272 zcmYLB&1%9x7@Tjj(QF_^Bhi-P!CNTx>LnMUry>*@DFyLnwlw~LO>*d=(1X6gzKF%* z`}7GE`U3sdOAj;5%s1ccT8Gecegl8lJWam522o$pMwu{u0CQl&m-m~qA!LMwKruiiFy|?O4T1iPZvmb&2jf`s|3l7%+-~M}{2W$w zR)u~kborY4tSgBQbH37*%eGuX*zJwBhye6p=C zAH~z$GsnsRxX2P7PhLCIwlr{8;JSh3m72Nx*||fr?WqZ%spE!OOqK;5uWxPuaVFIU zBq27FM{cE`#m*ixx&YCFy$B1nNvKEF&+4t_R0&ttnH6r*_z2$$C1;D$h4 zKx{!~5Lxi^aJe^En*}yaxQk1Qogqk0K_HD35ef9!lR0b(Y`sHdYTJ$Z^V>X}c5x}n zz_<6S=v2XpL!!AdM;iyDrG>>MIRrJVs|~2n?G@o_mvm>YwDmPP%wfF^G<#K58g`2@t&{b2-ZVwrYA6mv!dlSyucQShYK??roL4@Ltkta(}`*Ym-A3c~ll2mB^%N nDvA91%>6p~jH$LL=2Ve(2+pPb2tx delta 891 zcmb_aziSjx5dP-vue-h543&B0Pu$L_oc*{c0 z+GhU*s}vRzP(f_1to;K73qdTjv(b6aLk@Cw7W0_*ee-7CH#0A8e!1aUKLY<%lU{mn zLtg;6&9;A`{1Be^pAzod=x%lFlb_)c72BE**c`Ss9e2#gE|3dzT9Aa?Mg}B=L>R}y zh(QO3-$^lUV+0Hrh4vlo=PndM3iKI|NV!N{gL^o5LzxHV=?v?Sjte{#$ScUJkQP)G zNd=L#5ox!|u7hY}Q`wL%BK-{?Ne$9GCmmDQd711B3_t%P2dCs50!c8gz_lse)zQV2 zl3bRbWvn8V`ZW4Km`Zikj?5AsfzjHNU*Ap$bI|~t$f{v1vX}Kmj4=)@=^Rp z`JZTd3#ZGMCb~G?@#*p<_0sFq8vwmQ3_EL}?_+pXP+kM68j>b9HV1@z*&LJu>GSMr zMsyvjj$|IPj%)!uO72`F14McXcgEa|;kZi^+?bj*lv%mI&omY4$&&=OI*syqYt1Fz z-p5Y)wRNR@5Wg$iOV^gWD~x4&wYQ(_?eBE-qIZ3LT;`)ZTzXG;%UkVu)u({wD5iN4 pQzRPHqBC@s@00ks@>%<$d&CbrDAVS8`K!I+raD>w Date: Thu, 30 Aug 2018 20:36:11 +0800 Subject: [PATCH 10/17] fix some bugs Signed-off-by: Franklin_Zhang --- swig/python/modelserivce.py | 3 ++- swig/python/modelserivce.pyc | Bin 4288 -> 4312 bytes swig/python/server.py | 6 ++++-- swig/python/server.pyc | Bin 7981 -> 8028 bytes swig/python/test2.py | 4 ++-- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/swig/python/modelserivce.py b/swig/python/modelserivce.py index 4c7717f..ae45bc0 100644 --- a/swig/python/modelserivce.py +++ b/swig/python/modelserivce.py @@ -8,7 +8,7 @@ from modelserviceinstance import ModelServiceInstance class ModelService(Service): - def __init__(self, ip, port, id, name, type, url, pid, mid, registered, description, version, platform, deploymenttime, img, deployorname, deployoremail, status, limitation, permission): + def __init__(self, ip, port, id, name, type, url, pid, mid, registered, description, xml, version, platform, deploymenttime, img, deployorname, deployoremail, status, limitation, permission): Service.__init__(self, ip, port) self.id = id self.name = name @@ -18,6 +18,7 @@ class ModelService(Service): self.mid = mid self.registered = registered self.description = description + self.xml = xml self.version = version self.platform = platform self.deploymenttime = deploymenttime diff --git a/swig/python/modelserivce.pyc b/swig/python/modelserivce.pyc index 09c58153449cd239c99b82a89389a9c43047968c..448e52e982ceeae9dfffd2f577323e1190086bd2 100644 GIT binary patch delta 496 zcmX@0cteq$`7) z#eswd$bmtUAVL#F=uDR9h-cKET+cCs4PwY-Sx#LQxK%-5t3VD9G6E7BOdu9myAIH` zA&jP*4|9HJVicRan`aV=D z=A{IIf+a`~M8NF~G6ZqK?pB?w%_r*u@{9&QND$*Ad-$ptttYedmkWSxGXaU3fe8P}{sR7!@A3-*qvbunIivh!b%B`x D8Jbce delta 501 zcmY+B&r3o<5XaxXXK($PTWXk;Vn{tTqezqNP|zVlFj{Y2;(->DspX2$rT&2~&B3~N zuMj!~b?(|F=+vcuAfiJA?L0&3Fdt@ScV@n``y73UQtjR2+D7~h7UH?9k^Fdh#yw81E{k#_|}{>CQlXO>oQwhWuwyPAqj(`7ld`a zLn831Kf1;+F^&ksEzP+m(e2%bFFFwlU_2sWpavd97>Fcf?b{>)9s9Z7YXTWZD%Kyx ztx+hF&q)|6dRBQ7sx0puka1I(ha%m5aeS&I08j3-e{ve0JjuYFXX*HlC|M;?NugdV z^9c4#V@j7W8;x?U#5GK&5dGnN7DH7%8Xqy$0E(%k$npVTTO0~*yTf>W&QK`Tc zL}h=bTyKfrt??|2SU|)P3B)2|3Na0rgGVF>5pSDWGUhRxK@?z@ZNP_jNPZS&SrUe2 GcJTwiDp>;n diff --git a/swig/python/server.py b/swig/python/server.py index bb1049e..47187b8 100644 --- a/swig/python/server.py +++ b/swig/python/server.py @@ -34,7 +34,9 @@ class ServiceAccess(Service): if user == "": user = { "u_name" : "", "u_email" : "" } try: - ms = ModelService(self.ip, self.port, CommonMethod.getJsonValue(item, "_id"), CommonMethod.getJsonValue(model, "m_name"), CommonMethod.getJsonValue(model, "m_type"), CommonMethod.getJsonValue(model, "m_url"), CommonMethod.getJsonValue(model, "p_id"), CommonMethod.getJsonValue(model, "m_id"), CommonMethod.getJsonValue(model, "m_register"), CommonMethod.getJsonValue(item, "ms_des"), CommonMethod.getJsonValue(item, "mv_num"), int(CommonMethod.getJsonValue(item, "ms_platform")), CommonMethod.getJsonValue(item, "ms_update"), CommonMethod.getJsonValue(item, "ms_img"), CommonMethod.getJsonValue(user, "u_name"), CommonMethod.getJsonValue(user, "u_email"), int(CommonMethod.getJsonValue(item, "ms_status")), int(CommonMethod.getJsonValue(item, "ms_limited")), int(CommonMethod.getJsonValue(item, "ms_permission"))) + if CommonMethod.getJsonValue(item, "ms_limited") == "": + item['ms_limited'] = u'0' + ms = ModelService(self.ip, self.port, CommonMethod.getJsonValue(item, "_id"), CommonMethod.getJsonValue(model, "m_name"), CommonMethod.getJsonValue(model, "m_type"), CommonMethod.getJsonValue(model, "m_url"), CommonMethod.getJsonValue(model, "p_id"), CommonMethod.getJsonValue(model, "m_id"), CommonMethod.getJsonValue(model, "m_register"), CommonMethod.getJsonValue(item, "ms_des"), CommonMethod.getJsonValue(item, "mv_xml"),CommonMethod.getJsonValue(item, "mv_num"), int(CommonMethod.getJsonValue(item, "ms_platform")), CommonMethod.getJsonValue(item, "ms_update"), CommonMethod.getJsonValue(item, "ms_img"), CommonMethod.getJsonValue(user, "u_name"), CommonMethod.getJsonValue(user, "u_email"), int(CommonMethod.getJsonValue(item, "ms_status")), int(CommonMethod.getJsonValue(item, "ms_limited")), int(CommonMethod.getJsonValue(item, "ms_permission"))) mslist.append(ms) except ZeroDivisionError as ex: print str(ex) @@ -51,7 +53,7 @@ class ServiceAccess(Service): user = CommonMethod.getJsonValue(jsMs, "ms_user") if user == "": user = { "u_name" : "", "u_email" : "" } - ms = ModelService(self.ip, self.port, CommonMethod.getJsonValue(jsMs, "_id"), CommonMethod.getJsonValue(model, "m_name"), CommonMethod.getJsonValue(model, "m_type"), CommonMethod.getJsonValue(model, "m_url"), CommonMethod.getJsonValue(model, "p_id"), CommonMethod.getJsonValue(model, "m_id"), CommonMethod.getJsonValue(model, "m_register"), CommonMethod.getJsonValue(jsMs, "ms_des"), CommonMethod.getJsonValue(jsMs, "mv_num"), int(CommonMethod.getJsonValue(jsMs, "ms_platform")), CommonMethod.getJsonValue(jsMs, "ms_update"), CommonMethod.getJsonValue(jsMs, "ms_img"), CommonMethod.getJsonValue(user, "u_name"), CommonMethod.getJsonValue(user, "u_email"), int(CommonMethod.getJsonValue(jsMs, "ms_status")), int(CommonMethod.getJsonValue(jsMs, "ms_limited")), int(CommonMethod.getJsonValue(jsMs, "ms_permission"))) + ms = ModelService(self.ip, self.port, CommonMethod.getJsonValue(jsMs, "_id"), CommonMethod.getJsonValue(model, "m_name"), CommonMethod.getJsonValue(model, "m_type"), CommonMethod.getJsonValue(model, "m_url"), CommonMethod.getJsonValue(model, "p_id"), CommonMethod.getJsonValue(model, "m_id"), CommonMethod.getJsonValue(model, "m_register"), CommonMethod.getJsonValue(jsMs, "ms_des"), CommonMethod.getJsonValue(jsMs, "ms_xml"), CommonMethod.getJsonValue(jsMs, "mv_num"), int(CommonMethod.getJsonValue(jsMs, "ms_platform")), CommonMethod.getJsonValue(jsMs, "ms_update"), CommonMethod.getJsonValue(jsMs, "ms_img"), CommonMethod.getJsonValue(user, "u_name"), CommonMethod.getJsonValue(user, "u_email"), int(CommonMethod.getJsonValue(jsMs, "ms_status")), int(CommonMethod.getJsonValue(jsMs, "ms_limited")), int(CommonMethod.getJsonValue(jsMs, "ms_permission"))) return ms def getModelServiceRunningRecordByID(self, msrid): diff --git a/swig/python/server.pyc b/swig/python/server.pyc index bdee4b02688456635f8b878b8babfc70b53948d0..9bb27b8a623852413be29ddec4ce3887e086366c 100644 GIT binary patch delta 1615 zcmah}O>7%g5T4n!*FS65alEnP#13glnoU&dKpTXbHl<2J0->lZ&;;7hMqM|tQ@e7! zg-F=+-~&~2sXD4EaqfXj4=4g8#2FzfxNrjwa6mmEP8CH$DlqeGr!GQ5tM}>6-y08zznbIEgIC{eUdcK4@CoNK5&E3(4cO>mS6J%P&1%` zFuU>xeXhHs6>Rwh!HtTai?E@=<`BAjpr({Z$^bOzOVg5XVI%~uC2p-K7JE8G_D`}% zU;73RgxWr=Op6a^eUz*3@u+_K#g{vjX}fjCs;VTmQ<-gfHY{53XK|Y@`1j%fUG-nH z!c0P`diG+WRPgfdWn^)J;>H<$t8|g_#>~!V#wElF8V!yN^6kiHG2d@LsE`%sPs!r5W3)2mHI z!-BdFOl?hv*X%xeDSVu+heu7%;N)DtRQp9ZopgFwc7_@3knDJYvyXlbXQoDFs|$=V z*iyM8-FrTUQnlbZIZ-{^Ru!u!s?H%%O;RO3M|CrWPti?t5RcKP=5Ls!+mXrPed1sW zL<9~C$bpV9>8PAz^f1zkIZ8&~!>OGc(LA2oFGk7aBpGZeqgATx{&k#`>-Ysm1a=R$ zl}^Pjh#^NOVp}+~^JQ!iafG_#<2Xu3<96gETRjQeWS>g>OGyPv3 z2&<10H3{3zrZ{(3y;Y%%-cPLKDY};+>jg<8tmog!m%Z|8Des(9%zbA)fp61&YjXHG zIrpf*tiYncTLR|=E-=`@A+vP7CxLx*yXSYz(}&5TDZJXM^Dx_Aq~%l>u2Ug3u07D` zW@`NSF|7tr^g)BWJg4@4+1Gi35nK&6SU-iefK0jQgRli^zIohbzQ4KAd*_PBL(E|a zDc6LQNZ6DjkeXkptie(xuX(Z7kv;5K55ZOny)JnOYCPTnNb&5>uKWpg6Pnp-rsTJH zu|@L!0P?Q1^THX{hM*n>m(1S77@|sgZR&q2xr$4bv$$0D%QG~;uvG2`pBIOXFl;s` z+n2twhg*oLgi)wPp=g2I1s#XRxlROZnYxupZ}$4QDWOcvtB}%R;&%)HUEpc7_}{!z zV1NS4P>u2f_(`8@sVjH7sTeJ4jz;HjNT*t0(FC>=@cq&ZZ~!YaxD)B3c6b<*w?I5LLL>jIYrF45S)HAB2r6oAipfAhmU2ACP%3^Pz@0Uyu~KZUf0NKy;7#faviKmynzZwf=1QFu>F z<6svPH+AP(n7FdWg&PwMJLATs_DR+$Sxg0DKoWo!D_QM+H!-om;VI>Z8 zIXb@j8rdO5BhkUoVO_J)fp|3myDF3cDk{v{8TvGO2~+f2bl|Sj!9krYAQk+rR zPfpSA4Hgd2lZH+lqD<^hPA+7QbsvxET$DW|a9vQFZkTDz(;f3&e0J}#S-`mg@sLnX zieXD0CzVj!PV#khLAT(j8avPhYhMsUp1zFl;HAC3rWX;r>Fwrz?4?hd?br-keOb26 zK2l1iC5hMe@-4%N({v+odE%rhjAOxSr*;(47puGCugJO4!^AqiO4CV7PD&`bk-|HL zvR_^)6`a>Oq>D>5mm2H7AbXAro)=sbEC^NvF2e?PpQJ~r1g0s}`WRQ~@74{xNbA-r z-lQL`ekH2X6RY2xRixuIsB&FC4W_N$DXfH~U0JgmhMlA$jmmv1jrt2Lar;JKH%brF z7JZiKq0iInb62jq4d6FIMHe^Aje#W+)+7@wc4&kvSGU$+e(R3n$HnFCu;Z_v3 zKcdaH%-tqVzghZj*My1*8%c0m>Pt&-dI)%6N(LsiR_Ae3DlqZE%7N6G_`d{zd`Yu* zE8o;ikpV@yG|vPeE$g23F5>>JvG_AAX z$VN`^G@cJfUH+cs|T)LWq2?R~nAT^OVL z?U_-TH7ODPYsHiVX5~|AjZ%=6Hw6(v5cGYX)m~h`v&Qo`czE)(4UDJ}-A?k3D(?Ep*&7#5-6yMdwcCarR#()G1>C diff --git a/swig/python/test2.py b/swig/python/test2.py index a767d90..6ad1a28 100644 --- a/swig/python/test2.py +++ b/swig/python/test2.py @@ -55,10 +55,10 @@ from __init__ import OGMSService_DEBUG -server = OGMSService_DEBUG.CreateServer("172.21.212.7", 8060) +server = OGMSService_DEBUG.CreateServer("172.21.212.75", 8060) server.connect() if server.connect() : - server.testAllServices(5215, 900) + server.testAllServices(550, 900) else : print 'Can not connect!' -- Gitee From 3ed2bdf773b3e3ef5b8a667f44ae81e1bcfdab12 Mon Sep 17 00:00:00 2001 From: FranklinZhang Date: Thu, 6 Dec 2018 19:26:07 +0800 Subject: [PATCH 11/17] delete pyc files Signed-off-by: FranklinZhang --- swig/python/__init__.pyc | Bin 667 -> 0 bytes swig/python/base.pyc | Bin 1099 -> 0 bytes swig/python/data.pyc | Bin 2356 -> 0 bytes swig/python/modelserivce.pyc | Bin 4312 -> 0 bytes swig/python/modelserviceinstance.pyc | Bin 4677 -> 0 bytes swig/python/modelservicerecord.pyc | Bin 2480 -> 0 bytes swig/python/runninglog.pyc | Bin 1931 -> 0 bytes swig/python/server.pyc | Bin 8028 -> 0 bytes swig/python/utils.pyc | Bin 2765 -> 0 bytes 9 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 swig/python/__init__.pyc delete mode 100644 swig/python/base.pyc delete mode 100644 swig/python/data.pyc delete mode 100644 swig/python/modelserivce.pyc delete mode 100644 swig/python/modelserviceinstance.pyc delete mode 100644 swig/python/modelservicerecord.pyc delete mode 100644 swig/python/runninglog.pyc delete mode 100644 swig/python/server.pyc delete mode 100644 swig/python/utils.pyc diff --git a/swig/python/__init__.pyc b/swig/python/__init__.pyc deleted file mode 100644 index 7d64b0e8389a5c86dec8f1b7758b8a0ba742d002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 667 zcmb_Z%}N6?5T0b)D#bzt#aGyqCqWPq=~jwLE9~OIWg#q^SOfc0HlreVt2bX(@Bwrt zTl4`mWWJe?WM;lhg3rMg$1(N?X8Ml0+7^@EB7B zAzw!ZyTTs1RnuZf9z3`sip)tivlunnWQ(ggxpJd3nOAH^ocv}12W`3xJ{r`omWOF9C}hU`mton$qs2gMP;b6jyd~R)!(GWtb!$Y rIRmli3UdqpW6uAWpN^l1rXP!WY(DY7RQUIwb}v5T>W(Fi#aMm=LPd@& diff --git a/swig/python/base.pyc b/swig/python/base.pyc deleted file mode 100644 index 0f70afc63be3fd24c55b70f12f175a1d0ebb8a9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1099 zcmb_b!EV$*4D}@0!WIym*aH_N4n#s?k+`i8LTv>Vg&-wxV71aHB*Qk4O+v;Cs#H$P zKk!rh2Oq!(z_YWZcS;n$@k~6npY4RduI+yR`D0$t_6e~*f%vf&sE|6h7r3xh`$4HB;FAW zZpEchB_xEClZetRmb?l9kpQv}@izgdhE9nrlt2~rlxZeOES4-#bsS;o+Md;y?!2qt zr}8xwuQ6l*{{WhsEuK}p-pZK-RZkekl3Sx=9oq#4^IcxPV zuy)m!>l)is4AQZ{b-;Nps{PZzrDr4M<^S6;<7gZvgJT&9EytRx+G{b@`hSE~mX8Kr Lk0k}2iyOfo)N0rz diff --git a/swig/python/data.pyc b/swig/python/data.pyc deleted file mode 100644 index a8fc10c4d3621b05ec5da86bd92ea06c8426c370..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2356 zcmb_dO>-MX5bfEOWGN(6_$WKB;wuRs;u2FFI8YQt*$yND>o6jzLZw2r(T?R+R$66e zWH2R8;_q_e2f%whitKZYwA0(&JKE`f-TjpQbL+<0%fAO>*?dymzr*qcM2^cyDKdz9 zBBha8B7;N>pQUQ2GDxG{kg_4OrVN^}o8p>sY9w#TUm|OfUj{A7cO>sf-rl-k8|im% z;I!gje0p62HPC((!s3xD7p{)JoA4b~vspDiapA1Wqjv}1zN^oRu?r38$63g>+3;P5 zSpGhQLmmi6cs4S?xl~fg6IB{w`(36#?m%$ybw^nK1R{t`jjTjgJF;ra8Y!>T9woBE zB{E87g$qhUR=A)vWrYh$OIEm`AYa6*q4&CNyw@gtIknNKm=|F*3iK3tU@ReeM?_(X;O z0-F1J_(Ktns@x5GPfl8BvKEq_#5hPs{fgU9q9v) zKJQ)T-P2$WCaz+X2UB0o4+0<5&M(WL`1<8oG2jk_1Pl}+YT-77buX9Bhtb4^k-wOa zEt}BZqELLbS?R-uCph4lR)vqg&q^Ol_H(^-T>@a=fY1o0{ul>d6LchsKJgEKFMN0l zs%IQx?wLFIHt-$uP%d_oBL4}LtH`f)!1vIYD8L@D2G9n0$3f_Mmh=^V1#|7P(3--s zF3aM1U`kMH7wW>DI~`nLahQ4c)c&L(UCEvAJ1t7L$imrmvu7keJ9qoM(-3plbP4@t zn&#QeVVcm15zNR&Fu`WZPdM`xEio5uE{~ybU?R?h>V#A+lzJZ2V$PhN&9)rVQq>nO z{-}=Q1B>BS3!;#fk@wg+_9KeB6!$3ZQ+!OpPPLyxXkApiUU7)?2Ur_sy5yyf*)kJ@ zQyjm7g82Xt`>4sfNu~nw8^%%8`b6z<1VHs3QDb91Bx*W6 zY>my9V<1*nKrGJ5hYW#1Kd-7Xx_0SGA%OEW;RxjClkA0iy3i2Nk)Od6=O_8nC~?~N z;j#qHvW<0Q0?CCvP>hib{(bEOI4+~PMunI$Pt+h<=Iu^=Ya1?m2STA+hNAQqmRRLn lMF=FLf1j4%Sia}~2uOSNn@AYn@-R;dxtZKH_$Ir%{{d4;%l!ZV diff --git a/swig/python/modelserivce.pyc b/swig/python/modelserivce.pyc deleted file mode 100644 index 448e52e982ceeae9dfffd2f577323e1190086bd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4312 zcmb_fOLH7a5zg*;XlAUp>>bP6wT&Xy47+9(fME%hPXK{d8xzBHNv=_M z�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 diff --git a/swig/python/runninglog.pyc b/swig/python/runninglog.pyc deleted file mode 100644 index aab6d5bd3c15a72df5d92783a90a5bd53ba753a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1931 zcmb_dO>Y}V4CU-fie)&B6QgO|uR~8d<&XerQ4~QEJ1&scI*ft_6;vz)?O0i5KV;3w zwE_DQ_Xp&VYcBZ@{a*$81KRhv)kZnjvX>&cGbD%a4Hf@=eKWfC*Ki{LePVn+!sG8l zr1&?IiwtW$lH5oU$uJU=#*(%rZOI=Zmm36w|`n6WA_TdKfps{*s5N?Ss$Tw^T*Jy5^5foOq=!r9z~HWP$# zs5N)u%AhZg^6@mVio$t6p1Qzosl&>wsMj8hbMJI*FiMo&fUn zJ%L0=72dZBZ>(Jhu#vnHS$r$UyHa8s5RPRAKrl(LVco0&Z{F5`V+1sw2JpsH1KyYo z;5tWUm>pO^z<1?^-Vsu_Z+ULJO~K>ZTNFDGdJ~E3bKY&82ZSqkrTvs^8d&XZnx9eJ zfzX+2Kc~41p}0+|Wf|-j^nFS36~xt`#yj^|nL}0)G$!?&^Ac?Vv@O#CaCQClY$?Zu zOA?*@Nm5klGKXoo!!nxwMsS8^6O2auM%b_U>Klj;C9C#7#+-JKv(&Suj_G#0@r{i- lKHbXk8BV0_TZSz67Vf(1S67B&{6pP?hXm9!`Igy^{sqU5e{KK( diff --git a/swig/python/server.pyc b/swig/python/server.pyc deleted file mode 100644 index 9bb27b8a623852413be29ddec4ce3887e086366c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8028 zcmc&(TW=f36+TN!6senavlUrROeamswn-GEsnI$~-PlSb=OVPLBu;6m3`4HyrFWO~ z&Qg&I=}7_FBFIxw^cVCYKcwhG(O=M)A`fkWJ{CxUyrkcEW=SrU1VOC;70vOSvoo_Z z=klF1hxvccOuqB!r8^Bt|MK|%C-|Dbp=siuBY{YD(08Qj^!Yid=KB4-RP)-;NiZhi zxKzi*;rzVP1*sM+Jto0~ghi$$p<1QB0sM#NOQW+of&W!d9dxuEDq^^j=!yngKjd3 zW;02;n_kfMV#}Kb?`9_qJJB0na<|j8+zD{Ey?Ebmc*9|Dbedi;!d=0zEZ6Ntksq~O zuhEIqm6lEoxfPkD9`%xtiqZY5rr%-})#;+Gl?&zKQ~ z-oR7yHX0AARP{kR)E)Y0^YQ^y3H6OpKGiX4j%#OJng#6?q&cCT327F!Q

&J0)?q zD->IUmcuW1d=p=@j3yCjJ8~p)gf=H9c~#oBo@T3(!w8p6Qbbd$`H`R0Y89@Ma2ewT zdkLTWU8TF7IH`aXZOpUidDnI}{NyGCzq9pfR?^$+ukD!k{nk$R5L%0N43y=?Pj?U9 z5~j`JYq+vFK3g>cJpv_3t?3bdk0B7!ah{upsP2ixt0^aXgp$JnakLXhmYZX;ObVw2 zg(-<6?HteE#&onQ*Q2~FLkh=Z(h@lymtn_= zA5KS}EXnbd96>M81=e@Oxeb#VOQz)Bq{JWQoMRv$4GM2_WMeaOQ`AwY@+Btk@ zSW6DO9t6*BFAl6@b09rFWQTAP)?%;anOX*xlAck_PtdQmf(2dnDEoppcT z=i6V7<4#;5{J0c=N=VhIJyoXmu$lN!7it^Eg7km^gr(2h<_%-C=SNNNK*b8Rgvzoi zrKDA#M8MD}#Civ3M%H8r%Rv%Z7&fnCUyImJKjKyZN7z;9su^=tR4k8FR z3bTYP`*v`$NDDHHw0h#g?*IhXe6USPvq#HA6rjO{L0bywM3V)HPXK288z+{j!Ag?vWJ3DUZBycx(MBunmPE14pC-PNZ)5xm>rdN0cTQsq1}=&eynJ6FE&k zS6WG3?hopOW3pmhZNwo8(uRw`tj5)-m4qTvrp<^lk2q4@kJdC8rU??P>7r~PLhK;yLgP>h zG)o-)L|FxE1i;QLDozj_+Q?e_+9fh%nSBM1FiW(U(<2pEv&`Yjim?`2G2jH5^AKbR z8(EO?BXinN)H@r+S(d6CUVW9M$79k8NSYR^+gU;f$NOZ_(A)rFa)UjJ4o*oLSmaZ8s&C7 zCb3~cRZLkbp9#6H9CYeUJ2XMoma&0h(8zNV&Om(PM!NOnu8n>_ZBQ7E2$0fnzyK`&x3_g9<&nf#`<4go`n#u)359DrEq~fzu!w@;d;CAAv~iLaQe6qXLh#cmb4v&z~UQ z2FqsjLsk>@Ev*-AX_BWkB9(x8@-0Jpe%%YaT1_ib?hi5EeUZ&N8#)cboKpVW#nNo4h|g51sN!TL(Tn+B{Uhw$z}GNLd0!|Y zegF=z8alHjMAQ<;SQVtwHAHYewQ>{R|D`IZahk|%e8K_loJ47yV8iY=M zxmDffW9SeLw2B;GCb*8ELr%7vG)Yd{(xa+-H9Aq`H4>LH9`09zybe{vJoEOoEP;4U zJ)rGj>e$d1+|QBs6`pz4VDt+i5i zOE&gzY{DbjQwr;-gYn5UBLTLM7DWH4ck&6;RdL7t(q*vf#wPHiJ(Io!lbz^$Uojdl z#^|xp(a0MT)HTx-WC}S6sI<5{%?bBga{IoQOU|WdKTjEzMu=D_a$=82OxJfm z)AF8*1?4?>#}dAHLIM4iK>_tsO#h|?RLZev@qZW4ubtcXYba!D*1r9rN z?M=Mr^-k;QpwrT^?;D2OSMd9Yx$8B{*UE;tGieBm+xEp|a_d?~1X0mTE#VD`C()P5 zqGDA2J)?a_s75bt`mqa`6BnK=HVP4-G*M2gvRd%v8cajaNgQ;nxuA+0r0deI3u8IPv%tgfn2Hp`^A;=9jcP51j;m^xt#VW=R7j$>GZSWtRk~MkKAb$dBZ9)>q>6UxrjpO z7oR+tD&MjgrJ~?|;1fGj~mkq^kRr)LRhG)^8&oerkS7(!rbyVb9znTUa(2qk9iucpryKlo<=^o3vc}w&xi*I diff --git a/swig/python/utils.pyc b/swig/python/utils.pyc deleted file mode 100644 index e6b70a716365548138f72cf18919f8aa8032969c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2765 zcmb_eZEqVz5S~51#DugdErC{uLMTC&puC7LP$2|$O4_1Y)!C&GjI7JuCOPMP=iaVM zA~|0u5`TsN#}9z#nR8x>`hg}m+40Qo-OTJWZ?64yVe!v_{2a^tQ^WT+SZ)&}!M~AA z1j3v*vT2U^KsJLTz9ySBNgy^Qsmbpm&qRLOtV@Fb1xXsmTMer0wOdf1{*6!9FM_@6 z{p7CACbm5GB*6A_he?|5drTk6I;er^T)B7x-in_X44WwtR(uwMt6s512 z$nPo>!x42HHs`Lm^~gtRW>m2T3Tzuhl(^3*-x_SBz5|B_-TM#lmGx}-G>vU<{riFY zHQgCZ4*YJB52ilN+{X|u;jOT`=MZ-sx`R9>H10Bp1T}NnTrx}My18mvX4z;i@ccLz z3J3@N|1}qo1@o9MXv{~5c@r_OAH|%;yCDHM33y0ALt?M^hI}SufI_+(GJivcA!PJJ zhBRc@+j_c8QK5K^9Pb`pAz2}L1LWL5ze!D}fkr+>W5t`69IcQ`ZVQH+=HSa^Yi(bo15J`c{n!h3F5PM6SRTA^|S zwjDD~f~tU4jJoVw*cuM=Xl#c=ZR5k?xJafMMY`@#bLXj{~j_x$g@)G{)YQIyA$3^}??Z^zr3ryy z!Gyq@!^4Mzob-vX0JIzyV z?KM1{*{ZWUj1I4z-R9G=EhBHW*1n6f`Hbk7Q>znHRWq{oX_QT?0Rq)kZKio*_qFS% z-i}Y=d$!PO<==A~kM6C11ZU@Md7g#EcHtabUiM0K_Zw-Rg^iw5C5p z5CJ^5*Oc;0G7zuz`13^3rOGbi3rGo7c!Pvshily9u~q=aK7G y-ZVPXGQ*FKYCzF%MP&Y4!)a-%o>Q;lAvv2zs{5;|!+gzzS5TG!2>yaAYySXrB^LSs -- Gitee From cd89b998c03e471dd52619f4bbf8cfe86c89f4ec Mon Sep 17 00:00:00 2001 From: FranklinZhang Date: Mon, 24 Dec 2018 16:07:18 +0800 Subject: [PATCH 12/17] ignore test file Signed-off-by: FranklinZhang --- .gitignore | 4 ++- swig/python/test.py | 22 --------------- swig/python/test2.py | 65 -------------------------------------------- 3 files changed, 3 insertions(+), 88 deletions(-) delete mode 100644 swig/python/test.py delete mode 100644 swig/python/test2.py diff --git a/.gitignore b/.gitignore index 2b1cad7..470ea02 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ NJModelServiceSDK -.vscode \ No newline at end of file +.vscode +/swig/python/test2.py +/swig/python/test.py diff --git a/swig/python/test.py b/swig/python/test.py deleted file mode 100644 index 8d9d7b4..0000000 --- a/swig/python/test.py +++ /dev/null @@ -1,22 +0,0 @@ -from __init__ import OGMSService_DEBUG - - -server = OGMSService_DEBUG.CreateServer("172.21.212.7", 8060) -server.connect() -if server.connect() : - access = server.getServiceAccess() - list_ms = access.getModelServicesList() - for index, item in enumerate(list_ms): - print "ID : " + item.id + " - Name : " + item.name + " - Type : " + item.type - # dataid = access.uploadDataByFile("aread8_input", "E:\\DemoData\\GeoModeling\\udx_zip_d8\\d8.tif") - # print "AreaD8 - Input Data ID : " + dataid - # swat = access.getModelServiceByID("5acf6bde18f9e109f0aafa38") - # recordid = swat.invoke([access.createDataConfigurationItem("RUNSTATE", "D8FlowDirection", dataid)]) - # record = access.getModelServiceRunningRecordByID(recordid) - # instance = access.getModelServiceInstanceByGUID(record.guid) - # instance.wait4Status(4, 7200, True) - # print "AreaD8 has been finished" - # record.refresh() - # for index,item in enumerate(record.outputs): - # dat = access.getDataByID(item.dataid) - # dat.save("E:\\DemoData\\GeoModeling\\udx_zip_d8\\AreaD8_" + item.eventname + ".zip") \ No newline at end of file diff --git a/swig/python/test2.py b/swig/python/test2.py deleted file mode 100644 index 6ad1a28..0000000 --- a/swig/python/test2.py +++ /dev/null @@ -1,65 +0,0 @@ -# import sys -# import urllib -# import json - -# reload(sys) -# sys.setdefaultencoding('utf-8') -# type = sys.getfilesystemencoding() -# r = urllib.urlopen("http://172.21.212.7:8060/modelser/json/5affd6beffc23108c4dc738c") -# a = r.read().decode('utf-8').encode(type) -# print a -# jsData = json.loads(a.decode('raw_unicode_escape')) - -# js = json.loads('{"insun": "泰囧 / 人在囧途2 / Lost in Thailand "}') - -# print js - - -# import time -# from __init__ import OGMSService_DEBUG - -# success = [] -# error = [] -# count = 0 -# server = OGMSService_DEBUG.CreateServer('172.21.212.7', 8060) -# server.connect() -# try: -# if server.connect() : -# access = server.getServiceAccess() -# for num in range(0, 52): -# list_ms = access.getModelServicesList(num*100, 100) -# for index, item in enumerate(list_ms): -# print 'Service ID: [' + item.id + '] Name [' + item.name + '] start to test!' -# count = count + 1 -# time.sleep(5) -# if item.testify() == 1: -# print 'Service ID: [' + item.id + '] Name [' + item.name + '] test successfully!' -# success.append(item.id) -# else: -# print 'Service ID: [' + item.id + '] Name [' + item.name + '] test fail!' -# error.append(item.id) -# except Exception, e: -# print e.message - -# logfile = open("E:\\DemoData\\GeoModeling\\YTXTestResult.json", "w") -# logfile.write("Count : " + str(count) + "\n") -# logfile.write("Success : " + str(success) + "\n") -# logfile.write("error : " + str(error) + "\n") - -# logfile.close() - -# from __init__ import OGMSService_DEBUG - -# server = OGMSService_DEBUG.CreateServer('172.21.212.7', 8060) -# server.testAllServices(5214) - -from __init__ import OGMSService_DEBUG - -server = OGMSService_DEBUG.CreateServer("172.21.212.75", 8060) -server.connect() -if server.connect() : - server.testAllServices(550, 900) -else : - print 'Can not connect!' - - -- Gitee From bba1ac97641312a045c5aab8678f56675715d8b8 Mon Sep 17 00:00:00 2001 From: FranklinZhang Date: Tue, 19 Feb 2019 17:48:29 +0800 Subject: [PATCH 13/17] add task server add data exchange server Signed-off-by: FranklinZhang --- swig/python/__init__.py | 6 +++- swig/python/geodataexserver.py | 55 ++++++++++++++++++++++++++++++++++ swig/python/taskserver.py | 41 +++++++++++++++++++++++++ swig/python/utils.py | 41 ++++++++++++++++++++++++- 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 swig/python/geodataexserver.py create mode 100644 swig/python/taskserver.py diff --git a/swig/python/__init__.py b/swig/python/__init__.py index a609579..6a85600 100644 --- a/swig/python/__init__.py +++ b/swig/python/__init__.py @@ -4,4 +4,8 @@ from data import DataConfigrationItem class OGMSService_DEBUG: @staticmethod def CreateServer(ip, port): - return Server(ip, port) \ No newline at end of file + return Server(ip, port) + + @staticmethod + def CreateTaskServer(ip, port): + pass \ No newline at end of file diff --git a/swig/python/geodataexserver.py b/swig/python/geodataexserver.py new file mode 100644 index 0000000..776672b --- /dev/null +++ b/swig/python/geodataexserver.py @@ -0,0 +1,55 @@ +# Author : Fengyuan(Franklin) Zhang +# Date : 2019/1/4 +# Description : Using of data exchange server + +import urllib +import requests +import json + +from base import Service +from utils import CommonMethod +from utils import HttpHelper + + +class ExData(Service): + def __init__(self, ip, port, id, pwd): + Service.__init__(self, ip, port) + self.id = id + self.pwd = pwd + + def download(self, path): + dataid = self.id + if self.pwd == '': + pwd_c = '' + else: + pwd_c = CommonMethod.encryption(self.pwd) + filepath = path + urllib.urlretrieve("http://" + self.ip + ":" + self.port + "/data/" + dataid + "?pwd=" + pwd_c, filepath) + +class GeoDataExServer(Service): + def __init__(self, ip, port): + Service.__init__(self, ip, port) + + def upload(self, datapath, tag="", security = False): + md5 = CommonMethod.getFileMd5(datapath) + path = "/data?md5=" + md5 + jsData = HttpHelper.Request_get_sync(self.ip, self.port, path) + data = None + if jsData['result'] == 'suc': + if(jsData['data'] <> ''): + pwd = jsData['data']['d_pwd'] + pwd = CommonMethod.decryption(CommonMethod.decryption(pwd)) + data = ExData(self.ip, self.port, str(jsData['data']['id']), pwd) + else: + data = {"datatag" : tag, "pwd" : "true"} + files = { + "datafile" : open(datapath, "rb") + } + r = requests.post("http://" + self.ip + ":" + str(self.port) + "/data", data, files=files) + jsData = json.loads(r.text) + if jsData['result'] == 'suc': + pwd = jsData['data']['d_pwd'] + pwd = CommonMethod.decryption(CommonMethod.decryption(pwd)) + data = ExData(self.ip, self.port, str(jsData['data']['id']), pwd) + return data + diff --git a/swig/python/taskserver.py b/swig/python/taskserver.py new file mode 100644 index 0000000..8771fd9 --- /dev/null +++ b/swig/python/taskserver.py @@ -0,0 +1,41 @@ +# Author : Fengyuan(Franklin) Zhang +# Date : 2019/1/23 +# Description : Using of task server + +import json +import time +import os +import requests + +from base import Service +from geodataexserver import ExData +from geodataexserver import GeoDataExServer +from utils import HttpHelper + +class Task: + def __init__(self, pid, dxserver): + self.pid = pid + self.dxserver = dxserver + self.data = [] + + def configInputData(self, state, event, data): + pass + +class GeoTaskServer(Service): + def __init__(self, ip, port): + Service.__init__(self, ip, port) + + def subscribeTask(self, task): + pass + + def createTask(self, pid, dxserver = None): + resJson = HttpHelper.Request_get_sync(self.ip, self.port, '/server?pid=' + pid) + if resJson['result'] <> 'suc' or resJson['code'] <> 1: + return None + if dxserver == None: + resJson = HttpHelper.Request_get_sync(self.ip, self.port, '/dxserver?ac=recommend') + if resJson['result'] == 'suc' and len(resJson['data']) > 0: + dxserver = GeoDataExServer(resJson['ds_ip'], resJson['ds_port']) + else: + return None + return Task(pid, dxserver) \ No newline at end of file diff --git a/swig/python/utils.py b/swig/python/utils.py index 6ca0526..fe0e359 100644 --- a/swig/python/utils.py +++ b/swig/python/utils.py @@ -2,6 +2,13 @@ import urllib import httplib import json import requests +import hashlib +import os +import random +import string +import base64 + +charstr = 'QWERTYUIOPASDFGHJKLZXCVBNMzyxwvutsrqponmlkjihgfedcba!@#$%^&*()' class HttpHelper: @staticmethod @@ -62,4 +69,36 @@ class CommonMethod: if key in jsobject: return jsobject[key] else: - return "" \ No newline at end of file + return "" + + @staticmethod + def getFileMd5(filename): + if not os.path.isfile(filename): + return + myhash = hashlib.md5() + f = open(filename,'rb') + while True: + b = f.read(8096) + if not b : + break + myhash.update(b) + f.close() + return myhash.hexdigest() + + @staticmethod + def encryption(buffer): + a = str(buffer) + a = a.encode('hex') + a = (base64.encodestring(a))[0:-1] + a = ''.join(random.sample(charstr, 5)) + a + ''.join(random.sample(charstr, 5)) + a = (base64.encodestring(a))[0:-1] + return a + + @staticmethod + def decryption(buffer): + b = base64.decodestring(str(buffer)) + b = b[5:] + b = b[0:-5] + b = base64.decodestring(b) + b = b.decode('hex') + return b -- Gitee From 87ea9badc9d405b0a1ab16706ea9f1b362a53ada Mon Sep 17 00:00:00 2001 From: FranklinZhang Date: Tue, 19 Feb 2019 17:49:19 +0800 Subject: [PATCH 14/17] delete pyc file Signed-off-by: FranklinZhang --- swig/python/requests/__init__.pyc | Bin 4052 -> 0 bytes swig/python/requests/__version__.pyc | Bin 618 -> 0 bytes swig/python/requests/_internal_utils.pyc | Bin 1628 -> 0 bytes swig/python/requests/adapters.pyc | Bin 19558 -> 0 bytes swig/python/requests/api.pyc | Bin 7339 -> 0 bytes swig/python/requests/auth.pyc | Bin 10637 -> 0 bytes swig/python/requests/certs.pyc | Bin 637 -> 0 bytes swig/python/requests/compat.pyc | Bin 1907 -> 0 bytes swig/python/requests/cookies.pyc | Bin 24047 -> 0 bytes swig/python/requests/exceptions.pyc | Bin 7650 -> 0 bytes swig/python/requests/help.pyc | Bin 3461 -> 0 bytes swig/python/requests/hooks.pyc | Bin 1359 -> 0 bytes swig/python/requests/models.pyc | Bin 30772 -> 0 bytes swig/python/requests/packages.pyc | Bin 502 -> 0 bytes swig/python/requests/sessions.pyc | Bin 22678 -> 0 bytes swig/python/requests/status_codes.pyc | Bin 4664 -> 0 bytes swig/python/requests/structures.pyc | Bin 6008 -> 0 bytes swig/python/requests/utils.pyc | Bin 26811 -> 0 bytes 18 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 swig/python/requests/__init__.pyc delete mode 100644 swig/python/requests/__version__.pyc delete mode 100644 swig/python/requests/_internal_utils.pyc delete mode 100644 swig/python/requests/adapters.pyc delete mode 100644 swig/python/requests/api.pyc delete mode 100644 swig/python/requests/auth.pyc delete mode 100644 swig/python/requests/certs.pyc delete mode 100644 swig/python/requests/compat.pyc delete mode 100644 swig/python/requests/cookies.pyc delete mode 100644 swig/python/requests/exceptions.pyc delete mode 100644 swig/python/requests/help.pyc delete mode 100644 swig/python/requests/hooks.pyc delete mode 100644 swig/python/requests/models.pyc delete mode 100644 swig/python/requests/packages.pyc delete mode 100644 swig/python/requests/sessions.pyc delete mode 100644 swig/python/requests/status_codes.pyc delete mode 100644 swig/python/requests/structures.pyc delete mode 100644 swig/python/requests/utils.pyc diff --git a/swig/python/requests/__init__.pyc b/swig/python/requests/__init__.pyc deleted file mode 100644 index bb244b93e47cb0d144e43c54833e1377de2307ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4052 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 T>KnL!o%F!3<}~>*y>aU=EKS7O diff --git a/swig/python/requests/adapters.pyc b/swig/python/requests/adapters.pyc deleted file mode 100644 index 8cf4f2a2e0a631b5d9c241c16b30949b35d8693a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19558 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 Qt>k}w`wd#Rzq+;hUp`Z)i2wiq diff --git a/swig/python/requests/help.pyc b/swig/python/requests/help.pyc deleted file mode 100644 index 797bbe337f443380457b7e4430721cff3bf84b1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3461 zcmcgvUvC@75uZI$q)7d>Y%5Lw0PDIgnbszXBvk@8D2fJdVYiWlQ_=*4fWz@_C7yKL zJKyceA!0wdZ~YMMQ@=nzLD7eNgrc9L&qe#2xjX$a&{vbEib(U&+5fIHEJfCcYwiDR;wm zkA&|DUy=QbOnGvoKk-3aht9fmw$c*4mgv(-hjw47c8pu;(s_r9Z}~pX2K4gU)F~7w z!s6%OlKn(<^hC#BZ>qm1Q+=8G`^_mt!zxQiJXtfKJt%MW6fwc(i;QnZtb6oW zkD8^UhkDdlz+Blldes>I`8+9g8!P%nR-Bi5W=eNm6(9F-dANM66RY#Ea7k39Veyc) z=S4OPXX#Q@$C)YZ2qr;{K7rxSYWIP9T4c7i97n2Ptbwo#C`wLipO*8iN@M8Oab}H( zb6G7ZtDN{P%HSQ`PB{;A(>gQC;C9x9izAT#D*!N9HHJrQ=9FEAg}CpEb0q;ZnGCwM6sKN**JI1>mAE(jc|8)AU+6ghEScT z^-QxJ>4LOhmhP5p%9odkn%I*}%v^+L$b2?S0y0hIIm`D5*^1`RBeb zyyB(Y)r+j6ui!-nJs<}F3CIK>=|X}h|7+O5YF63_)SDX<08%X9;#vZ&SpKTdOJAbW-Jx@+-B!?q z;jV=!7{t<6DH#g<0rwdG*3d!fI^46}?29+RLrvU7hXZY)!~Sh_kZ}tg&c8!@Y%Yo) zgvPfSLpjLHAEWuLv8D(eXEvu`o!6Y2;kCLokqqNFHw($0CTxAaNuMi}&nYO8(G;aN zFiVc*2VeVA={SB54xj8F9sNG|!xR7L>A`-m|HWs&e&YL_3_j0G2G^_nFH} za4KIid>ez-jMiUcJ{!X73XlSUlH1_Ck@~`CyPLz;3z^Y)pk~PPqJ1mWEJmyAo~gO4 zncX8J{|6X}^RMngCf+8}F!=K+e}TSyhK9V3>ZlEM$J;>PSDPIMnQd_UYUuUA8>)9O z+T~w&2V>pgIsR@mJ<}Z(u{8cjvEfG(X9G~jDFz-~)N6S(;idsDfSA|H!<$ASg^tDy zUgdje4pGD1@{zpWq}=ga?|LSMrG9pFus@NIErGScxj`Cnwj=;z>wq;x`yx?_gou*x zIxF#nWKD6k$V>l2P{RMbsLa(Ryd})%n^@pITcDSeCQq^`2$+j!={sy5`!WbnY=S`2 zIKYdRpAA9aV}|^Xxsgoc8sh(ioBP~oZaA?7N9sKLDTa=7FAt;h@YIx(CeA1Pwl0!c zokWa2PZ#{UuCtY|(I0UmStrTMzVkVV8k_kQ0Gq+6Yvx;W;wtogvXK7|e#uZ$K19<) e_;R(xx9&X-=Q{}39==27bq4na9}QO4)&Bq=0YT{i diff --git a/swig/python/requests/hooks.pyc b/swig/python/requests/hooks.pyc deleted file mode 100644 index 4a102e2bd5bc3a4e52aae69849a67dc87ebbd5d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1359 zcmcgs!D<^Z5FM=(H(nBwltK@^=u$9+m>k+1LP%N~LLuOQ9a;z**7B}wt6s0xlGcf- z(@T2oH}o6&4gIA4KxdS7O+TPnR!r6~sR|!-P!|z)h_9coG;0h&! zA%iOhX#n5Q5N)6IA=r-3W{3nXg$Z099v#pWVV;g?`=Ly5hk+OWE(=wC1FnXp^ zX}KFoo`^#9Ri>Om!$2Ev>{Q9PPsZ)sIyq^D;k%hondoBG#@Ue8Ed=-kR)?=a-} zTw>CtjSpomjc_vM1EVKg@G5gFbQ_3z8TXfh8XDiznVz9={``1s$Kdpy0lwX4fR1)T zRFOvUmc|Pd3xMlgxMQ$D)&K?pd}LE33UC=MXg5)S&){frYu^!nawc>4;3B`hMv)vw zrIp4;McL0(5~VsRCm3d<8=a@<7zrbz#7N<^L2inuP{m%qR9U)rFnhf}A4bc9tQ5~# ztC-sc?r=oZ+!p5eDeXyc>J_v#)Kir>5AMUo#d&uH&TIc4q1z%1av;jg#UA$V5+$&N zNU!4{pyy=&f&w`&HmPLyP?g{_76PZNnwlFx)-eow`aS@2;>+Z{Il%23nx0<2g1a?X z;ESO(_>S&%Sgcd~j~iglNWTkUdPeUjT!(Sprtg9S1aYctAzU)TRu;ZRIT5LJF3gs&U80Ut4z zb6+aYlcU;_7E@|RLE{@?hSo16hYQi>N%bMC+CElUD~>#b=ZMAMH3+uZHml>vq>Ejr0Kpb~GH*{$_J1ADzAFD4naMz=U-`Fwrs3n5ytWj&!{{WQQVY>hT diff --git a/swig/python/requests/models.pyc b/swig/python/requests/models.pyc deleted file mode 100644 index 26dd0c512c9451744b246e9f53c03cd445176411..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30772 zcmeI5dvG1sec#XC3xEI!5ES?jDN*8zHbsacA?jg0V2Kt*QWh-zi|{?^4y~$NJxj^rXxYoF9Pq@m2 zzaMq2N!Q-&Dx3ZNm}^bB_Oz=^yY?1W+2YzWt}^4=TU}+Vud&IsZgcHfSDEF0+%+a# zYny9tca`n_e$usexb{w0+3D{$yVmWly~|a0`THr?+U?qRxXK-_eW$D3>Dqf-WsiS0 z?OJ!a_T8>>w`=cpmA$SVx=QHU_qfVEuD#Dy_PO>4T;&6<{XtjxpnqqJYwdUKdtK#T z*FNAX2Yl&_Yt6a#eXeq!Yaeu#gRXtQtK9F}hg{{5Yae!%!>&E=D)X-WfU7*<+DBaF zh-*LSDi6B$L$30WZ)K}%J?z?#xXL50{UKNRkZV8cDv!GMW3KX;Yd`KPkGu90uJVLy zFSyErYk$~PKJ400y2_KT{gkUbPf@z)8h5$)1$zJt-CaC*$u;)ojf6$%%YwbrbN2`&mq;d)_{wUW z_S5-xw-L9}$xp8TH#vD`rJ062Ty4c+z1!*6nw>Q4uf$<5X|`+0TG+jCDX#ZbR_lko z?zK1xqrB0{=J)uwI2Z7#{uD{}9^=rP$ z1XU8ex{Z->&I66D|2P4_w`PlCYtf3T2ft3y6tL%clx(c zelhM>{j=%{V~YLoDC(`{<-9bvN$qHE)cjz?FE-P(*|~VSz7n@<{Yjpm>Rhe0nvGYY z7y26H@s-ui<+yQDlTJndrafSJ<4)h^wRkY2H@ck;Ys{qi%If^-eiGN(JV{sEG^SOU zgT^^qihj4+Ve+oV)wG|`lohUanzqc%v|3B+&E}l?*55*M5fDtP%gt8YskP%`4raZ*iN%{mA%=+>pQ+o`Vhmu;#659-j*{tntLf z*Ra*RV5`6wRy+3P{x}c0O?$0o-1)@z9f(2-AjGfLL4dvpR=f9Fuh}~+kZ2r! z^y(u=)-Jv#bP;hMWIUCh@2wdOs@tNePw}~Qr#?S2R+=eI1Y^NOY1)2I2U|<^e8~iV zwq#o=@r%VE`X#r_e3x9ZTg!Kvnc)|!rJ_T_MZVT};8*+luWCZ5%4(cA|M%T%thFt- zS}r>#kp|K=%`~@K(vq7>eoQwPb5OY6((Q@!jSK=BqweyAOTJ)mu*v#Z(nPB(-!One z)+y_Y9a`lPpBl+4{IT+vhAWKN$bhmdUvT_Cdu7p`1z~}p25(K$PHnO5bNC4)NZbBEZT{$RDGALHmzwyNg9&4i57#@hq(mnMfQj1{Q+Wq0Mvpl-vRy*?W-T_?^@2BI~a^ga4?1B@q~$h);! zqH0Fbel6%vXPpyi;Y**~kc7=w|9?W(&Yd<|M!iO^=9KQSMAycDZjt8+-rk;ZI7w8Z6FlGN6sC)601*Dl(%%R{;Lk~eY^>TNX)wEa^3JK$=wW5>!j*gQUD_QRQUn~As$N%d24;Tm1 zbSBHzdErm=G43~(@d%T1#$$tSQ;jDQ)A~Sg?cV zGgfCuX*L)u?LthPD%}%o4Q?yVmb^kL0I8z=wc~2lR=-;H)&p+!41h$1>aRtQb7N2g z=kGV`NJ=Z+M)WMDk;LD@>{xCCMB?Z$pA~?n5-XUK9W!^DE}E%D&q?E7uM-KDp3xgp zBVyBu8m16=d*0iWl%@D+`Rjt6{1WJ-pCW+;!;&sJcX^Xb_KEhx$0^(iK^8AJ2!lQY zd8j#JbTMntZ9&J>0iH-DmWquKCf} zN4TWsr3XkD@AvtE<`(A!^F|2FU=%&it*3&F z5tEe?QM^c`kQD@su0ul`e%z0$P)lU9Yve=CZ0Oh!fS_F&P?*{4mncYO&2#0MU>lU+ zcBn!D-s-M_x9kLKdxqf<$o9|*fjoV-GwVhG>&ufaIf7skFuc>}fPRlIDPk!mzWl>L zV=sxXHoL3o5R9UO7>pKdG>ZGH2?k0j0n&D4s8o$GzAm5!Sf8!6QhNjk9B|G>LxgCB zZ`vXxal3mpj-KY;mdqBxUL7n<1lGFfGRelShpbvCcEc<3Rf_N?J;~B!kXcZUe9*s`J@j%0c;lPEwt%{rK}U-lUe5IQfAQ3 z1lU)kabpbv_)ynkz%YOFWna=LTDYm;=n|B1rCDE*wvA!9uVw^~bmMBAWbH4Q5*T{! zw-Cydo89C#D1+^+8n&8++&)E<4G+NC!%QArFxvpOS~Jcshgq?jd)F%_2;BU_8@YV9 zkPEa>+#8n1%HJJG{ULUSZf$)hB<(ENFilUOItqM^NyrADWa>e9YMHr|6(j2@la$M< z2+~p~OiRXi41d8u(npF5d#zeMUN>l&Hy1*srjuxXzwd{`IjDjSThIpP}7cUjF1wNEUvA_Rb%*@76^?#H_?cj|=Z- zkp!?nKt(Q(yJS{YX4wu#WyipRkd+_I%e@)dqz~19Ms^U@N0%qXR^Z#Isq_*6&CiQs4-rF+f6JAED?jVbdg-ug zf*rN0X!`Vo3>v(dPOIqqjD-?Ze*Tj|)2BWe3L#w>(*zC{0 zKX4i#z6XTPNgg(b<4qLGpg$vHe}!hHMtFRAjNFDoLA1sf|BTDDTlX#i_uxKRS~SIf zAZpr(t5y6})v6~eS2c)hO4Q_F5F3TUQIF4lgUe*(v7KY+ExT@?C`Z>Rt8>{uq31JP z=|3b{Cx4n#Q(-wX-}gWACxYmZ{0Y3jjRXsHk6LEj#lZEL^620dKzoywL-xllg8`RM zOt`msIxRDL9>GE4vk(zAja!WbKY*%Wf|ITHxpEqF^X zYS%ieNF{5xNbvB2%MUDk3`srdu*`EBhaSYG5MCtIr1KKO=aNF8iL#)D@DmRmIg(2< zVjJsN$Fmf`yCH~G(~6Wa=esf{u_$9AjWRfB@GSWHK%dV*TL)$p87w?)fLD55Iyy4ve1&LxX1F#0sW>J8w@ktoU?%#d+UNRxibN~cOD1`3x)xQ=tB zmr0lv)OENAh$klyj0#(X{4XVc&kc^2>>&&bZ%K9o(=u@p`Rc8*ugpFC%B)t_n2CX^ zKQLd2X=kiJu~DEcz zXKLQMvTPa6%9_{H@~tZ{5lv!qUc;0Gj@93V zM}muYi(oq`eYa-u|Ai=KZ1X7%Pm;ip2&P+u?$44Lh+rPF1Ca?qIZ#cWl)P7Lh>rM3 zc8eeejX=W@fuI^5;9ML7mQ|7qWy)cj+5fy;;l#?y)BeXb)9SB- z$(4hB(78!(b(aP?&SgOPJ!T(rzy#t4k-z93n{R{#<9)1v;zP;?qi{AW>=63^OUo;0 z@=bi8vg{FoyFBKS*R37GEr97fMrz8J3bZXaBOQ&FqA0X!a^U; zcJ^WT-)yV8RZxZzNx}hd@3vZs8xd=hZg3 z^jiV4J~PEzTBEe2rOadDlK&o%zeEH%7NR@?P8A3Pv0%AmxAl}ATc&S8wP+{D9LIr~mfm2!{Kd3O_uB0XPmO3^jpe~D@`Pq_I%&%3+=7D+N zk(XFxO7c7UT=K0FS`8VZQh0Z#VrFFGklpvs{zzfb;4b=+0#ToOgw${ zKsdJrWJvdrydQCudDbWdF=>yRzi`2BWsY1-Pw-|IGi}E9H;&ws+*k+~F`!#ebrAqJ zAHEzXE45x4u60*2+t)DiXNJu;j@Hk9nF&+&^pWQPw(BI&dG`EJ&X4$Ct?@L-D>K177=X`7G|SsDel8Z zD6|x_Z?1Yg@ku|GJJ%cLM93o%_ect+%}_15n1x1QqObKMv7^Wgh@xE4Pb&FwB_B~D zwI#BS?Nd$+%ofLUEHnPemSR1!xsAQy?rZ9MX2pq zux)HAC?l;(VkO?9ta!g^DEnA&ds$()ip}s*7lYqBN;`ym?rB z3HikPVOXY)AitJT^Q?Fy)XPut zv42wVTU(QDrAY~a0!r~(UB+)mK@zAJY)+|h(W&H|=8SvEg6G7teBh+SaZ@s>t!XE< zm=0{2Ec+0O83j(c%8c%8y%q0R9t%a$J{>?GBw$&+Q(ev_6 ztXK%MHRcJoB$iNI?l&Y;sk_jB$y9KqC0SP0Em)-)YI%&dn~hqY%x8aYv zE8h;_)2xnqMEis*Scqu=!%pZ3vWIm{(K&yv!mOWD^ouvZ4Up?DP19-5bwuah4=2nq zDVO7XDtd~?khp%^WAuO=m; z)74w6DHer!vy5OLS3ut37h?9{WR4iW`zO7P9-NU0d>OC!$!sr>Mb4%7+|;@2hp%0` zcG!HfSRH)ua>GQ?Ea3030{*NZ|KJ&m0KA)qjOb^vJ8k09uWP7=*NxS7FCF4o;uv5B z6Vqy0IE)VzTvQ`3Dru;~CXyGKIxLfs^d}SO^*JxlZ=vWIA>&Pg*|V5Ky)*D1PBjTlAyQRT$xOnC2keU6P< zJ{FSsV(LxLwOAm}`i|+HNXh+5Obh;)nh>F6w-4NzjZL0YTLT+Q|2{)6z9#yoKDkZs znbJ16k)i~5pnFUO`{86;gPp;o;sQ&%M#RCkmBrV@({`4&Qu|KhU3bI7*i2I1kw>s= zg>@PAl<`qm>9=h>CLxDg$#kGOc-k>V+Gv|F4}ugxAv&(}m|-H6ilA$7vtzfmy~pc0 zY7xn@llz?fo8T-DPMgCbl{Au}Dn9jLM9E?%!VB!DYJ|9la-*HM!x{1kncoY?G&FqD zhP}_7Ja)pwlp~AYvhgcCjQ%l+-$$e#7!VIZlV-%Q0B9YGH8KeKM|zWM;~3#D^RWO9 zmn)tu{aAT-aG-1=sl|MWzZdKIWp1>dFa%~Fx3{P4o;mp)2F3uB!{UT8Jt1&dm?Li` zKX1|oG~4SUEwe`%IIyS+zNf^fIBH_?7H}bWF;a|^p%=})=k4XYc-QaWQY*F2nkQjKp=9icCP^}lcElR3@#8%BF3;wxeW0(80d~%DHdzOqFnF8O1#rKquOUv8Jbsnt` zVXaai)sHpvVkL`&wrs18J+U*Bt*GblvM_oUY93)2u}5=(3zE_&jJbp6xGX^Pb&EC5 zr{8a}yqWvvZB@2$d3m*C5k@{d)$>S&Y05JtpYhVtaSNbXTFP2IX=kG970(W?95;Ey-5G=TYqz*P^LABDw-vf=z<%6y!l4G$xLld;3 zGMe3B&hr*ud|Y!P;^{`U6>f1(WN8p+5WTM3t4eHT*Oap`gSVBFc{;kF#H+ATF*Y+f@#@6psgo1a zQ#&WN8%xQ(#dWINKQWtUxYEaHB_0l%H7<O@#0p?@cM0*A$nofG6W}Vv&@u>30l~$JoKKp1>Nq*Z)faw zXMVfYZg0&`Y0zQK!dOF)as+wkZV6UQ=$yLI3MPHK@mMcdcTWpfJxosp7Oy5Oc zBe9(~g%-tB**O!2=%zhZ*=x~{eqGf?^S$|~OfIQi^VZ9Mq2k|A@^vM~28`N|b1Px2 z&tW0PFqGl+lYTAwm#X;R!Yqfu?dE+_dOi9DCE|sC#+J#MA}X`T zO%S~SQ@4Is)aUcL8_V{lyrbT2BFX9C2zfgMM+jZ5s?%w;dQ-m#w;M153zVtKA1nII zj>gYu5aPM6Jc02;rVx|S)b&C}`#3k(4@xfcfPLcp9y6?)ZQX0clF?9v2`9QT&5;tO zF99F&hEtZ^8(r4DA%uEhV2vC>I*kt6=`foP%=;wK` zu_z?5wpyi&*(`oRvnVR;IObq`d8?-kLMB1+ajsOYQHY(ak&676k4KOG9$NlJuZVS3-(-&Pq3<8kAhHjJL^#@q_@K07o|vNO1Fvn*-nm&2uLz6a-rL8RjWT+ z0L%Eh`S@Q0i-*oz3M|p@11z@+R7CpNLEr7X9w*&u^-J#oErMkuEefRbq{WNanVNry z;$tlw`#v%Oq-LiXC{!pWS*!sPnof_JZ+@B=Jer7B+o3%fSH4BFU@ovfREnD*?m~{!4024&}p+hg(ZpZnT9b zUekM;+^vEz;rOoz!c3lox_T9 zvw=8ZExd*&*L(B9P*b2S)I2(Q;#73< z_?hbIGsn)Hx*J=rY^X4A+OqonTkkO+6nV(oP6mzK2Qe#{%9Q)v86i+u zxD1H|DG-|>u{n#bV5fI>8WTII4A!#4JaN@r(3yMlk!)5TJ2h-G^KsZGR3iFqJ-J1b zqF9l9G(IL7uhj1jX2_1ntqUn++L@YdVJ4!-Ee);LHSG#g)f4e9l|oERw{ITq_!C z5r(O)MBXmVQIDuiH~|&f6Q<4A4WC5II;-sqI%;4!+q#F3F{#_ zfcI^LopYRT=g|m%BElY0;P640Ion{`0>2deMd&hiPmX@$kkW}#I!~QJkNv@d03s+4 z3d7y|0#+UEDk4)0_ouj+%?+c8@J{=$ku#<%(?}%7>RmjVLmG*`l0O$^i0;z!J4pPN zbBmt&uc|S$P>BIJ2d?KuN14FspN=|CXd-N0wawY9{zf8U`;dbdDoL zPMrU{7Lklw4~&D89<_+oQFnV5@Cu&1YFk^pHJT_YxSwrSL4JM8(WC>1@nGc(Zd{XQuOTi)w5UEpGx;X z8Q}kg^&XPci1b7P%dCZR8(aUTl;@bG*Seiyx#LVy+1a9%n7X?b6zEcC3+XyO9Cke`EOBpHDE-BBQ=Rinr(6 z+3_M7c8a{FAcdG|$3$-^&a`OBoO1X$n{63)%w>>q$>@)H%i8pf2+)-C$iR);02Htt z8|s;knmOaa3`78; zKLrucJRqh3dK8kPssVjyhXjWcK+dfJvflc*Aes__+pfGJVe>7X=G$NCDUI;Imt>E8 zO}Gl$tMVX|^&yiW_o;W8Tqg-CWW8189dhQnidNZl-p=BniA2GXHG7jsUCms zmBr_)r%zQ*8f%-oHEM^cJO^3aEE-V<)8lX}-OY87?f$m@JRY3)^aXB2bG+Zk2NAOr ztnj|U`s=`UNiUE@*7_-1EZ(slY8+PxoT!4)P{0F7c&j8iU+ zYiTLdF69a-N(Ev?lQ)550egH(T4&M*7YV_$C}?a;F~T(>wX9b~d)Yo8of;;4v!w3m z+2i3uk3RUQTs4CB7JsdR^X?=NYnxm>*9dBjtI$4<6hpQz+QaO9*vw;>JKbx9H1bp` zkPd&V$&W-!e!L>aYCRv!A#405?MB3YX(=ftacN0fIVYVaO=Nk7|%CQyE!EB$E_ zPvE8y(mgVf!QAHakVXjYwl!>xs4I_xv{Z(Typ_hJ5l`U?cn8W+U>XyzSOfr3R@_67yX~$089YCr6qk~US}YtK$g_pbO167X7*0QSBulH z7lZ=pSV7YLj-W33rQ`v15wn=|)n>zbKWNR);$F1BEn`L^BaV^9o8PTr8}xmNoaf}~ zl5GJs`{OHqhx>`aA54n=f~o@`G@Zu}*PEbtx?!MbTVSBG8J*uWHwpkk>Bl%!ZF-bF z?qWYeJ%Q|Tt`r8JfncVFLh1vBoe9R+N3d+r=%KFcu0NqzixcPP%^t+w027e`(_Um- z1-OOC(*%kr1|ymnWsk{&w%L)pjEz6eH-~`>+n%iQS;R6@%Vo0@4=-;4U8dluib-fm z+_C^QKmBGz{-DKG333cX;%M7*wnq#V&b`L-P_=lc2{9yB^S%T)DlC18f z`Tc2l+=pdYa|@`~7W!{z#O_a<=TIo~il^?G5(W zHRcHlvojzl&vBy#=T-X~Mvw?3z_(B@B-VQo&)6DL-dpUC&h>05)h7f9Sydjd<3%k( zbO8Yo1&Dk0H`EZQIBYc&j(V6q_)9%9_L}ICX^1)uK>oi%F3L7|sHIi?^{3XFq!nbF z+O?%TEP4H3b}*3!z^h$^rwlQ;gNsr~!_#I5_C{W9<(E^j6H}j#4K|c;o;iC|o0wJS z4;Fnf)dDJ}!6`zwlWp>ThgpnF!T3$(enE-&(op#3DA2pHFrlve1HpuJWj8j#HpCsU zm&G|_o2Yo%`Pi>3_d80iD*0DReoM*kD)~Jn*OdH$l7FLQK}k)CJju~_l>A2}|4GRo zDFJ#i^-7Uzr_P*=hIK2=P4uTqOa}Z5qV$PuJ+h6lAc+8)y_M5Fp z$Ze8OUdq1c*rd4BTW2Loc#EwB3pf*$wHwKM<k-F`u0kJum^s|c@9^`7 z({9%7loDAQ?Tw*Ni75KRF~l^zad=iaGYN0k8-j}}hE6+enLjhwY^DB84Ti_e>{+q$^ig(g|93xP^(=Jglpx^ik3KJVy1sO5jJMm4w- zC!am`$_r3o)Rpv0NVCtQa>GG4b~Obxts zFQ^&yL+8ad2s)#+n%>*0r^SkwWIE?YNNX99eY_%VltVE{dAsyLkDa+;VkQ{P% zXEkS5BvaC8A|Y*)I>-f03lwOI7HJW2!-oH^J3{{Lsv|JC1n`-^{3tf=VMg}*8+kg5->;;^dkQ^kFz zMo!iCtNMs4j;Q(pRXm{TqpCP+p7pBQK~+DbiicGFuqqxlrG2V)MAeU~;!$&-SG7k} z{g^5qQ*~PvZByE>YLBY=W2*R=svlRy)YV1+9_o(`qDvp`^0aYug z`YBaBW$p*1-P5XgTGby{#m80sj4GZ{^>I}kSM>>1oKW?%s(9Aa-m7ZoRQ(B6e8Suh z$-JIa#V3{Jrqt?F>JGMJSgoa0@Hf_GzjD)R^=VanMqO_lQW^JIwbrYGZ&~>9$$R;v zVX0ReIjM=AdPceZs=80z#csY&^7|$KbE-O`+)1^BeLJA;Dt7c*@i|o;Rqk_AdN3(H zud0W5Q@lX9m@6D6xO^T-Z{Xf)xjNJn+SS_g8@+Gb^Xu)MU-7hE_p7a%Yc~V`wpVqv zUAE`U3%0+w>Q+KK^zC}NQC@cKa-(WD-9URfw6zcD}k?d(w$wX`2L#b>N9q^ z6|S6N!yC9gHPP$+0KeISh0%rGNM0&8n`pumF8Ps^%?*S=@QL)ZBb3>_hfyP;~>hI_*_L>8cgfR(-D#_TU-v&2pgKLIyYC zFcQZ zD3RWy$|2`+EpXAhTaC-u&-Ba-mtMItUvg%qFFP|+^Q9}7U%EVB0MaXIw(2gGTeYyX zg3h!l@pQ8sR#v3QEYu)t`=v%X^lrOcCN8Zs!EW(n&D|{BF4symY@ZAzY1S=cwX|6e zHZ$-0FO?gcj$8EtK!EA;asw}W)w#-wTQ7(EP;F|Z)mU?@GmVO0MQ1ZX;0NY`-w54C zIPG>kFoWc3PnETMxuM;L_Bd4Tk$K3CdvSjL+NEl_8M;A%dn&t0Q1(N&)CxS=uVptZ zxsBUi;5SMUc!hgVndJ>P3=F7*`%$D<{8p`6THI`wHNeBbqU<0m3q;AD11O@d*1ZPm z`_)Y|D8d@1;c9csZjx=9o4+)FS$6n3Uh>y{nY^RP9&W-F$VcTV1&IMRgt7Ie{Gg zU5tL(#a`6C21!E`3)l?2a_GkRZ!h_QUAC98kqw*s1d?;c4$Er*2pb6JgFaOJRwL}S z@e5a6+udl^yo#4l5ZiB{yd1XQCYfQ)h{T|o=vL_1gnfC*E=zMs1yU_yEy!Fs*hK#; z?xwx&)oS*lYYS4MMISr9;s$n0b8HK&U#ipq77NnYtbsS~+^i2M>P5ywRUMWa71zO? za)yuyscAKMD7*PoEw$EEr-BS zx8A(b^qS*~Ew5G`fA;p%=QfvbL<86DOf+mg(cJ8yZqdY^M6db~5|zzcnG~+ffHjcH zq=u~F%oA3>)t3@%;CK^kfB+-dkRtT!N10z0D}9h}&H+X6 z47n}f3SpLg=`SO>1~7Gl+NRliZ7=%aN(^6s6~I?CH(N;RM6W=AutRXfhFbv#1Rw!= zDrKyzy}r_hZbOCb3m5EP7z;`;2g&UWSar6&RN_TMne7)16P|7#GoZ5&MDT$wVRMZs%`k5jNxV6Y67^* zJ_@+tB|Kry2o*6;dCA-G8WmRKkJ7;Nxbz2*xR7Q56iURJ6on-StS)Gn{O7Hu?q*dn zONr+$DtD`DS~5M9b6Jv8&YYlgg$$5j!D|Yaem@d|9TxMsHvApj289LmO%Rq=(FGvN zQYdU-FET7d7a-4b=wMFd5B**=Xc3ndLQUL^aGDjvtQ}UBS6#AS*Ab!QI0_B4 z@UeDlOVT6(%z2j2aP1~+klmBd#xp2|We7;&B8qjMW9i9R{oPq>2=t;tfsQXwTv@}V zzl+TSRoLzo5+K{gP3cn`f1BFsQ^9vq+$=CZ)XA%@UbPB>V0a;J042w8S4ykRKH2Du zvaUDARR&ZW3x~yAN{fj8hJuJrkmymXIqp12{~eT3Scgo&C)j&o%By*`)}?~4Q7i*M zkTT`f2w+0GwLWeUUiiWu4$8tHR|g2UcsuxS6@vZa*_Nc8rYIUDX5`#g0ztT@xkWWop;en_opp)b zS}HuvH`y>ZE>Dc#f?W2Cgscx+x3E@d{c*v6EI#N0I?kwSzsOYB8qlBt4y8IssM*S? zH?8b8WI0Svroe$F(_>Kw6yt$(!3CTv5b`1Iy)8{yb{lR$E^hlv3DMD{E>5iQiS{H? zMU@gb6%vuhHFb@djfx8;t7@Or34PKN&N+5ZVtMwgrc`rMPoC6z4{}rHw(A zw2h1AH=C{|;h7K04ZY+BmsO0&rP>OH6fw#0NG^*kTMpcVt zbdrH`t>&*M)I%Ev`OZgGIDTMJ(F@BP?O8a~oup!==A$B+C4|f%)azcj z;*b~0%TP&#s+$F*+T}_X1eDqe2M#e6Y{X&Kp)4kw9=Iacl~8@fuZmWK=EIf-9Dq^S ztS5pj#6UlQn3D`miXk{b-N(R_VrP=Ca6V1HX~Yw<7wSmD$v)(6%4#^I;8GH+zz#WB zw3cEN5OKI^RN%N$BsQBt$Ggv!jweDbO=c!)S*ht$ar7I`F*a@(U85=pRA#hSa@44TLb>A8#cHFKy-0BWP1ph92}xQp63@UqC_<3LX!JiwqnfIRL7!@O~(~EXfG>%#u(;Q3jz#x|U{rl5q=~?(4#^K$F4In-mGm zI}MTk$XGzu!3}dN_*_K9$#V>=z=KHL_#Vc0o$A4&OSLjyL=f0@sGeo0q2-3y&}flq zicO3vfRX)d+8(H_iZVbAIf6xKt9JRe?^W#@bO<&K-L1+OL0cwlW4IIirjqT}Y99DP z2!$tb>ple1q&@07AiYiK+!RxRNgcgItqEZHgZa(_?6v!B_ho}ZX``x${!U_c361!H z_fe5vXA4An0cAlEL%vAEqL~OiSn+k(D1#sgg$P<&>^II4zIq&q5Z0J1aFC);8*KJi ziR`J}iBJp-VcBcIo)zI5`9-|?aTy`0;jW9FXO~gSSw!F8!6jT*0ZVeJJn$e71-UkaWIIc_)uQ*qR+RaGPTjz#o$_DiLKa2s*HA<4qtH z@~8lTnZn@LiBXh`4QhT{P%W)4pmg&PO?h|&)ei!RZiuuBvHg1ED8xg^)o5}L#Y2e8 z$wP{Yl=PplAV?tvGsP_>HY^A5G_B5~ZM15%J^fWIUngz^?zju9Wec_%EjA>wmrWat zeaTyHL5u<$u@|L4!}v{;=?-j+jEuCT*tg3td;v{>elS1*xy!(v7~p{J#8@bLSI|1d z8Wb#UCRjLowRFw7`s!z;N^WjD0z9uTy#oU~>pL2Hm$ z-$GjP*>M4evI>l=k@<_bEqyg*Fc=*$?6&8(+SDN)K8*88>z(TdV&h|u%~}~25m~@% zT)^=iB)~T8j7E~6O~?`>N=MU^K?sR)QcQJ8e?lM{zSw3rg>6IX(-emv(ATWkC1+;~ zr41EN)yIBPZ4-)j;e}?RrPG>kq2dCDq=D5TCES(NRsvVhQ9YG0=P*gZhy;b7iI6SQe~- zy^u09RV(6W#KIC#g&PW}1d>5zr3`G-O}8St*J1$cKWxj3?n)Ub7Id&oF4T)Nm!<`@ zKQJ>dBIUKKbMujrhr+w*)_E0KBcGE`YS%5nZi%i4I!iF38})(=zADa|4p^RL>qHvQLC+3%m*#k z@mWM3>JUmDcGI4kMq>)=w(>mMPKkaqkZ%Uhchy;MVYro)Lldq?2%h|p5d2<`3jFl zB@e5QIG*AAkDSg!s(M&j7*^FIlG&%KM|+Pv6V1vPM$r>KZ{;t!Vi|u zqI@i_c|NuZ+pj-)?%d6brt_=tn9)2e_Js}bck!+VJI6*_zypTBH}z!4Kq!{$cQzQl zYWN%IrqQG+dmHtbG{?9ZNT48Nm+RV@LRM60L1~B+OD>$yaueyz+9=$@aj&6v1v{*G zrE&3f{Us!!#5BMjR9K@~op@s6d>EW)B!ibD}4KFN}=CP;x2!^A&@|j#$E)6?C8vio6EUy7r28OL< z^9cZ)vd$pEa?i;mX3Yfn@S)6yOtyqT0{FK}rB87}DU>KPY-Tw!ijrb+B$No)S^^w= zW@1^Kmys2@RAwRkowlQgvpwzxx98Ixv*ApL!?a+^CY;7YBds;_k#5PD1Mz^-)sa&A z9LWJnfI^WI3|1BKo7|BN84$Viv+Fm4t2>q|KPq`a?~%Oz(P|L15N{Q z4aWo&Td0pP(SR3W2&e#eh&WFmCz|@;naqF@p?PG$h42b8;6lcOg1o_Na3K&1_)1b1 zSSx)Wc!VGa3<8)9wHnj|g=U!IKLGEg9tlT@@u$F8sm)d7J4DgI_?i^cfnpE z<&T1{lIEh=hS-dhyzLlYfDHyDAsHA&9LXTPLdu1nXvEy4v3N=mzgy_k+=Kzd{Alvt zemYu*8VtUG>hPMAg;6_AdJtx19KmDl*|de_SV4>gZ#{9(VkQkacd;qPCQCZG2ib`(}wL(jy2R>Slbca z&M~3RD579AYZ;l4>=wKVfkXSH^Xp80gUMMYGA!v`c*D~ylM#s_|2%JRF%h;*1`$Pv z7(qzOI3zfvx!W{`TrHYtY&QQaNzG}LtKI?Fw+7N_>u@>;b#Vw*V5*Z$`R}l`AC6us zlogtt$vzpOHHAxm3kigRhz7uFg}l%gVn4)Rpe#gQ;C)6l$4Rq*`t(A=td&;H_e%)` z1d*p<4kB8^NThnYyAyf~BBs@a z{2G&DV|phq8{u)%F8ECf?B&`in?ZlfBE|-zS=yka2Lq&YSj4T^5B*g){M z{gVpq=${2N6|(gQw78?gw{1Q0DedT>b7hxohEv)vnvjvC+lVf=ZFRC>5kHII^Zuob zh|hhUas3jCdC&UAEa1oNO33+r9mVjnggBZpR-r)wkypv)jhoHW3nrkCv*M4yQb+i# z2RIB7e+4fnVW`!t`Q_?;5JL@UN7uA<+97HKI0D#LYc*PdxtJILayzz6RL!%~@W$xy z>=gVQaPP<-u$BAzid^A4x_i-Ihtq|2XdkX45QG@kVP1k=Io`w_y%NfSJE-Y064T5M z`Y`2`CCm~LnHV}`7AS0!3kc8_-Pw-1KeMAPIE!G*Ha_}O_W3BML0)7HI_5xIZd?<) zz<$_`R7;wS@bDf-{*D>X!NiTp(&_`0v?JT>y&c`x!XniEd%KCOvOAjZK!`g0U|bwj z3;l{;<8YHa2yfCH!6x=uacm@)w6I5ZL3R@b@UdnzN6;q3IPB;fCUF|@*o0R{Y&#=o z;iN;TaD%`n?J_uvF@!rh7t=rkBH^?N{f6<~2iQww!NUExY2qk$bUg#%3q1oauug8d zafZ}peZ{M+7#{&3i=701P1ABOmDgR{w6tR^oV)=($ZYdh=EVBxEzyMuLyQ2HA=c^vIxM;O38yg=PFibA zrAEZNNA?q8Z>J1uA`@PK#89AV!J)3<{3es%LW01oIJUCG6BP#uYa@W3WNoOV$`~X> zdQ7BaBln8F2g3vx@UO||5TKBUH)AxDwz}cZ=!bY(p=O-MmBIBPT>3Z? z`XxjXg@g??P^3Jlj-rm@*_(;y|KCt~4l^f}gW%$1h|;t>^2xYf$r&(5-XGH8MJ=F4gMaQi#Pb{wfW0eXXk#(H(3Kjk~^e2iO1;^zoD&ocJ_bbcsXOnOY+W@N|yvXsW2 z9$Z4Lk0C=9KDHaQEe25PGoaL|IdPNfKLBrt5t*LXhqkvrp*s2ih4DTOzJstE)&0j+ zLEpZ`cc0+IF>vL5T>E2%ZZcC79xZ1x(@>S)RouKuVX* z{Xhz<)tf0R3L$*06Fgt}*@Dh@9hM~Q;@T_o0!|%}#7(*vk{$*Skpwqe;dlZ=xpxFZ zuXn=GrTM8Bf2L^MyAMSqJlD9c|6k#V1C%4-@9Tgh5+wo{fnBH(-PN7cC{}1#QGXXn z%qFL2uFTBOJTxGB_cxRT+Dx*8C~&Phh{D652OJl^fq+BTQ^`j5h$2J30*wT+kv({r zXsX=NNLe+?E0k67dWimNiXak+x1*!T_(2gU4=ooSD>zG`yx}HTrAG_i7PxAoBW-8{ zz7@DzbF4s*FG}Q$opI;V(b^}zTyz3oF8nem>4yu(LNGGULEM3-7lnuz#(61mHq&DQ zC#^h!b7yoL&RKYL;Ke~7P`i7g$PFIa!r)L2^~*`Z z4}-ISaOfh1D>seE!Y$dUR!9Dl=EI0<^@ z(Rt58MD{YKgQHytO8yE%lW~ZSE+?E~qrm|8$e{+BL?ujQSOOl?N`K$N$!(Z*I{T#e z8FQp*!NO{?{$X|f*7vPUctpaY|AS%CxPKK>fLyCHDb&G9JUO%06MLvH12l-ec6=KD z+D^}Or(Yua_1^ZzGL6ERxYIb)|H#kf70^b!|0Krw` z3>u6i62cG19Ud(qDM;w8s2&gK$~nP$G=@pI;D-^yZ4O*Huk*ntnNZsouc?@z5Or0G zLXb??k*5-e(h%f~bN+s1O{`=N7^QL8y0vl>@tn>e8{+E8`6c5Jrm*Q;Vd5hZn+E*n zFb;|ptbq@Mh>I6rn?R0;IT!lP%LpWqkaFjPDCvkMmexp2%+kn&X=@W*HX60GC&$3V zvl}>n%=*buCLHgOG48UqElc(i3DNTyj_MvpR1f~~s6TzZIJL7MQ9naznA0RTXxXU| z(*s_*#g03 zS^4(B$B0Sn3(+cXaU+1Ta1%p?1PV5Pr=tV`F%q$I>n$R&!Bh@d&O9JEh9!o$BA!KP zBTEczm4gZhi(v`Ig10~tQKw6JsDJ@v;9N$pUHF43X7LBk?r!z$oE)psAK_}ncIv4W zx3VTKgAQY`_>0Zw24K+_&z|<{G}xQZ^E?3S`Q?eEQ4_$<-nDPKgNUm&I&K}L1w@acmg>!7tSGm5{X zz!v$3({mLr1K~f7ixbu_A=!8~LIZMgg7QfLWy5U2OBs+P(Fy{g{E`g5cyVh`T?a)n zVG|>OQ?P4*aHLnhfo9tq9etI6-W<5WlJB@g&OkUlX`4czN{cYj{-VE6LA6A%E!1&vMVu>&R5ah*SPCF>^OTQwI632E95cUWnQww92U>g3!#g5 zcu;MFki~mzaWk=#(WiF^$5T8X4EF-QV-qj4;5#G1T5#kU&zyV}C;E2CXYiJAE1r77 z@syWw-wsWDD0smke1j`QkXNY@bH2IC*@&ZJq1b zFy|_VLCHqGSz@T(H&{l9b_fY_#E2)p_zf~10C6T*9oKFG`)ASJHxpp*>bIVTA1wj) zG@kMjIT68Jzl69v;nkl|>X)$@mYN2I!hZwx2F_=b*9j3%@%1qz*sz;Nql#z>uaoT~ z=rqkQRN%7-;Fb`&qA+5jnQ#?If#om^gbfMU3(J`}CsG@q7+vo?>dV^g3XRY?ba$TL zZP;iA7ypUt#{p*zV#?6Sk|8579GRokrBWMdW5F~#RF%J~%}0+OW?zQu)ePJhYL&oTKt zlV4*(AHNZqKFQoICR{-0OH6)`$?r4yGLyHM{2>!8nQ|y@2=@^h?+`Vezh?4xNZQLH zxm{Ts=TqqTIY6g=5}EAYY*K$He7-N=m+Q@4&K=F|!SR8< zT&9AzPH}>MGpsl$bV&!3$^&)ZcO&SSY(DH2* zk@Gsfy22`mFhbyc3&B#31Wtd34G6j&VotP;Bh1Nx-$$6Edr-(%$JbA^WAo9Ye8eeh zd{NJ>ODzOzFX59UIA#NJ^N(18bGrm`>@Bv!=zA}ubHR%1IR@=y*73LZHB zfWn6YPu#il=5*ynZlET!V-yVk4dMjvAk^{4Qb+J9k3n3IrCB!7HJIi{I?_+mj{#dJzABK5z?)%^En}23HbLTCX z7?UO@#>9xAMFgux5f`E{CdR}iQWth`-?zH&OW6_d`|kWR@5dIp-0y7n&bjBFbME~| z_pe?xyJzo2EQ3EQfM?==IWr=n_!meb(hp=Jkic#g-77jOTl5>EO99^$T@Lt`=t{u1 zMGpboB6=9$R?))&w}~DBxLx!pz#XDT1MU<(25^_?v4Fcp#{l<;9tZf2=z73+MK=Jx zCwcU`1J%Im;ehl!a=na6!L~jHXDhccYcr6PwxXeimnQvpB@6&wPlpJ_72D z&&FD6H*+%MKN%^e`FwUvMDX@Kjki@g$gL~j)|Hgfg;J~uqwS9;_drr%M|fKUkTAuK?UD4`-s zd&Zwui7=N_mM1YBwZ^9Q?O@jS!(5hUZ{~Ake0^MXBkkZe*m zj24ylqnyFO_H9|05M8Jf+kTu%cJ3-2G=2IT*3tAG?+FTf1MS(nlPsP=v_3(eHC4M8 zs>w}?)Q%T?tQJ{&?di;E3$XU<)V>hf$vTSRBu!Gy=E@Lv1%f}gKnmQ- zKDq};?af?+wT(_Riz4yIhRzZuriaXWMOaKx;Cf*p4hww0+L(0*SM+XsFXyvKuoqdjS9U~X%6(KceYJ<%doEhA z_fzPfBlrkzq;P0A-gt<&4>U^;W`|ABd60_d;G5IV6ahDC>%nzFGESLtvap}jmpEgR5elc93vDLRq`zY<33(?HuRRJ6O7^Q3=sc~~zG4rH7+Rq%ash>DQ0#E7W14;~Edv#nl+e$*6ORJ|bYtPYcla<$D#oeU&?+{zicO%ri+BgrYaCD06I#;~NqHwWQ}J>R zTPX7%Jc;Zp$odbS+)}5s)TyMr@oAtsr?-kTTI!Xg{5Q@7)j5m9t6JHs$!_IvHf8=p z=d{|_P;oAY*S6a8Ncm5`j*9bJ#RaY6LMkq5+1HbOL(6u^Ufi;8B zW_G$|sJ6?gzR=e95csJx}7ZFSUELAt3-pw2eb3HmzfE2Um2_4(1J zN^dFCk=Ct6>n+anc+lnapCRkj=Gn|xXNT6+v&7A6V|#yp`LEY|7`s?62WdBnovzAD zQ|qvqqnG^`e}`FsnFq|=YsfyUQ&XGtVU{@eCh7;VHIE8w3Y)p?!mxdTy@meYBH43f z2H1fKc}u0QQ3zi_0vm(?ltkE;LWcrj3(##!VQVglqb{YuuAWLo3P+fyD=oKG+LOW^ z6+Rx^=A!?G==XJk{q1JU4eIeY#U97w-8?%tx;#EJi5vEM8h?+bRc@xHa8}28uBXOL z$`s`y)n#Ss*kxs5b$KF#$K#~Tb9~Ik;ioefALr)NxT><^bUfCv)t3g7;Fs(5Ef!A7 z>S{b5>iyi7GDlUH7g=i9ms9vr=FHS$h~LjXzCSlt*gOsZX}j}4WFh3rs2 znMlQ}Ti4kC^w`uEDmAhO1%N%XuJhPB&e+Uh+>W3dkFjt)fS6odB&TLuquMdq6 z4nF?#6ApdVSgqgFPwJVMGpElp>jv1zU5;N_s2L}d|E{c|%$QuGR3|2eMcFU<#0>83 znj$Gv;O##JjYNR8fhiXYjb6n0OjH`<^Zvp7vyYq4@D=R70xOO7lkcG6G_KR!ST9k~ zVNzZSCHx3o#8aa$LDsU)PO}2^zXHWdSbAd{oUUM9)R%!OltR~8n_bUa>K_68u7V?_lRF%2 zAPmZ9n3XYA3WnrYvgC1~2>98h0kpg59%ZT&KxIVQ53{aBUW0aEnqnU-ON7d{Y zq#LDWG81nzx-0>zwi8Hal+-4M;Nb|WQI%D@$FnR?cYk^D^LtmPqsGB63riCE6>&MNLDT=IdbU#sa4^_+ks&>MkCJE^8qk-yQ!McspX#4Si!{+B5i-I`h z=_)+}HteyAv|hb>e5VaQQrzPUUdHzpI=_bRqgUzj{|Q-Y;5VqbU#%dcIWkcfqPZWS zz__8o=ZX68MF86s-6b4OIx<w9;CZ0_8azYXwKRDQQr?_7&G4Ss z5f9Fkyr%G{I4DedGwimc;NGbz5CYT>_D~VscjmO@mc{AF?yPt*;p+NnN^b-AgIFSp ze%WSkF+7DV3Q!b~3^Baz>^Mr52`pz$`mx2JSt2@Fdd@qYHwQA% z@x;k&6Pt@STDf^Rj+tLOLVo4GgY2+$i_45jeQbhTNVtu@zXjBY3^F(Gv0#3W*?+au-`!SCfx=J!kZpr$mWnH z8YXU45WS585P>LULW2loSOq1X5CLBJV~h@ei0meDdFNi63eKI68FOrh0}^f?dGZ<& zMMBvqnwIG-XVp7Wgu77`in2IW$V+<2gCOJtA$1%wHWQMDnx%J{y@zbcPbsY_oEB2i zb6Tpav)yUk?sPZ1?fL&!x7%$C)=$dvd{({s?Sm1G!JEb6?E^0z-|+T(T%>F+%cgmzS8vlorl`P8t%W9VzwpJQB1d*4|uH{SR#a zfj1pN!6|O$L=iHNv3%ngh=Pe`alm$(fro)mo{w-T@8IH_c7y-B%JdFszrWu1q;<ibN2pQ-OR<^869z?2V|`ax4ZXzBx|JYecinetPn{d%?-bEbaClncgfyZ0bi%`KYNMGv#Bbao&_)GU0Z!IAT7+sE?X(i&-o(A8a>EITL@&33iw- zN*neeg+4x3=m z9QX+Rc*6wG%Z+gpydaqg6C9DuqzPV>%oP(1N#;!x3`^!M6Ly)!t0p+gOSbbl6C9IU zZ<8Q{m!z-PO)w&bQzjTSK~V~CnBce+-Za4p$-HBNlV;H~!6|8~WWtgOPMf{uTar72 z+-(!QEOqag;H+e(P4J3j?wYXIEPmbu=j7?~#>;yqcvY&+m|#pY_f7DcWZq>@OT!n) zQC~yS7l+I3FiDeQJB?~d-xoIg>Fc|-5G8KC8MJGm+lreHq99CMR*lkCcdp&2rctwz zxaoqQx_%tG?IaA`hf%r^HC)d&-PgJ6*ODfy%(ZLoTr+mVl{AbSe$B0-k#@bs#)^H> zPw{6ea?rhDCh1lrmCA!KPH?|c(ZX&NR>L?=^l~RFHY*K3jUI%RB#ooSyx!S?J1sv> z!pcILwkowKNr$(yHd|P3H`6ffMXnv!q?Q!VuBI3i${w^N@4pcTVH^e%Q8i7suzEuu z?L&S(Offbq5gzHsCG)G5+0~YxBq{Hs>2^aK=jE)Qpe8$*Zo_5NNW=LsuB59i6!)+s zskBy4rw5T;-&Q4TJc#0EqaHTWbU$vcy?6aB{pvlqUu`y*qHxiVD|2zPUJ20mwVUJU z#nnaN*2)yX(+#tA>D*a*|OD&JPoEQfF!b(;^9D(9HBI3MHqC4(qQjfwY( z$Tbx8j~vtJ&n|PkT%9x@I%Y91DTI8^e1!6xTy~oe!H;>C1YKs}kyg^u?oMf!nQrVh zUFg4m@3u4$1>8!QZVLOYnWYwge=%*w1It9P``E zM|p@`X>|EpW}2NECh<%Ovm~z}TWZdw55a>o*Q09OOmH=0M|ftu9mgP=JIX;bS3z+x z=D{t6X^PoPgu-uy$H=2nRzL^0oIGb`6*}WwS;qbzSgYzwTn_xOmZlhDayq$ zxhNi!i`RwGJQ9pdKByxO=Y@YN>+&~RVdL#^HQj}JZ@oSF`O5fh&zqdORk>Z7^n|6} zX@~LZ9lzENCs*Y08zrGGVb&`UE1~3)7UWV&D!vuBL#Y^tt(spAQ+6@dT6I6IE=d2b z4wLTWfrVz0dM>XhNyw8Np$!8hyr=^tVHIoU&>h`e`#x!+L9`6}3iZ+fgkTJ^SFyiPia;Ohm6`L{=AD ztHO5D4J&Rc7+%P?cy$!7PEN5aPLH!A*YD(=ey4!{w&Ax6X}7c8>FVB*+lKOfXN$92 z{yXUOI>L{fX%3n2<6&gLkI?<`9)p1cQGyXl7*m@A3M&n>dh$&qUYNGyhRZ1!aicjX zhtTEly2(PbT?^dV&{g3W2F1QU*Zvt_2&+p8mCVYji}@77bmx6M4Y})5f=Ns3grKyZ zw8CmM7lpw{rzvO_zB3z(V&}%xFh#mYI`cTq9!E$-qQ?Q-%&GIJ)TZzg0cm;)PG7Dw z^6aII{2($Ic?>g#7}6|$j`>C8jd^5w{LwNjOQCA%v+BA%2{6}8f+XScd!z&|#t zJLN8FqVYU*#$M{#A5*a|!f@y@kZ71n z2M=NXY%jOS%TmX_4Duc?%i(1sc-eLXojaG4_x+S=3W^V3x>PXnGV`doyzDHe&RyG@ zsF66$>h&7rS5M1l>=Y#`y2v3Z>6?V77xAGv)4J-A)*RzZqtT5oujAdki;u&-yLclh zP&!_s zqzj^Sp?|`-9yK5g$lZX9DV`g}BlGEkz)7Ia1Y9qG7BCZBLivn(&?Npu_njLcIYW}>`L!Vgf zXwg;B?60~t046tWDmzx2P{P&pv5ptrt7}NvJzYF8;wJ4@3%USrs?{hgXeQm4>yNWRfskiYSVQcO#Lasb(Ye&fv;B$K+L(vqscR_u`-1fZp=LFn}VC z0iZFmybqC0NH&+G5D1*JB&~1|rBQyW;ATJ$BEUpSdEpV7dPF4N5hU{D)f=L&z4I){ zBdPl!&Q2)eLaxferJ>Lf zT_Hwc^-XdQ#8nNWBg|h1qvc_WcM0ZvmjgF({|+(d>LJc7B+w$f78SWLBhmWoG-zUyW%t)b9cIN z00MKjN%v&c-eWc1;zx-T611FYN{W(>m`U3$2m!xs<%#dk!!l~Pu-_Dai0x7o$gK*K z{GkR7G42$toSQT?)%4-rFC72i#G@&ZX=B1peo~Dhk%MC4DzB0cy=zRaGog7dn0#vT zmN#Cxa`oC|$-BftYP=ROkyvTrO3QBqgqJEln=zoRFeT8m;$xCnxB^I+co3d;#zuGT4~^fjz^8K@zeZKwM2 z!z6HFb&Q_yckD;7!9y_$*S=MHBtuw{@1i`IljqP05kqk#pCs5G&{mL|N84B=ORYH{ zH7e1jiUocxY;QGXD;%F+M@d5IYVvt!f363xI`15Ewsm#qc0(rg=KCQZ`nv$d0kik# z^3Fa;kp0enXHUMz*`D8{pqp}m6FiPzat}!d`qA{vQ|*%8rv=M699=@fY0cmA{VMp1=h}B7`>OCZH7rl|nF3E~WBsoS- zQ)u-iKv1Dym9Ql-OOo%S?OXm51Q76tj5Tt=4=^e@J<#m5rXnB+R1jRyibD)u3Tyy; z0TBqgHR&*O!k3syMEL@gDoCsm<=TTcr%|y(0{5% zKAYwK6trzUJQ=HSc>WK0gqY(=JmLW`8xN4#co3?JO{&dW4Y~?OLn4~!y5DNSND-%o z@RURWNRM6<$)>W5ctbZ%{g2Uygs8&o$QWjK#x&H37O&8r51GvQz>u!Kf;Qr0BYr zHx}V7a5KvDbQ1V5;(dLy)NM2yquPY4O=x}C{ts;1YG5yf(nLK9f*S08_Z^0cFaYRk zW|0H>H37K+jcc`4*PnxfLOv9vmW={*uAkTn51TPOoV5rlevGlRvG-(D;NnUv3ldv- z&s}U&+fz%3UrxJ#j|TyVe(cuUwKSrUl16oQ2Kb-~00nTMaU6!_-~@OaYWG-b`!_t4HkZQ2h&yOUP+A+bn)#mI zrTSlgd+5HxhFeWn{M-OIu72*CS9e1XTz?*uHo{0DsY1rU4p@LFVP~we_+utxNL6)J z|6}rbjIoKs23JBx`dW1ekLiGnZTxzDnN{q3MhetaV_Z@|?w|lRn3?cnePWEnsba%} zwyOk4h(}PPa~>Ok`k^U$q!2I;^D2Ugv%aa~h#LG8->?&+F`)%#4)nlp@d7NBU5bAx z6guMQFXIAM0L9T)*NdYsP_EGb2Vjg~7^3`eh05i5NEZs6oPoeme+Sg}3|y};Z!$pO z5*Oq%5mpnwL?*(1k+@oM1FDD!%lzPcL*DQWD!(|~$-6MBZqg(d0!XNup>#(qNNo90 z{Ike3GMW$q1PVNc;{B^bAOU3hF5)l?&4#$w*YQr^Ua*eM+9|HZJ@TbW}*4MYI7kS>hqg zBXFK4!k1V&V_o8t{jYfSZC!yuMP{{$NLgs=VUKS81hFr0yHy;bkT!_p_m1jZi?=># zLYvYivpNUb5|67CrxJl*%Y8_#JR4)l0vZ<_;8)W&Rlm@I1{}ybeAgNT7~7zhh-lV# zSM5~kT}FCpR05kwv+63O>Jh?Pa~f*YeI_A_ozaUyjb$E1iMUe)+@=K1SW=StH8zvZ zgyKsiD=`Oqk9BX`asZAoaix%uI_@r-%vP01jC11tev4^A1*$s`_B_A5%?fvZb@Fpa zGDoh+tK*7pNYggbDRE=p9haprpY!95SfRQ&wstFXxe-G%I2O4CBeTe{aLMk7r}6aPG+y@mb@J0f$GLYE}D2{GB%Kcq{kl4H?BTcLLvH z6}e8hxG!xJqLe#b+Bj*QV&N=h7J@jP!!PoyevX&;X|f5iZmyj2gFrrw@oxQ6OwR|L z9?pj86?P%3bl8Q81rr070Ehy)VQw4%qeYRhkeJLfB;){_*>c=kUoH+x)|beUT_V*Z z^DIaWp(W0_V-5gRtzDF4$xI?Pw>S+Gb#X!7DVx}si4D(M6YH_r*U;@4>_<8`1*NZJ zI&qnG+S3_KeiI)IlQLTiqmfcN;XAc6>Xxu@2envJt>|8XU=}Z7)PRhp)z*ZG0aHrN zC$&F=D5g?H~J1ly_Mmw{mEX@Y(J~hpn2&fc~CWq0{^L2Q> zi^pECVsQ_Qy9@UQXNK+{8!o=|`cY;t-q*k?BFBmN3On_6U~K)@I?u0rGI;^*zk7b> z^_6-JZ^*v>ldljryf=Z`-Xsz+RwhCihKS?f`=&K)>mB1g`Ws=Iw-8+RMzVrAF6FD$ z1h3c{GPL4?v|onxMp);@Ws3fM-RBiSH@b%GrgG6!c6L z8L$xhE?Y%G%%PL4BrAevXi!X2u7D8zeYJFB^xV0ZUmZO;HB1{2f<;DMiNxVza%My0#0l{#D3FB!04~ut=$A%Z^+R9NPO3 z#@~gXKw=U+#c~zDga$F@Td9XJp`&JH59w**{#FZT?l{Z)%`}K>jhav$v;x8*(HIA^ zc;zL1=y^uyDSwel09_ZHlG3^jT6){y@3d9`se!^U+LZdRx4TXJYg!EkH{Yj{o19Wg z0dMPYbQ2ZO8+^rVA!}ahcJqPCiG0ja3s_lL%IX zw+^xw(J8;C?}@!>RPs2lYprB279%PaV@Sx*J|Zu!F0>m<0;%E$n@SbWp{pQV3{^$@ z1F4p@;8PAO?MB4U{d*)0#-a_@d~j(cqaE82gcz@q2sxueA^|Qi8*q?-P%!79 zk_3oX6!{XOyQ6kV7$^er1yi?jf?`F(iYQ!y#Z@77ppbu|pby`1H1`Tuf}H?$5vlR5 ziHqc_OfF(jFpAs+i%>D;FpT_6Hv@LlV5JCDTa|%qI&2?Hb2fEG z#FWA3RP-~x%i$L{75EYo9Yb!zwCo&-b{s$9%E!Udytu6(!6@vNwPZZws#)Djf@e7( zkU*=_^l}x;O0diuYgS}Q4VfH^y{*T*YVKm9R-fANoaN`7gS9LB@HEx|;_0u+`aNm8 zq)SrR&E!8J$t)R~h!*F-MVtjH|Tb@3#(lg+CE7WFq>c=t5+xUm2_0jxA2)y zL~*tSmAe_2{h5I{?=NvWDE_8o#n2jz@_wFozRu(?GNCf_zJf&fzj(-C>?`M99W7SAP{j*{XDM`qZ-0yo*>D{eTlqsuLa-L}0eBGd z5SGux{eNubDHxK=V4w;QLyNMGz%X2M%i6yYRZ1Pp{OW*RpMg3wf`pf$Zl@cE!L7O} zC@IAmEYVF7CxO4-H$)Js~dWE>|JJihRioCkZ96F%+^UMF4V&2~96v8X^q{3-9 zyb!(CFDl7$faKfw`rD0B1l#;p2$oxQu@JG!C9k$9TNy3kD&M{BUDd#m4{vT88!cc_ zBLXDcOWsz-w5wBL_B^2G2lHkXv6>!1(|NeP$li>ST`rAZy{blb?zJZ#`ZbQh4>W}@#d??FS1rtZu%tl`x*){{}>0%fL&^gEJNcZ5_ol>zB{ z$Rb5+GxlS09$}j4+2K5cz{_*sx&d+>Fy{c!=l(Ujg>zD4`|3X3+7;ZdXF7%Q3bD`ZCLX_tH784Sb z%IlAj!>Uuv3F=7z1?Bu&3r@O>b zp|0x4*01raAX^1@f*feq3Z*~}Lc9(rKJ6H?Ga8|T)Z6$BSP7z1Z4(M(k;n2pZfvZo zqS!VM>*NxaDud*h!%AfS0~u{s9sDtRC;pZWZ9!7O@$RlR+w_=Mxmk#-;XqYaZ(>_mNL+eW%RSiDiE1m@#}E)j6v9Op<5!GlVmkr3t_sGubwKNJbSKqvUpNu zA8^z9(i6u|oe?U{_9}Ink*#MxYda@S6s09;DwCjG+$9BKabLJ5U|a;!aa~AhA$S}6 zPMOs;ZIVrz)g|ncBE-P1h_nI&uCcakH)y5^4|0ua-A|T8RBD67`B6(`C~itiQ41c( zSVSy}Bu`G5jUXXOHMWr~&*9xv5~rMGuedxDt9{WOc43f|-iKSJ_Yjc(OV0Bu7x{tg zzR1Pn$UrVC7zc$Pyol_<%XEthc`E6vn?@l(NpwZ>=h%Wqd$9u=L#V*`_{s`5V!(e$ zYFk-ZDX#lHMr@!@c@Wa<)R{FgnbF{>mtQVszY|Xe%(Xmv@zXE<^ox0;%GJfSP|C%t z8c6&nC|Dx_xXpdzYZj4n0$i z`3k&KxY#tWKk+|ea#8ESnTnT%0ubz#1_pe$BE?JQS-lv3k*>Q5`&nDZ2ziR zeby>_T~`4?Oeu_iK88SB70DxVud05CJVi zgNeLF(*sLgSOa7G zLEy<%DI;#si?nf!)B;JOvIc|%(g2;{5(G#0HJqCL4#W!{M;;^yZL0=1;ic?Go6v`WBUyyS zACO1A0HNZ~1~kNV`~$P{5gVAef6f3p5_alNwvQRWLM2{;Zofy%ytMqwwus{Km$Rbj z<$h=7lD6_Pcee43u)F1r3AU3x)`8Bw_=noW4b`k4W6pW2> z(+w8_vY#g?U_YGQt~SMeXz=^szHC&(=)H3n8|C7P!~Wuq-JN!gBTuB6`2(>$7PK6@ z53$VC?x2^mML_;?=!lERCTR83L}isqBvT|M$8D>@dHvct~pHrtX7Z6w^P3J$J@!% zNbt$`cTq8tG{rDRCJQ19*tzOHRn9v(04Kg#34Y9-EL?TJgoNpcjJr zK=$mQE4~uRj(Afj5dAkbOoxlQ@Cg{ayG)KU5iR(8%>6!-A28wP$Y5bTYQjZ(-oIlp zC588GCIT&ck;7`-HTWc2)|+7k?(-0t#>lJaZSjI;gJ1FEdF{jZSdlGBC7>P|Pcc38 zBnb9p)36s;Tqq-Dr)F42YIB&+uq!Kmjh#t|NJ_h2udPJ8)1&e|{?#%e<7| z+DnH#$O5u;nSfu7*WWZ*iHfmHF$49Op-9(4+j;uuf;XHg%x);Qbnumvf7RM6jCb?{b(4S4_`t zU>O-WUUmlVH*kURY8C8?Fdanb0BRqA7$^tbsXWeV#55=rMMLG1c_B(#ia|c056M4J zFIpdQGgO_&=4w$$P*f|!L_8DsU3;t#+NOi|eZBlP-uF15Dpx!`CULneS(I_^L>EX$qs&qEb|`CRv>lMD#vjgKM84&(}nAy_4ivy zd;>Q(GPfEUfU>er1AD76^`saCOMGku;38Bkz=rgHT&Z^gX_W6rlH*4bUBrefdyY-W zoLn;5g!OCm&Defd*zbz;``>a{@x!oIneq?&ECY248Sr!jb5R5#2JI}^6wm{wVu8&8 z4$lG?0tcSu`rm>%i^9^dVAxmjtg?kQ3A6bqVr<|fgBLj|j$=*NV`rPmGvY0}jZThU z=HN;Pary@Z&;0xFiP6`EZ>eE#l1%yKYBg-7qm$gji8&IMId=S*C@#GxEiQ#&YZOM? z1GpQ}0=z~I-3+C|_rIac`|n89pG>Lf{RxwQz%u;SC7Uo|q~&bF>0`5rz0Q)OGC9pOLT9~+hli(c@JRo%~ z!E$n}n|h9Zn{T-(Av+*m5&dX@4rd%+kzJl&{)#LsrV^3YI?IRbI%5t&@*O0K#$CUo znIYnM*kLVdEZG&^dU_Q!oYl~BUd%PzA9K(1?7^|)#bWU|BJkkr#a1|f@imBm+65_i zO*VXBYe*gZbDVbvN9;rL6yxseAL8|ET(z~~k&Rx&&h{lCTz6FVd7O0b+n# zT;7rWnlX+u1;$`8Hb}5oLoYZ@0CbJVaH1y`B;r1tbdX!1X$41M7+Sm^k|&6O@Hnr( zPY?r1%D>&_=ksO&nwmHM24$|i2WL|~e)Ib#=+~VWXh{3@6KRNDh4qi;e`JDf+4F~N z*-v;zEH`YR!O}40O+w7QL2PH53`zjE2`k#^-01035eHDLA6}muO`>@j;ZBv4XMvzm zg(NFgraHAxo*e~@;w-E$!ZvI&u{Mti>#u5|Xch0Tpn}*gZ``0&F61de6%ETY)>oE9D;Kp zM&JZ#g%fXj4r9&r&Rj=0lGTM0JY>!8fAIHgd+*%sptdB{8v$#mmcxYZyB zRR|)Oah=K?;uAMT!*}fI572f-2(U(Umew6)#0CCb@Qz6X48$o7cE1lmcxPLu9tLGM zq7&KD6dK_g2LvA#QK^mZ` z<#g6$5%rw_dFZ;WFG)-abs#T9YS2S0&(3XF#s#HjR~-ByI)o?{PZH${7RU|7#u|oT zTmUjdLWSC1=cN&v}>@yJ2+ho zMmpBtac2eCMq05ijv72}36z?N4?#<|TVt+}C;SUIp%9j%4WSJSjcT9m_C^TOwFOuj zdS2@ayO(uZ`-}GU{bTNtB)P~@k>hme)UX}<;0U%I97!JGFan%afP;t_%L5YS_^?6Q z)iWZ(_DFWN4I_biq79`+W&GOY<*CYBlb0tZy^1&a=H%VV8=t>5nI8C*o26Tx_Y#{R zju74uHsD(|`a;6e?#V7Z4Zwgr!8DsI6xl&post1dz~3mqu?%;}EPHX+Y~i7S47TK< zIS&9|VwpHW3w2~iPtM_@BOR$Eg-zD$NzgN#l~ji~+e39Ilq4=_5aBP#T~HgB@_?U| z4?5Zt=rU8CR3*tY5~05JVpBIyDS=rHlLg}Blsr%`kA*ltw91=^kbtN}Kuvp{+ z5rxx930!a_2+nMQ2+I!L6q-m_Ywg%E9BL{jba0Ox0bA(WTf@mxU)DZUi_Y&mSjuZZ8?aXA!0pL9{=dMuAi(wrN-z22b)TU zHPmHEsUwm73d`0G5+$~kgAC<_Qjbzcz?d96N=Snxv;j7I$QuQN%kw;2byKO19xwfT z`2aAlJtnAYpDYU91&zBWFI^Y=NYB}q!x4uo{C2WZrGhiZD;4iokrzY9TjnidOzJK` zpIS8QQPO*tc%v5y&P-3KQar+aT}i`LMY;|i8H;Pk*s_!ztFk~+*dGKt0sk8bk6a*p zO_1fM9wo6JhQJ9@6hto3_49nAfFg-lXatI|LXQiS$)XXdM|Km5$am>R*~FtMFJA-o zV;z7VeQZ(|uF!)A0hP##PSqb=IV6+r-DEuqAvuCb{-+99%6|FwwOf_(%au27Pfc8# ztlYeO>n*j(;KL5G5IQ!uQT}# zCV!I&O&6gwc!S=@YS=LK{yxipi^*>@`2myfGWk6wzmG&{+fHKLZ@_aDYY^{8tZ{+K ze_`^+O#Xz)|77wLB=SMBhb#1Q6sdV8T}*nJ^fTGTU!9bfLE} zP Date: Thu, 21 Feb 2019 11:01:31 +0800 Subject: [PATCH 15/17] update task server function --- .gitignore | 2 ++ swig/python/geodataexserver.py | 11 +++++--- swig/python/taskserver.py | 49 +++++++++++++++++++++++++++++----- swig/python/utils.py | 10 +++++-- 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 470ea02..66183cb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ NJModelServiceSDK .vscode /swig/python/test2.py /swig/python/test.py +/swig/python/*.pyc +/swig/python/requests/*.pyc diff --git a/swig/python/geodataexserver.py b/swig/python/geodataexserver.py index 776672b..15b2f97 100644 --- a/swig/python/geodataexserver.py +++ b/swig/python/geodataexserver.py @@ -17,20 +17,25 @@ class ExData(Service): self.id = id self.pwd = pwd - def download(self, path): + def getURL(self): dataid = self.id if self.pwd == '': pwd_c = '' else: pwd_c = CommonMethod.encryption(self.pwd) + url = "http://" + self.ip + ":" + self.port + "/data/" + dataid + "?pwd=" + pwd_c + return url + + def download(self, path): filepath = path - urllib.urlretrieve("http://" + self.ip + ":" + self.port + "/data/" + dataid + "?pwd=" + pwd_c, filepath) + url = self.getURL() + urllib.urlretrieve(url, filepath) class GeoDataExServer(Service): def __init__(self, ip, port): Service.__init__(self, ip, port) - def upload(self, datapath, tag="", security = False): + def upload(self, datapath, tag = "", security = False): md5 = CommonMethod.getFileMd5(datapath) path = "/data?md5=" + md5 jsData = HttpHelper.Request_get_sync(self.ip, self.port, path) diff --git a/swig/python/taskserver.py b/swig/python/taskserver.py index 8771fd9..4d7cd0d 100644 --- a/swig/python/taskserver.py +++ b/swig/python/taskserver.py @@ -12,23 +12,58 @@ from geodataexserver import ExData from geodataexserver import GeoDataExServer from utils import HttpHelper -class Task: - def __init__(self, pid, dxserver): +class Task(Service): + def __init__(self, ip, port, pid, dxserver, username = "Unknown"): + Service.__init__(self, ip, port) self.pid = pid self.dxserver = dxserver self.data = [] + self.username = username + self.tid = None + self.status = None + + def configInputData(self, state, event, data, tag = ""): + dataItem = { + "StateName" : state, + "Event" : event, + "Url" : "", + "Tag" : tag + } + data_n = self.dxserver.upload(data, tag) + dataItem["Url"] = data_n.getURL() + self.data.append(dataItem) + return 1 + + def checkStatus(self): + resJson = HttpHelper.Request_get_sync(self.ip, self.port, '/task/' + self.tid) + if resJson['result'] == 'suc': + self.status = resJson['t_status'] + return self.status - def configInputData(self, state, event, data): - pass + def _bind(self, tid, status): + self.tid = tid + self.status = status + return 1 class GeoTaskServer(Service): def __init__(self, ip, port): Service.__init__(self, ip, port) def subscribeTask(self, task): - pass + params = { + "inputs" : task.inputs, + "username" : task.username, + "pid" : task.pid + } + resJson = HttpHelper.Request_post_sync(self.ip, self.port, params) + if resJson <> "Error": + if resJson["result"] == "suc": + task._bind(resJson["data"], "Inited") + return 1 + return -2 + return -1 - def createTask(self, pid, dxserver = None): + def createTask(self, pid, dxserver = None, username = "Unknown"): resJson = HttpHelper.Request_get_sync(self.ip, self.port, '/server?pid=' + pid) if resJson['result'] <> 'suc' or resJson['code'] <> 1: return None @@ -38,4 +73,4 @@ class GeoTaskServer(Service): dxserver = GeoDataExServer(resJson['ds_ip'], resJson['ds_port']) else: return None - return Task(pid, dxserver) \ No newline at end of file + return Task(self.ip, self.port, pid, dxserver, username) \ No newline at end of file diff --git a/swig/python/utils.py b/swig/python/utils.py index fe0e359..0bdeae3 100644 --- a/swig/python/utils.py +++ b/swig/python/utils.py @@ -36,8 +36,14 @@ class HttpHelper: @staticmethod - def Request_post_sync(ip, port, path, params, files): - pass + def Request_post_sync(ip, port, path, params = None, files = None): + try : + r = requests.post("http://" + ip + ":" + str(port) + path, params, files=files) + jsData = json.loads(r.text) + return jsData + except Exception, e : + return "Error" + @staticmethod def Request_put_sync(ip, port, path): -- Gitee From 710032a82232fad467923b50f6914fb4d67e8bbf Mon Sep 17 00:00:00 2001 From: FranklinZhang Date: Fri, 1 Mar 2019 20:33:58 +0800 Subject: [PATCH 16/17] update task server functions Signed-off-by: FranklinZhang --- swig/python/__init__.py | 6 ++- swig/python/geodataexserver.py | 4 +- .../{taskserver.py => geotaskserver.py} | 53 ++++++++++++++++--- swig/python/modelservicerecord.py | 1 + 4 files changed, 54 insertions(+), 10 deletions(-) rename swig/python/{taskserver.py => geotaskserver.py} (57%) diff --git a/swig/python/__init__.py b/swig/python/__init__.py index 6a85600..bf9d4a3 100644 --- a/swig/python/__init__.py +++ b/swig/python/__init__.py @@ -1,5 +1,6 @@ from server import Server from data import DataConfigrationItem +from geotaskserver import GeoTaskServer class OGMSService_DEBUG: @staticmethod @@ -8,4 +9,7 @@ class OGMSService_DEBUG: @staticmethod def CreateTaskServer(ip, port): - pass \ No newline at end of file + taskServer = GeoTaskServer(ip, port) + if taskServer.connect(): + return taskServer + return None \ No newline at end of file diff --git a/swig/python/geodataexserver.py b/swig/python/geodataexserver.py index 15b2f97..3fd559e 100644 --- a/swig/python/geodataexserver.py +++ b/swig/python/geodataexserver.py @@ -23,8 +23,8 @@ class ExData(Service): pwd_c = '' else: pwd_c = CommonMethod.encryption(self.pwd) - url = "http://" + self.ip + ":" + self.port + "/data/" + dataid + "?pwd=" + pwd_c - return url + url = "http://" + self.ip + ":" + str(self.port) + "/data/" + dataid + "?pwd=" + pwd_c + return str(url) def download(self, path): filepath = path diff --git a/swig/python/taskserver.py b/swig/python/geotaskserver.py similarity index 57% rename from swig/python/taskserver.py rename to swig/python/geotaskserver.py index 4d7cd0d..a54951c 100644 --- a/swig/python/taskserver.py +++ b/swig/python/geotaskserver.py @@ -6,6 +6,7 @@ import json import time import os import requests +import urllib from base import Service from geodataexserver import ExData @@ -17,7 +18,8 @@ class Task(Service): Service.__init__(self, ip, port) self.pid = pid self.dxserver = dxserver - self.data = [] + self.inputdata = [] + self.outputdata = [] self.username = username self.tid = None self.status = None @@ -31,13 +33,50 @@ class Task(Service): } data_n = self.dxserver.upload(data, tag) dataItem["Url"] = data_n.getURL() - self.data.append(dataItem) + self.inputdata.append(dataItem) return 1 - def checkStatus(self): + # status : 'Inited', 'Started', 'Finished' and 'Error' + def wait4Status(self, status_w, timeout = 7200): + currtime = time.time() + endtime = currtime + timeout + self.refresh() + status = self.status + while status <> status_w and currtime < endtime: + time.sleep(2) + self.refresh() + status = self.status + currtime = time.time() + if endtime >= currtime: + # TODO more judgement + return -1 + return 1 + + def downloadResultByStateEvent(self, state, event, path): + for item in self.outputdata: + if item["StateName"] == state and item["Event"] == event: + urllib.urlretrieve(item["Url"], path) + + def downloadAllData(self): + pass + + + def wait4Finish(self, timeout = 7200): + return self.wait4Status('Finished', timeout) + + + def refresh(self): resJson = HttpHelper.Request_get_sync(self.ip, self.port, '/task/' + self.tid) if resJson['result'] == 'suc': - self.status = resJson['t_status'] + self.status = resJson['data']['t_status'] + for item in resJson['data']['t_outputs']: + dataItem = { + "StateName" : item["StateName"], + "Event" : item["Event"], + "Url" : item["Url"], + "Tag" : item["Tag"] + } + self.outputdata.append(dataItem) return self.status def _bind(self, tid, status): @@ -51,11 +90,11 @@ class GeoTaskServer(Service): def subscribeTask(self, task): params = { - "inputs" : task.inputs, + "inputs" : json.dumps(task.inputdata), "username" : task.username, "pid" : task.pid } - resJson = HttpHelper.Request_post_sync(self.ip, self.port, params) + resJson = HttpHelper.Request_post_sync(self.ip, self.port, '/task', params) if resJson <> "Error": if resJson["result"] == "suc": task._bind(resJson["data"], "Inited") @@ -70,7 +109,7 @@ class GeoTaskServer(Service): if dxserver == None: resJson = HttpHelper.Request_get_sync(self.ip, self.port, '/dxserver?ac=recommend') if resJson['result'] == 'suc' and len(resJson['data']) > 0: - dxserver = GeoDataExServer(resJson['ds_ip'], resJson['ds_port']) + dxserver = GeoDataExServer(resJson['data']['ds_ip'], int(resJson['data']['ds_port'])) else: return None return Task(self.ip, self.port, pid, dxserver, username) \ No newline at end of file diff --git a/swig/python/modelservicerecord.py b/swig/python/modelservicerecord.py index 5009ca1..d5e0751 100644 --- a/swig/python/modelservicerecord.py +++ b/swig/python/modelservicerecord.py @@ -28,6 +28,7 @@ class ModelServiceRunningRecord(Service): self.refresh() currtime = time.time() if endtime >= currtime: + # TODO more judgement return -1 return 1 -- Gitee From 79a6bc8d79d5b147b03e9554e616ce35e1746c79 Mon Sep 17 00:00:00 2001 From: FranklinZhang Date: Fri, 1 Mar 2019 20:49:49 +0800 Subject: [PATCH 17/17] add task test file Signed-off-by: FranklinZhang --- swig/python/test_task.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 swig/python/test_task.py diff --git a/swig/python/test_task.py b/swig/python/test_task.py new file mode 100644 index 0000000..4215100 --- /dev/null +++ b/swig/python/test_task.py @@ -0,0 +1,12 @@ +from __init__ import OGMSService_DEBUG + +taskServer = OGMSService_DEBUG.CreateTaskServer('127.0.0.1', 8061) +task = taskServer.createTask("51c650cd6320c08b54a71a0efa7b7d8a") + +if task <> None: + task.configInputData("RUNSTATE", "LOADDATASET", "E:\\DemoData\\GeoModeling\\FDS\\data11.fds") + taskServer.subscribeTask(task) + task.wait4Finish() + print 'Suc' +else: + print 'Error' \ No newline at end of file -- Gitee