1 #include "../include/message.h"
\r
2 #include "../include/nntp/mime/Mime.h"
\r
3 #include "../include/stringfunctions.h"
\r
4 #include "../include/freenet/messagexml.h"
\r
5 #include "../include/option.h"
\r
7 #include <Poco/DateTimeParser.h>
\r
8 #include <Poco/DateTimeFormatter.h>
\r
9 #include <Poco/UUIDGenerator.h>
\r
10 #include <Poco/UUID.h>
\r
11 #include <algorithm>
\r
13 #ifdef DO_CHARSET_CONVERSION
\r
14 #include "../include/charsetconverter.h"
\r
21 Message::Message(SQLite3DB::DB *db):IDatabase(db)
\r
26 Message::Message(SQLite3DB::DB *db, const long messageid):IDatabase(db)
\r
31 const bool Message::CheckForAdministrationBoard(const std::vector<std::string> &boards)
\r
34 SQLite3DB::Statement st=m_db->Prepare("SELECT BoardName FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID;");
\r
37 while(st.RowReturned())
\r
39 st.ResultText(0,name);
\r
41 if(std::find(boards.begin(),boards.end(),name)!=boards.end())
\r
52 const bool Message::Create(const long localidentityid, const long boardid, const std::string &subject, const std::string &body, const std::string &references)
\r
56 Poco::UUIDGenerator uuidgen;
\r
60 // date is always set to now regardless of what message has
\r
61 m_datetime=Poco::Timestamp();
\r
63 // messageuuid is always a unique id we generate regardless of message message-id
\r
66 uuid=uuidgen.createRandom();
\r
67 m_messageuuid=uuid.toString();
\r
68 StringFunctions::UpperCase(m_messageuuid,m_messageuuid);
\r
72 m_log->fatal("Message::ParseNNTPMessage could not create UUID");
\r
76 SQLite3DB::Statement st=m_db->Prepare("SELECT Name FROM tblLocalIdentity WHERE LocalIdentityID=?;");
\r
77 st.Bind(0,localidentityid);
\r
79 if(st.RowReturned())
\r
81 st.ResultText(0,m_fromname);
\r
84 // get boards posted to
\r
85 std::string boardname="";
\r
86 SQLite3DB::Statement boardst=m_db->Prepare("SELECT BoardName FROM tblBoard WHERE BoardID=?;");
\r
87 boardst.Bind(0,boardid);
\r
89 if(boardst.RowReturned())
\r
91 boardst.ResultText(0,boardname);
\r
94 m_boards.push_back(boardname);
\r
95 m_replyboardname=boardname;
\r
103 m_inreplyto[0]=references;
\r
109 const int Message::FindLocalIdentityID(const std::string &name)
\r
111 SQLite3DB::Statement st=m_db->Prepare("SELECT LocalIdentityID FROM tblLocalIdentity WHERE Name=?;");
\r
114 if(st.RowReturned())
\r
117 st.ResultInt(0,result);
\r
122 if(m_addnewpostfromidentities==true)
\r
124 Poco::DateTime now;
\r
125 st=m_db->Prepare("INSERT INTO tblLocalIdentity(Name,DateCreated) VALUES(?,?);");
\r
127 st.Bind(1,Poco::DateTimeFormatter::format(now,"%Y-%m-%d %H:%M:%S"));
\r
129 return st.GetLastInsertRowID();
\r
138 const std::string Message::GetNNTPArticleID() const
\r
140 // old message - before 0.1.12 - doesn't have @domain so add @freenetproject.org
\r
141 if(m_messageuuid.find("@")==std::string::npos)
\r
143 return "<"+m_messageuuid+"@freenetproject.org>";
\r
147 return "<"+m_messageuuid+">";
\r
151 const std::string Message::GetNNTPBody() const
\r
156 const std::string Message::GetNNTPHeaders() const
\r
158 std::string rval("");
\r
160 rval+="From: "+m_fromname+"\r\n";
\r
161 rval+="Newsgroups: ";
\r
162 for(std::vector<std::string>::const_iterator i=m_boards.begin(); i!=m_boards.end(); i++)
\r
164 if(i!=m_boards.begin())
\r
171 rval+="Subject: "+m_subject+"\r\n";
\r
172 // format time as : Wdy, DD Mon YY HH:MM:SS TIMEZONE
\r
173 rval+="Date: "+Poco::DateTimeFormatter::format(m_datetime,"%w, %d %b %y %H:%M:%S -0000")+"\r\n";
\r
174 if(m_inreplyto.size()>0)
\r
176 rval+="References: ";
\r
177 for(std::map<long,std::string>::const_reverse_iterator j=m_inreplyto.rbegin(); j!=m_inreplyto.rend(); j++)
\r
179 if(j!=m_inreplyto.rend())
\r
183 // old message - before 0.1.12 - doesn't have @domain so add @freenetproject.org
\r
184 if((*j).second.find("@")==std::string::npos)
\r
186 rval+="<"+(*j).second+"@freenetproject.org>";
\r
190 rval+="<"+(*j).second+">";
\r
195 rval+="Followup-To: "+m_replyboardname+"\r\n";
\r
196 rval+="Path: freenet\r\n";
\r
197 rval+="Message-ID: "+GetNNTPArticleID()+"\r\n";
\r
198 rval+="Content-Type: text/plain; charset=UTF-8\r\n";
\r
203 void Message::HandleAdministrationMessage()
\r
205 // only continue if this message was actually a reply to another message
\r
206 if(m_inreplyto.size()>0)
\r
208 int localidentityid=-1;
\r
210 std::string boardname="";
\r
211 std::string identityname="";
\r
213 int changemessagetrust=0;
\r
214 int changetrustlisttrust=0;
\r
215 int origmessagetrust=0;
\r
216 int origtrustlisttrust=0;
\r
217 SQLite3DB::Statement st=m_db->Prepare("SELECT tblBoard.BoardID,BoardName,ModifyLocalMessageTrust,ModifyLocalTrustListTrust FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID;");
\r
220 localidentityid=FindLocalIdentityID(m_fromname);
\r
222 while(st.RowReturned() && localidentityid!=-1)
\r
224 st.ResultInt(0,boardid);
\r
225 st.ResultText(1,boardname);
\r
226 st.ResultInt(2,changemessagetrust);
\r
227 st.ResultInt(3,changetrustlisttrust);
\r
229 if(std::find(m_boards.begin(),m_boards.end(),boardname)!=m_boards.end())
\r
231 SQLite3DB::Statement origmess=m_db->Prepare("SELECT tblIdentity.IdentityID,tblIdentity.Name,tblIdentityTrust.LocalMessageTrust,tblIdentityTrust.LocalTrustListTrust FROM tblIdentity INNER JOIN tblMessage ON tblIdentity.IdentityID=tblMessage.IdentityID LEFT JOIN (SELECT IdentityID,LocalMessageTrust,LocalTrustListTrust FROM tblIdentityTrust WHERE LocalIdentityID=?) AS 'tblIdentityTrust' ON tblIdentity.IdentityID=tblIdentityTrust.IdentityID WHERE tblMessage.MessageUUID=?;");
\r
232 origmess.Bind(0,localidentityid);
\r
233 origmess.Bind(1,m_inreplyto[0]);
\r
236 if(origmess.RowReturned())
\r
238 origmess.ResultInt(0,identityid);
\r
239 origmess.ResultText(1,identityname);
\r
240 if(origmess.ResultNull(2)==false)
\r
242 origmess.ResultInt(2,origmessagetrust);
\r
246 //origmessagetrust=m_minlocalmessagetrust;
\r
247 origmessagetrust=50;
\r
249 if(origmess.ResultNull(3)==false)
\r
251 origmess.ResultInt(3,origtrustlisttrust);
\r
255 //origtrustlisttrust=m_minlocaltrustlisttrust;
\r
256 origtrustlisttrust=50;
\r
259 origmessagetrust+=changemessagetrust;
\r
260 origtrustlisttrust+=changetrustlisttrust;
\r
262 origmessagetrust<0 ? origmessagetrust=0 : false;
\r
263 origmessagetrust>100 ? origmessagetrust=100 : false;
\r
264 origtrustlisttrust<0 ? origtrustlisttrust=0 : false;
\r
265 origtrustlisttrust>100 ? origtrustlisttrust=100 : false;
\r
267 // make sure we have a record in tblIdentityTrust
\r
268 SQLite3DB::Statement ins=m_db->Prepare("INSERT INTO tblIdentityTrust(LocalIdentityID,IdentityID) VALUES(?,?);");
\r
269 ins.Bind(0,localidentityid);
\r
270 ins.Bind(1,identityid);
\r
273 // update new trust levels
\r
274 SQLite3DB::Statement update=m_db->Prepare("UPDATE tblIdentityTrust SET LocalMessageTrust=?, LocalTrustListTrust=? WHERE IdentityID=? AND LocalIdentityID=?;");
\r
275 update.Bind(0,origmessagetrust);
\r
276 update.Bind(1,origtrustlisttrust);
\r
277 update.Bind(2,identityid);
\r
278 update.Bind(3,localidentityid);
\r
281 // insert message to show what id was changed and what current levels are
\r
283 std::string messagebody;
\r
284 std::string messagetruststr="";
\r
285 std::string trustlisttruststr="";
\r
287 Poco::UUIDGenerator uuidgen;
\r
292 uuid=uuidgen.createRandom();
\r
296 m_log->fatal("Message::HandleAdministrationMessage could not generate a UUID");
\r
299 Poco::DateTime now;
\r
300 StringFunctions::Convert(origmessagetrust,messagetruststr);
\r
301 StringFunctions::Convert(origtrustlisttrust,trustlisttruststr);
\r
302 messagebody="Trust List of "+m_fromname+"\r\n";
\r
303 messagebody="Trust Changed for "+identityname+"\r\n";
\r
304 messagebody+="Local Message Trust : "+messagetruststr+"\r\n";
\r
305 messagebody+="Local Trust List Trust : "+trustlisttruststr+"\r\n";
\r
306 SQLite3DB::Statement insert=m_db->Prepare("INSERT INTO tblMessage(FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body) VALUES('FMS',?,?,?,?,?,?);");
\r
307 insert.Bind(0,Poco::DateTimeFormatter::format(now,"%Y-%m-%d"));
\r
308 insert.Bind(1,Poco::DateTimeFormatter::format(now,"%H:%M:%S"));
\r
309 insert.Bind(2,identityname+" Trust Changed");
\r
310 std::string uuidstr=uuid.toString();
\r
311 StringFunctions::UpperCase(uuidstr,uuidstr);
\r
312 insert.Bind(3,uuidstr);
\r
313 insert.Bind(4,boardid);
\r
314 insert.Bind(5,messagebody);
\r
316 lastid=insert.GetLastInsertRowID();
\r
318 insert=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);");
\r
319 insert.Bind(0,lastid);
\r
320 insert.Bind(1,boardid);
\r
323 m_log->debug("Message::HandleAdministrationMessage updated "+identityname+" to "+messagetruststr+" , "+trustlisttruststr);
\r
334 void Message::HandleChangeTrust()
\r
336 if(m_changemessagetrustonreply!=0 && m_inreplyto.size()>0)
\r
338 int localidentityid=FindLocalIdentityID(m_fromname);
\r
339 if(localidentityid!=-1)
\r
341 // make sure we have a record in tblIdentityTrust
\r
342 SQLite3DB::Statement ins=m_db->Prepare("INSERT INTO tblIdentityTrust(LocalIdentityID,IdentityID) VALUES(?,?);");
\r
344 SQLite3DB::Statement st=m_db->Prepare("SELECT tblIdentity.IdentityID,tblIdentityTrust.LocalMessageTrust FROM tblIdentity INNER JOIN tblMessage ON tblIdentity.IdentityID=tblMessage.IdentityID LEFT JOIN (SELECT IdentityID,LocalMessageTrust FROM tblIdentityTrust WHERE LocalIdentityID=?) AS 'tblIdentityTrust' ON tblIdentity.IdentityID=tblIdentityTrust.IdentityID WHERE tblMessage.MessageUUID=?;");
\r
345 st.Bind(0,localidentityid);
\r
346 st.Bind(1,m_inreplyto[0]);
\r
348 if(st.RowReturned())
\r
351 int localmessagetrust=0;
\r
353 st.ResultInt(0,identityid);
\r
354 if(st.ResultNull(1)==false)
\r
356 st.ResultInt(1,localmessagetrust);
\r
360 //localmessagetrust=m_minlocalmessagetrust;
\r
361 localmessagetrust=50;
\r
364 localmessagetrust+=m_changemessagetrustonreply;
\r
365 if(localmessagetrust<0)
\r
367 localmessagetrust=0;
\r
369 if(localmessagetrust>100)
\r
371 localmessagetrust=100;
\r
374 ins.Bind(0,localidentityid);
\r
375 ins.Bind(1,identityid);
\r
378 SQLite3DB::Statement st2=m_db->Prepare("UPDATE tblIdentityTrust SET LocalMessageTrust=? WHERE IdentityID=? AND LocalIdentityID=?;");
\r
379 st2.Bind(0,localmessagetrust);
\r
380 st2.Bind(1,identityid);
\r
381 st2.Bind(2,localidentityid);
\r
389 void Message::Initialize()
\r
391 std::string tempval="";
\r
396 m_replyboardname="";
\r
397 m_datetime=Poco::Timestamp();
\r
400 m_inreplyto.clear();
\r
401 m_fileattachments.clear();
\r
402 m_changemessagetrustonreply=0;
\r
403 Option option(m_db);
\r
405 option.Get("ChangeMessageTrustOnReply",tempval);
\r
406 StringFunctions::Convert(tempval,m_changemessagetrustonreply);
\r
407 option.Get("AddNewPostFromIdentities",tempval);
\r
408 if(tempval=="true")
\r
410 m_addnewpostfromidentities=true;
\r
414 m_addnewpostfromidentities=false;
\r
417 option.Get("MinLocalMessageTrust",tempval);
\r
418 StringFunctions::Convert(tempval,m_minlocalmessagetrust);
\r
420 option.Get("MinLocalTrustListTrust",tempval);
\r
421 StringFunctions::Convert(tempval,m_minlocaltrustlisttrust);
\r
424 const bool Message::Load(const long messageid, const long boardid)
\r
431 sql="SELECT tblMessage.MessageID, MessageUUID, Subject, Body, tblBoard.BoardName, MessageDate, MessageTime, FromName FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID INNER JOIN tblBoard ON tblMessage.ReplyBoardID=tblBoard.BoardID WHERE tblMessage.MessageID=?";
\r
434 sql+=" AND tblMessageBoard.BoardID=?";
\r
438 SQLite3DB::Statement st=m_db->Prepare(sql);
\r
439 st.Bind(0,messageid);
\r
442 st.Bind(1,boardid);
\r
446 if(st.RowReturned())
\r
448 std::string tempdate;
\r
449 std::string temptime;
\r
451 st.ResultInt(0,tempint);
\r
452 m_messageid=tempint;
\r
453 st.ResultText(1,m_messageuuid);
\r
454 st.ResultText(2,m_subject);
\r
455 st.ResultText(3,m_body);
\r
456 st.ResultText(4,m_replyboardname);
\r
457 st.ResultText(5,tempdate);
\r
458 st.ResultText(6,temptime);
\r
459 st.ResultText(7,m_fromname);
\r
463 if(Poco::DateTimeParser::tryParse(tempdate + " " + temptime,m_datetime,tzdiff)==false)
\r
465 m_log->error("Message::Load couldn't parse date/time "+tempdate+" "+temptime);
\r
468 // strip off any \r\n in subject
\r
469 m_subject=StringFunctions::Replace(m_subject,"\r\n","");
\r
472 st=m_db->Prepare("SELECT tblBoard.BoardName FROM tblBoard INNER JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID WHERE tblMessageBoard.MessageID=?;");
\r
473 st.Bind(0,messageid);
\r
475 while(st.RowReturned())
\r
477 std::string tempval;
\r
478 st.ResultText(0,tempval);
\r
479 m_boards.push_back(tempval);
\r
484 // get in reply to list
\r
485 st=m_db->Prepare("SELECT ReplyToMessageUUID, ReplyOrder FROM tblMessageReplyTo INNER JOIN tblMessage ON tblMessageReplyTo.MessageID=tblMessage.MessageID WHERE tblMessage.MessageID=?;");
\r
486 st.Bind(0,messageid);
\r
488 while(st.RowReturned())
\r
490 std::string tempval;
\r
492 st.ResultText(0,tempval);
\r
493 st.ResultInt(1,tempint);
\r
494 m_inreplyto[tempint]=tempval;
\r
508 const bool Message::Load(const std::string &messageuuid)
\r
511 std::string uuid=messageuuid;
\r
513 if(uuid.size()>0 && uuid[0]=='<')
\r
517 if(uuid.size()>0 && uuid[uuid.size()-1]=='>')
\r
519 uuid.erase(uuid.size()-1);
\r
521 if(uuid.find("@freenetproject.org")!=std::string::npos)
\r
523 uuid.erase(uuid.find("@freenetproject.org"));
\r
526 SQLite3DB::Statement st=m_db->Prepare("SELECT MessageID FROM tblMessage WHERE MessageUUID=?;");
\r
530 if(st.RowReturned())
\r
533 st.ResultInt(0,messageid);
\r
535 return Load(messageid);
\r
543 const bool Message::LoadNext(const long messageid, const long boardid)
\r
545 std::string sql="SELECT tblMessage.MessageID FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID WHERE tblMessage.MessageID>?";
\r
548 sql+=" AND tblMessageBoard.BoardID=?";
\r
552 SQLite3DB::Statement st=m_db->Prepare(sql);
\r
554 st.Bind(0,messageid);
\r
557 st.Bind(1,boardid);
\r
561 if(st.RowReturned())
\r
564 st.ResultInt(0,result);
\r
565 return Load(result,boardid);
\r
573 const bool Message::LoadPrevious(const long messageid, const long boardid)
\r
575 std::string sql="SELECT tblMessage.MessageID FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID WHERE tblMessage.MessageID<?";
\r
578 sql+=" AND tblMessageBoard.BoardID=?";
\r
580 sql+=" ORDER BY tblMessage.MessageID DESC;";
\r
582 SQLite3DB::Statement st=m_db->Prepare(sql);
\r
584 st.Bind(0,messageid);
\r
587 st.Bind(1,boardid);
\r
591 if(st.RowReturned())
\r
594 st.ResultInt(0,result);
\r
595 return Load(result,boardid);
\r
603 const bool Message::ParseNNTPMessage(const std::string &nntpmessage)
\r
608 Poco::UUIDGenerator uuidgen;
\r
611 mime.Load(nntpmessage.c_str(),nntpmessage.size());
\r
614 // date is always set to now regardless of what message has
\r
615 m_datetime=Poco::Timestamp();
\r
617 // messageuuid is always a unique id we generate regardless of message message-id
\r
620 uuid=uuidgen.createRandom();
\r
621 m_messageuuid=uuid.toString();
\r
622 StringFunctions::UpperCase(m_messageuuid,m_messageuuid);
\r
626 m_log->fatal("Message::ParseNNTPMessage could not create UUID");
\r
630 if(mime.GetFieldValue("From"))
\r
632 m_fromname=mime.GetFieldValue("From");
\r
633 // remove any path folding
\r
634 m_fromname=StringFunctions::Replace(m_fromname,"\r\n","");
\r
635 m_fromname=StringFunctions::Replace(m_fromname,"\t","");
\r
636 // strip off everything between () and <> and any whitespace
\r
637 std::string::size_type startpos=m_fromname.find("(");
\r
638 std::string::size_type endpos;
\r
639 if(startpos!=std::string::npos)
\r
641 endpos=m_fromname.find(")",startpos);
\r
642 if(endpos!=std::string::npos)
\r
644 m_fromname.erase(startpos,(endpos-startpos)+1);
\r
647 startpos=m_fromname.find("<");
\r
648 if(startpos!=std::string::npos)
\r
650 endpos=m_fromname.find(">",startpos);
\r
651 if(endpos!=std::string::npos)
\r
653 m_fromname.erase(startpos,(endpos-startpos)+1);
\r
656 m_fromname=StringFunctions::TrimWhitespace(m_fromname);
\r
658 // trim off " from beginning and end
\r
659 if(m_fromname.size()>0 && m_fromname[0]=='\"')
\r
661 m_fromname.erase(0,1);
\r
663 if(m_fromname.size()>0 && m_fromname[m_fromname.size()-1]=='\"')
\r
665 m_fromname.erase(m_fromname.size()-1,1);
\r
668 m_fromname=StringFunctions::TrimWhitespace(m_fromname);
\r
672 m_fromname="Anonymous";
\r
674 // get boards posted to
\r
675 if(mime.GetFieldValue("Newsgroups"))
\r
677 std::string temp=mime.GetFieldValue("Newsgroups");
\r
678 // remove any path folding
\r
679 temp=StringFunctions::Replace(temp,"\r\n","");
\r
680 temp=StringFunctions::Replace(temp,"\t","");
\r
681 std::vector<std::string> parts;
\r
682 StringFunctions::SplitMultiple(temp,", \t",parts);
\r
683 for(std::vector<std::string>::iterator i=parts.begin(); i!=parts.end(); i++)
\r
685 (*i)=StringFunctions::Replace((*i),"<","");
\r
686 (*i)=StringFunctions::Replace((*i),">","");
\r
687 (*i)=StringFunctions::TrimWhitespace((*i));
\r
690 m_boards.push_back((*i));
\r
694 // followup-to board - must be done after board vector populated
\r
695 if(mime.GetFieldValue("Followup-To"))
\r
697 m_replyboardname=mime.GetFieldValue("Followup-To");
\r
698 // remove any path folding
\r
699 m_replyboardname=StringFunctions::Replace(m_replyboardname,"\r\n","");
\r
700 m_replyboardname=StringFunctions::Replace(m_replyboardname,"\t","");
\r
701 std::vector<std::string> parts;
\r
702 StringFunctions::Split(m_replyboardname,",",parts);
\r
705 m_replyboardname=parts[0];
\r
710 if(m_boards.size()>0)
\r
712 m_replyboardname=m_boards[0];
\r
716 if(mime.GetFieldValue("Subject"))
\r
718 m_subject=mime.GetFieldValue("Subject");
\r
719 // remove any path folding
\r
720 m_subject=StringFunctions::Replace(m_subject,"\r\n","");
\r
721 m_subject=StringFunctions::Replace(m_subject,"\t","");
\r
722 #if DO_CHARSET_CONVERSION
\r
723 if(mime.GetFieldCharset("Subject"))
\r
725 std::string charset=mime.GetFieldCharset("Subject");
\r
726 CharsetConverter ccv;
\r
727 if(charset!="" && charset!="UTF-8" && ccv.SetConversion(charset,"UTF-8"))
\r
729 std::string output="";
\r
730 ccv.Convert(m_subject,output);
\r
738 m_subject="No Subject";
\r
741 if(mime.GetFieldValue("References"))
\r
743 std::string temp=mime.GetFieldValue("References");
\r
744 // remove any path folding
\r
745 temp=StringFunctions::Replace(temp,"\r\n","");
\r
746 temp=StringFunctions::Replace(temp,"\t"," ");
\r
747 std::vector<std::string> parts;
\r
749 StringFunctions::SplitMultiple(temp,", \t",parts);
\r
750 for(std::vector<std::string>::reverse_iterator i=parts.rbegin(); i!=parts.rend(); i++)
\r
754 // get rid of < and > and any whitespace
\r
755 (*i)=StringFunctions::Replace((*i),"<","");
\r
756 (*i)=StringFunctions::Replace((*i),">","");
\r
757 (*i)=StringFunctions::TrimWhitespace((*i));
\r
759 // erase @ and everything after
\r
760 if((*i).find("@")!=std::string::npos)
\r
762 (*i).erase((*i).find("@"));
\r
765 // only erase after @ if message is old type with @freenetproject.org
\r
766 if((*i).find("@freenetproject.org")!=std::string::npos)
\r
768 (*i).erase((*i).find("@"));
\r
772 m_inreplyto[count++]=(*i);
\r
778 CMimeBody::CBodyList mbl;
\r
779 mime.GetBodyPartList(mbl);
\r
781 // append all text parts of nntp message to body
\r
782 for(CMimeBody::CBodyList::iterator i=mbl.begin(); i!=mbl.end(); i++)
\r
784 if((*i)->IsText() && (*i)->GetContent())
\r
786 std::string bodypart=(char *)(*i)->GetContent();
\r
787 #ifdef DO_CHARSET_CONVERSION
\r
788 std::string charset=(*i)->GetCharset();
\r
789 if(charset!="" && charset!="UTF-8")
\r
791 CharsetConverter ccv;
\r
792 if(ccv.SetConversion(charset,"UTF-8"))
\r
794 std::string output="";
\r
795 ccv.Convert(bodypart,output);
\r
802 // add a binary file attachment
\r
803 else if(((*i)->GetName()!="" || (*i)->GetFilename()!="") && (*i)->GetLength()>0 && (*i)->GetContent())
\r
805 std::string filename="";
\r
806 std::string contenttype="";
\r
807 std::vector<unsigned char> data((*i)->GetContent(),(*i)->GetContent()+(*i)->GetContentLength());
\r
808 if((*i)->GetContentType())
\r
810 contenttype=(*i)->GetContentType();
\r
811 // find first ; tab cr or lf and erase it and everything after it
\r
812 std::string::size_type endpos=contenttype.find_first_of(";\t\r\n ");
\r
813 if(endpos!=std::string::npos)
\r
815 contenttype.erase(endpos);
\r
818 filename=(*i)->GetFilename();
\r
821 filename=(*i)->GetName();
\r
823 m_fileattachments.push_back(fileattachment(filename,contenttype,data));
\r
830 const bool Message::StartFreenetInsert()
\r
834 int localidentityid=-1;
\r
836 StripAdministrationBoards();
\r
838 if(m_boards.size()>0)
\r
841 xml.SetMessageID(m_messageuuid);
\r
842 xml.SetSubject(m_subject);
\r
843 xml.SetBody(m_body);
\r
844 xml.SetReplyBoard(m_replyboardname);
\r
846 for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)
\r
848 xml.AddBoard((*i));
\r
851 for(std::map<long,std::string>::iterator j=m_inreplyto.begin(); j!=m_inreplyto.end(); j++)
\r
853 xml.AddInReplyTo((*j).first,(*j).second);
\r
856 localidentityid=FindLocalIdentityID(m_fromname);
\r
857 if(localidentityid==-1)
\r
862 // add the message delay if there is one
\r
863 SQLite3DB::Statement st=m_db->Prepare("SELECT MinMessageDelay,MaxMessageDelay FROM tblLocalIdentity WHERE LocalIdentityID=?;");
\r
864 st.Bind(0,localidentityid);
\r
866 if(st.RowReturned())
\r
870 st.ResultInt(0,min);
\r
871 st.ResultInt(1,max);
\r
873 min<0 ? min=0 : false;
\r
874 max<0 ? max=0 : false;
\r
875 min>max ? min=max : false;
\r
879 m_datetime+=Poco::Timespan(0,0,min,0,0);
\r
883 int delay=(rand()%(max-min))+min;
\r
884 m_datetime+=Poco::Timespan(0,0,delay,0,0);
\r
890 // set date in xml file AFTER we set the delay
\r
891 xml.SetDate(Poco::DateTimeFormatter::format(m_datetime,"%Y-%m-%d"));
\r
892 xml.SetTime(Poco::DateTimeFormatter::format(m_datetime,"%H:%M:%S"));
\r
894 st=m_db->Prepare("INSERT INTO tblMessageInserts(LocalIdentityID,MessageUUID,MessageXML,SendDate) VALUES(?,?,?,?);");
\r
895 st.Bind(0,localidentityid);
\r
896 st.Bind(1,m_messageuuid);
\r
897 st.Bind(2,xml.GetXML());
\r
898 st.Bind(3,Poco::DateTimeFormatter::format(m_datetime,"%Y-%m-%d %H:%M:%S"));
\r
901 // insert file attachments into database
\r
902 st=m_db->Prepare("INSERT INTO tblFileInserts(MessageUUID,FileName,Size,MimeType,Data) VALUES(?,?,?,?,?);");
\r
903 for(std::vector<fileattachment>::iterator i=m_fileattachments.begin(); i!=m_fileattachments.end(); i++)
\r
905 st.Bind(0,m_messageuuid);
\r
906 st.Bind(1,(*i).m_filename);
\r
907 st.Bind(2,(long)(*i).m_data.size());
\r
908 st.Bind(3,(*i).m_mimetype);
\r
909 st.Bind(4,&((*i).m_data[0]),(*i).m_data.size());
\r
914 HandleChangeTrust();
\r
922 void Message::StripAdministrationBoards()
\r
924 SQLite3DB::Statement st=m_db->Prepare("SELECT tblBoard.BoardID FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID WHERE BoardName=?;");
\r
925 for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); )
\r
929 if(st.RowReturned())
\r
931 if(m_replyboardname==(*i))
\r
933 m_replyboardname="";
\r
935 i=m_boards.erase(i);
\r
943 if(m_replyboardname=="" && m_boards.begin()!=m_boards.end())
\r
945 m_replyboardname=(*m_boards.begin());
\r