1 #include "../../include/freenet/siteinserter.h"
\r
2 #include "../../include/global.h"
\r
4 #include <Poco/DateTime.h>
\r
5 #include <Poco/Timespan.h>
\r
6 #include <Poco/DateTimeFormatter.h>
\r
13 SiteInserter::SiteInserter(SQLite3DB::DB *db):IIndexInserter<long>(db)
\r
18 SiteInserter::SiteInserter(SQLite3DB::DB *db, FCPv2::Connection *fcp):IIndexInserter<long>(db,fcp)
\r
23 void SiteInserter::CheckForNeededInsert()
\r
25 // only do 1 insert at a time
\r
26 if(m_inserting.size()==0)
\r
28 Poco::DateTime date;
\r
29 date.assign(date.year(),date.month(),date.day(),0,0,0);
\r
31 SQLite3DB::Statement st=m_db->Prepare("SELECT LocalIdentityID FROM tblLocalIdentity WHERE PublishFreesite='true' AND (LastInsertedFreesite IS NULL OR LastInsertedFreesite<?);");
\r
32 st.Bind(0,Poco::DateTimeFormatter::format(date,"%Y-%m-%d"));
\r
35 if(st.RowReturned())
\r
37 int localidentityid=0;
\r
38 st.ResultInt(0,localidentityid);
\r
39 StartInsert(localidentityid);
\r
44 std::string SiteInserter::GenerateIndex(const std::string &htmltemplate, const long localidentityid, const std::string &name)
\r
46 std::string content="";
\r
48 SQLite3DB::Statement boardst=m_db->Prepare("SELECT tblBoard.BoardName FROM tblBoard INNER JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID WHERE tblMessageBoard.MessageID=? ORDER BY tblBoard.BoardName COLLATE NOCASE;");
\r
49 SQLite3DB::Statement st=m_db->Prepare("SELECT tblMessage.Body, tblMessage.Subject, tblMessage.MessageID FROM tblMessage INNER JOIN tblIdentity ON tblMessage.IdentityID=tblIdentity.IdentityID INNER JOIN tblLocalIdentity ON tblIdentity.PublicKey=tblLocalIdentity.PublicKey WHERE tblLocalIdentity.LocalIdentityID=? ORDER BY tblMessage.MessageDate DESC, tblMessage.MessageTime DESC LIMIT 0,10;");
\r
50 st.Bind(0,localidentityid);
\r
53 while(st.RowReturned())
\r
55 std::string post="";
\r
56 std::string subject="";
\r
57 std::string boards="";
\r
60 st.ResultText(0,post);
\r
61 st.ResultText(1,subject);
\r
62 st.ResultInt(2,messageid);
\r
64 boardst.Bind(0,messageid);
\r
66 while(boardst.RowReturned())
\r
68 std::string board="";
\r
69 boardst.ResultText(0,board);
\r
79 content+="<div class=\"post\">";
\r
80 content+="<div class=\"postboards\">";
\r
81 content+=SanitizeOutput(boards);
\r
83 content+="<div class=\"postsubject\">";
\r
84 content+=SanitizeOutput(subject);
\r
86 content+="<div class=\"postbody\">";
\r
87 content+=SanitizeOutput(post);
\r
88 //post=SanitizeOutput(post);
\r
89 //StringFunctions::Replace(post,"\r\n","<br>");
\r
97 return StringFunctions::Replace(htmltemplate,"[CONTENT]",content);
\r
101 std::string SiteInserter::GenerateLinks(const bool publishtrustlist, const bool publishboardlist)
\r
103 std::string links="";
\r
105 links+="<li><a href=\"index.htm\">Home</a></li>";
\r
106 if(publishtrustlist)
\r
108 links+="<li><a href=\"trustlist.htm\">Trust List</a></li>";
\r
110 if(publishboardlist)
\r
112 // links+="<li><a href=\"boardlist.htm\">Board List</a></li>";
\r
118 void SiteInserter::GeneratePages(const long localidentityid, std::string &uskkey, std::map<std::string,std::string> &pages)
\r
120 SQLite3DB::Statement st=m_db->Prepare("SELECT Name, PrivateKey, PublishTrustList, PublishBoardList, FreesiteEdition FROM tblLocalIdentity WHERE LocalIdentityID=?;");
\r
121 st.Bind(0,localidentityid);
\r
124 if(st.RowReturned())
\r
126 std::string htmltemplate="";
\r
127 std::string filename="";
\r
128 std::string name="";
\r
129 std::string key="";
\r
130 std::string publishtrustliststr="";
\r
131 std::string publishboardliststr="";
\r
132 bool publishtrustlist=false;
\r
133 bool publishboardlist=false;
\r
134 std::string editionstr="";
\r
136 st.ResultText(0,name);
\r
137 st.ResultText(1,key);
\r
138 st.ResultText(2,publishtrustliststr);
\r
139 st.ResultText(3,publishboardliststr);
\r
140 st.ResultText(4,editionstr);
\r
142 publishtrustliststr=="true" ? publishtrustlist=true : publishtrustlist=false;
\r
143 publishboardliststr=="true" ? publishboardlist=true : publishboardlist=false;
\r
144 // no edition exists - start at 0
\r
149 // previous edition exists - add 1
\r
153 StringFunctions::Convert(editionstr,edition);
\r
155 StringFunctions::Convert(edition,editionstr);
\r
159 if(key.find("SSK@")==0)
\r
164 key+=m_messagebase+"/"+editionstr+"/";
\r
167 filename=name+"-template.htm";
\r
168 FILE *infile=fopen(filename.c_str(),"rb");
\r
171 infile=fopen("site-template.htm","rb");
\r
175 fseek(infile,0,SEEK_END);
\r
176 long len=ftell(infile);
\r
177 fseek(infile,0,SEEK_SET);
\r
179 std::vector<unsigned char> data;
\r
181 fread(&data[0],1,data.size(),infile);
\r
184 htmltemplate.append(data.begin(),data.end());
\r
186 htmltemplate=StringFunctions::Replace(htmltemplate,"[LINKS]",GenerateLinks(publishtrustlist,publishboardlist));
\r
187 htmltemplate=StringFunctions::Replace(htmltemplate,"[IDENTITYNAME]",SanitizeOutput(name));
\r
189 pages["index.htm"]=GenerateIndex(htmltemplate,localidentityid,name);
\r
190 if(publishtrustlist)
\r
192 pages["trustlist.htm"]=GenerateTrustList(htmltemplate,localidentityid,name);
\r
194 if(publishboardlist)
\r
196 // pages["boardlist.htm"]=GenerateBoardList(htmltemplate,localidentityid,name);
\r
202 m_log->error("SiteInserter::GeneratePages unable to open "+filename+" or site-template.htm.");
\r
205 // get extra files that the user wants to add to the Freesite
\r
206 filename=name+"-files.txt";
\r
207 infile=fopen(filename.c_str(),"rb");
\r
210 std::vector<std::string> files;
\r
212 fseek(infile,0,SEEK_END);
\r
213 long len=ftell(infile);
\r
214 fseek(infile,0,SEEK_SET);
\r
216 std::vector<unsigned char> data;
\r
218 fread(&data[0],1,data.size(),infile);
\r
221 // split on \r and \n - on systems with \r\n line endings there will be blank entries, but we'll just skip those
\r
222 std::string filecontent(data.begin(),data.end());
\r
223 StringFunctions::SplitMultiple(filecontent,"\r\n",files);
\r
225 for(std::vector<std::string>::iterator i=files.begin(); i!=files.end(); i++)
\r
227 if((*i)!="" && (*i).find("index.htm")==std::string::npos && (*i).find("trustlist.htm")==std::string::npos && (*i).find("files.htm")==std::string::npos)
\r
230 infile=fopen(filename.c_str(),"rb");
\r
233 fseek(infile,0,SEEK_END);
\r
235 fseek(infile,0,SEEK_SET);
\r
238 fread(&data[0],1,data.size(),infile);
\r
242 filecontent.append(data.begin(),data.end());
\r
244 // strip off path from filename
\r
245 while(filename.find_first_of("/")!=std::string::npos)
\r
247 filename.erase(0,filename.find_first_of("/")+1);
\r
250 if(filecontent.size()>0)
\r
252 pages[filename]=filecontent;
\r
258 m_log->error("SiteInserter::GeneratePages could not include user file "+(*i));
\r
268 std::string SiteInserter::GenerateTrustList(const std::string &htmltemplate, const long localidentityid, const std::string &name)
\r
270 std::string content="";
\r
271 Poco::DateTime date;
\r
273 date-=Poco::Timespan(20,0,0,0,0);
\r
274 SQLite3DB::Statement st=m_db->Prepare("SELECT Name,PublicKey,tblIdentityTrust.LocalMessageTrust,tblIdentityTrust.LocalTrustListTrust,tblIdentity.IdentityID,tblIdentityTrust.MessageTrustComment,tblIdentityTrust.TrustListTrustComment,tblIdentity.FreesiteEdition FROM tblIdentity LEFT JOIN (SELECT IdentityID,LocalMessageTrust,LocalTrustListTrust,MessageTrustComment,TrustListTrustComment FROM tblIdentityTrust WHERE LocalIdentityID=?) AS 'tblIdentityTrust' ON tblIdentity.IdentityID=tblIdentityTrust.IdentityID WHERE PublicKey IS NOT NULL AND LastSeen IS NOT NULL AND LastSeen>=? ORDER BY Name COLLATE NOCASE;");
\r
275 st.Bind(0,localidentityid);
\r
276 st.Bind(1,Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S"));
\r
279 content+="<table class=\"trustlist\">";
\r
280 content+="<tr class=\"title\"><thcolspan=\"5\">";
\r
281 content+="Trust List of "+SanitizeOutput(name);
\r
282 content+="</th></tr>";
\r
283 content+="<tr class=\"headings\"><th></th><th>Message Trust</th><th>Message Comment</th><th>Trust List Trust</th><th>Trust Comment</th></tr>";
\r
284 while(st.RowReturned())
\r
286 std::string idname="";
\r
287 std::string thisid="";
\r
288 std::string messagetrustcomment="";
\r
289 std::string trustlisttrustcomment="";
\r
290 std::string messagetrust="";
\r
291 std::string trustlisttrust="";
\r
292 std::string publickey="";
\r
293 std::string uskkey="";
\r
294 std::string freesiteedition="";
\r
296 st.ResultText(0,idname);
\r
297 st.ResultText(1,publickey);
\r
298 st.ResultText(2,messagetrust);
\r
299 st.ResultText(3,trustlisttrust);
\r
300 st.ResultText(4,thisid);
\r
301 st.ResultText(5,messagetrustcomment);
\r
302 st.ResultText(6,trustlisttrustcomment);
\r
303 st.ResultText(7,freesiteedition);
\r
305 if(freesiteedition!="")
\r
307 if(publickey.find("SSK@")==0)
\r
311 uskkey="USK"+uskkey;
\r
312 uskkey+=m_messagebase+"/"+freesiteedition+"/";
\r
317 if(freesiteedition!="")
\r
319 content+="<td><div><a href=\""+uskkey+"\">"+SanitizeOutput(CreateShortIdentityName(idname,publickey))+"</a></div></td>";
\r
323 content+="<td><div>"+SanitizeOutput(CreateShortIdentityName(idname,publickey))+"</div></td>";
\r
325 content+="<td "+GetClassString(messagetrust)+">"+messagetrust+"</td>";
\r
326 content+="<td>"+SanitizeOutput(messagetrustcomment)+"</td>";
\r
327 content+="<td "+GetClassString(trustlisttrust)+">"+trustlisttrust+"</td>";
\r
328 content+="<td>"+SanitizeOutput(trustlisttrustcomment)+"</td>";
\r
329 content+="</tr>\r\n";
\r
333 content+="</table>";
\r
335 return StringFunctions::Replace(htmltemplate,"[CONTENT]",content);
\r
339 const std::string SiteInserter::GetClassString(const std::string &trustlevel)
\r
342 std::string tempstr;
\r
344 StringFunctions::Convert(trustlevel,tempint);
\r
346 StringFunctions::Convert(tempint,tempstr);
\r
350 return "class=\"trust"+tempstr+"\"";
\r
358 const bool SiteInserter::HandlePutFailed(FCPv2::Message &message)
\r
360 std::vector<std::string> idparts;
\r
361 long localidentityid;
\r
363 StringFunctions::Split(message["Identifier"],"|",idparts);
\r
364 StringFunctions::Convert(idparts[1],localidentityid);
\r
366 RemoveFromInsertList(localidentityid);
\r
368 m_log->error("SiteInserter::HandlePutFailed failed to insert Freesite, Freenet error code : "+message["Code"]);
\r
373 const bool SiteInserter::HandlePutSuccessful(FCPv2::Message &message)
\r
375 std::vector<std::string> idparts;
\r
376 std::vector<std::string> uriparts;
\r
377 long localidentityid;
\r
379 Poco::DateTime now;
\r
381 StringFunctions::Split(message["Identifier"],"|",idparts);
\r
382 StringFunctions::Convert(idparts[1],localidentityid);
\r
384 // edition is very last part of uri
\r
385 StringFunctions::Split(message["URI"],"/",uriparts);
\r
386 if(uriparts.size()>0)
\r
388 StringFunctions::Convert(uriparts[uriparts.size()-1],edition);
\r
391 SQLite3DB::Statement st=m_db->Prepare("UPDATE tblLocalIdentity SET LastInsertedFreesite=?, FreesiteEdition=? WHERE LocalIdentityID=?;");
\r
392 st.Bind(0,Poco::DateTimeFormatter::format(now,"%Y-%m-%d %H:%M:%S"));
\r
393 st.Bind(1,edition);
\r
394 st.Bind(2,localidentityid);
\r
397 m_log->information("SiteInserter::HandlePutSuccessful successfully inserted Freesite.");
\r
399 RemoveFromInsertList(localidentityid);
\r
404 void SiteInserter::Initialize()
\r
406 m_fcpuniquename="SiteInserter";
\r
409 const std::string SiteInserter::SanitizeOutput(const std::string &input)
\r
411 // must do & first because all other elements have & in them!
\r
412 std::string output=StringFunctions::Replace(input,"&","&");
\r
413 output=StringFunctions::Replace(output,"<","<");
\r
414 output=StringFunctions::Replace(output,">",">");
\r
415 output=StringFunctions::Replace(output,"\"",""");
\r
416 output=StringFunctions::Replace(output," "," ");
\r
420 const bool SiteInserter::StartInsert(const long &localidentityid)
\r
422 FCPv2::Message message;
\r
423 std::string localidentityidstr="";
\r
424 std::string sizestr="";
\r
425 std::string uskkey="";
\r
426 std::map<std::string,std::string> pages;
\r
429 StringFunctions::Convert(localidentityid,localidentityidstr);
\r
431 GeneratePages(localidentityid,uskkey,pages);
\r
433 message.SetName("ClientPutComplexDir");
\r
434 message["URI"]=uskkey;
\r
435 message["Identifier"]=m_fcpuniquename+"|"+localidentityidstr+"|"+message["URI"];
\r
436 message["DefaultName"]="index.htm";
\r
438 // add each page to the message
\r
439 for(std::map<std::string,std::string>::iterator pagei=pages.begin(); pagei!=pages.end(); pagei++)
\r
441 std::string filenumstr;
\r
442 StringFunctions::Convert(filenum,filenumstr);
\r
445 StringFunctions::Convert((*pagei).second.size(),sizestr);
\r
447 message["Files."+filenumstr+".Name"]=(*pagei).first;
\r
448 message["Files."+filenumstr+".UploadFrom"]="direct";
\r
449 message["Files."+filenumstr+".DataLength"]=sizestr;
\r
454 m_fcp->Send(message);
\r
456 // send data of each page
\r
457 for(std::map<std::string,std::string>::iterator pagei=pages.begin(); pagei!=pages.end(); pagei++)
\r
459 m_fcp->Send(std::vector<char>((*pagei).second.begin(),(*pagei).second.end()));
\r
462 m_inserting.push_back(localidentityid);
\r