version 0.3.2
[fms.git] / src / freenet / fmsversionrequester.cpp
diff --git a/src/freenet/fmsversionrequester.cpp b/src/freenet/fmsversionrequester.cpp
new file mode 100644 (file)
index 0000000..027d530
--- /dev/null
@@ -0,0 +1,176 @@
+#include "../../include/freenet/fmsversionrequester.h"\r
+#include "../../include/freenet/fmsversionxml.h"\r
+#include "../../include/option.h"\r
+#include "../../include/stringfunctions.h"\r
+\r
+#include <Poco/Timestamp.h>\r
+#include <Poco/Timespan.h>\r
+\r
+FMSVersionRequester::FMSVersionRequester()\r
+{\r
+       Initialize();\r
+}\r
+\r
+FMSVersionRequester::FMSVersionRequester(FCPv2 *fcp):IFCPConnected(fcp)\r
+{\r
+       Initialize();\r
+}\r
+\r
+const bool FMSVersionRequester::HandleAllData(FCPMessage &message)\r
+{\r
+       std::vector<char> data;\r
+       long datalength;\r
+       FMSVersionXML xml;\r
+\r
+       StringFunctions::Convert(message["DataLength"],datalength);\r
+\r
+       // wait for all data to be received from connection\r
+       while(m_fcp->Connected() && m_fcp->ReceiveBufferSize()<datalength)\r
+       {\r
+               m_fcp->Update(1);\r
+       }\r
+\r
+       // if we got disconnected- return immediately\r
+       if(m_fcp->Connected()==false)\r
+       {\r
+               return false;\r
+       }\r
+\r
+       // receive the file\r
+       data.resize(datalength);\r
+       m_fcp->ReceiveRaw(&data[0],datalength);\r
+\r
+       // update latest edition #\r
+       std::vector<std::string> parts;\r
+       StringFunctions::Split(message["Identifier"],"/",parts);\r
+       if(parts.size()>2)\r
+       {\r
+               std::string editionstr=parts[2];\r
+               Option::Instance()->Set("FMSVersionEdition",editionstr);\r
+       }\r
+\r
+       // parse file into xml and update the database\r
+       if(xml.ParseXML(std::string(data.begin(),data.end()))==true)\r
+       {\r
+\r
+               SQLite3DB::Statement st=m_db->Prepare("REPLACE INTO tblFMSVersion(Major,Minor,Release,Notes,Changes,PageKey,SourceKey) VALUES(?,?,?,?,?,?,?);");\r
+               st.Bind(0,xml.GetMajor());\r
+               st.Bind(1,xml.GetMinor());\r
+               st.Bind(2,xml.GetRelease());\r
+               st.Bind(3,xml.GetNotes());\r
+               st.Bind(4,xml.GetChanges());\r
+               st.Bind(5,xml.GetPageKey());\r
+               st.Bind(6,xml.GetSourceKey());\r
+               st.Step();\r
+\r
+               m_log->debug("FMSVersionRequester::HandleAllData parsed FMSVersion XML file : "+message["Identifier"]);\r
+       }\r
+       else\r
+       {\r
+               m_log->error("FMSVersionRequester::HandleAllData error parsing FMSVersion XML file : "+message["Identifier"]);\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+const bool FMSVersionRequester::HandleGetFailed(FCPMessage &message)\r
+{\r
+       std::vector<std::string> parts;\r
+       StringFunctions::Split(message["Identifier"],"/",parts);\r
+\r
+       // fatal error - don't try to download again\r
+       if(message["Fatal"]=="true")\r
+       {\r
+               if(parts.size()>2)\r
+               {\r
+                       std::string editionstr=parts[2];\r
+                       Option::Instance()->Set("FMSVersionEdition",editionstr);\r
+               }\r
+               m_log->debug("FMSVersionRequester::HandleGetFailed Fatal GetFailed for "+message["Identifier"]);\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+const bool FMSVersionRequester::HandleMessage(FCPMessage &message)\r
+{\r
+       if(message["Identifier"].find(m_fcpuniquename)==0)\r
+       {\r
+               \r
+               // ignore DataFound\r
+               if(message.GetName()=="DataFound")\r
+               {\r
+                       return true;\r
+               }\r
+\r
+               if(message.GetName()=="AllData")\r
+               {\r
+                       return HandleAllData(message);\r
+               }\r
+\r
+               if(message.GetName()=="GetFailed")\r
+               {\r
+                       return HandleGetFailed(message);\r
+               }\r
+\r
+               if(message.GetName()=="IdentifierCollision")\r
+               {\r
+                       return true;\r
+               }\r
+\r
+       }\r
+\r
+       return false;   \r
+}\r
+\r
+void FMSVersionRequester::Initialize()\r
+{\r
+       m_fcpuniquename="FMSVersionRequester";\r
+       m_lastchecked=Poco::Timestamp();\r
+       m_lastchecked-=Poco::Timespan(0,6,0,0,0);\r
+}\r
+\r
+void FMSVersionRequester::Process()\r
+{\r
+       Poco::DateTime now;\r
+\r
+       // check every 6 hours\r
+       if((m_lastchecked+Poco::Timespan(0,5,45,0,0))<=now)\r
+       {\r
+               StartRequest();\r
+               m_lastchecked=now;\r
+       }\r
+}\r
+\r
+void FMSVersionRequester::RegisterWithThread(FreenetMasterThread *thread)\r
+{\r
+       thread->RegisterFCPConnected(this);\r
+       thread->RegisterFCPMessageHandler(this);\r
+       thread->RegisterPeriodicProcessor(this);\r
+}\r
+\r
+void FMSVersionRequester::StartRequest()\r
+{\r
+       FCPMessage message;\r
+       std::string key="";\r
+       std::string editionstr="0";\r
+       int edition=0;\r
+       \r
+       Option::Instance()->Get("FMSVersionKey",key);\r
+       if(Option::Instance()->Get("FMSVersionEdition",editionstr))\r
+       {\r
+               StringFunctions::Convert(editionstr,edition);\r
+               edition++;\r
+               StringFunctions::Convert(edition,editionstr);\r
+       }\r
+\r
+       //start request\r
+       message.SetName("ClientGet");\r
+       message["URI"]=key+editionstr+"/FMSVersion.xml";\r
+       message["Identifier"]=m_fcpuniquename+"|"+message["URI"];\r
+       message["ReturnType"]="direct";\r
+       message["MaxSize"]="30000";             // 30K\r
+\r
+       m_fcp->SendMessage(message);\r
+\r
+}\r