1 #include "../include/message.h"
\r
2 #include "../include/nntp/mime/Mime.h"
\r
3 #include "../include/uuidgenerator.h"
\r
4 #include "../include/stringfunctions.h"
\r
5 #include "../include/freenet/messagexml.h"
\r
18 Message::Message(const long messageid)
\r
23 const bool Message::CheckForAdministrationBoard(const std::vector<std::string> &boards)
\r
26 SQLite3DB::Statement st=m_db->Prepare("SELECT BoardName FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID;");
\r
29 while(st.RowReturned())
\r
31 st.ResultText(0,name);
\r
33 if(std::find(boards.begin(),boards.end(),name)!=boards.end())
\r
44 const std::string Message::GetNNTPArticleID() const
\r
46 return "<"+m_messageuuid+"@freenetproject.org>";
\r
49 const std::string Message::GetNNTPBody() const
\r
54 const std::string Message::GetNNTPHeaders() const
\r
56 std::string rval("");
\r
58 rval+="From: "+m_fromname+"\r\n";
\r
59 rval+="Newsgroups: ";
\r
60 for(std::vector<std::string>::const_iterator i=m_boards.begin(); i!=m_boards.end(); i++)
\r
62 if(i!=m_boards.begin())
\r
69 rval+="Subject: "+m_subject+"\r\n";
\r
70 // format time as : Wdy, DD Mon YY HH:MM:SS TIMEZONE
\r
71 rval+="Date: "+m_datetime.Format("%a, %d %b %y %H:%M:%S -0000")+"\r\n";
\r
72 if(m_inreplyto.size()>0)
\r
74 rval+="References: ";
\r
75 for(std::map<long,std::string>::const_reverse_iterator j=m_inreplyto.rbegin(); j!=m_inreplyto.rend(); j++)
\r
77 if(j!=m_inreplyto.rend())
\r
81 rval+="<"+(*j).second+"@freenetproject.org>";
\r
85 rval+="Followup-To: "+m_replyboardname+"\r\n";
\r
86 rval+="Path: freenet\r\n";
\r
87 rval+="Message-ID: "+GetNNTPArticleID()+"\r\n";
\r
88 rval+="Content-Type: text/plain; charset=UTF-8\r\n";
\r
93 void Message::HandleAdministrationMessage()
\r
95 // only continue if this message was actually a reply to another message
\r
96 if(m_inreplyto.size()>0)
\r
99 std::string boardname="";
\r
100 std::string identityname="";
\r
102 int changemessagetrust=0;
\r
103 int changetrustlisttrust=0;
\r
104 int origmessagetrust=0;
\r
105 int origtrustlisttrust=0;
\r
106 SQLite3DB::Statement st=m_db->Prepare("SELECT tblBoard.BoardID,BoardName,ModifyLocalMessageTrust,ModifyLocalTrustListTrust FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID;");
\r
109 while(st.RowReturned())
\r
111 st.ResultInt(0,boardid);
\r
112 st.ResultText(1,boardname);
\r
113 st.ResultInt(2,changemessagetrust);
\r
114 st.ResultInt(3,changetrustlisttrust);
\r
116 if(std::find(m_boards.begin(),m_boards.end(),boardname)!=m_boards.end())
\r
118 SQLite3DB::Statement origmess=m_db->Prepare("SELECT tblIdentity.IdentityID,tblIdentity.Name,tblIdentity.LocalMessageTrust,tblIdentity.LocalTrustListTrust FROM tblIdentity INNER JOIN tblMessage ON tblIdentity.IdentityID=tblMessage.IdentityID WHERE tblMessage.MessageUUID=?;");
\r
119 origmess.Bind(0,m_inreplyto[0]);
\r
122 if(origmess.RowReturned())
\r
124 origmess.ResultInt(0,identityid);
\r
125 origmess.ResultText(1,identityname);
\r
126 origmess.ResultInt(2,origmessagetrust);
\r
127 origmess.ResultInt(3,origtrustlisttrust);
\r
129 origmessagetrust+=changemessagetrust;
\r
130 origtrustlisttrust+=changetrustlisttrust;
\r
132 if(origmessagetrust<0)
\r
134 origmessagetrust=0;
\r
136 if(origmessagetrust>100)
\r
138 origmessagetrust=100;
\r
140 if(origtrustlisttrust<0)
\r
142 origtrustlisttrust=0;
\r
144 if(origtrustlisttrust>100)
\r
146 origtrustlisttrust=100;
\r
149 // update new trust levels
\r
150 SQLite3DB::Statement update=m_db->Prepare("UPDATE tblIdentity SET LocalMessageTrust=?, LocalTrustListTrust=? WHERE IdentityID=?;");
\r
151 update.Bind(0,origmessagetrust);
\r
152 update.Bind(1,origtrustlisttrust);
\r
153 update.Bind(2,identityid);
\r
156 // insert message to show what id was changed and what current levels are
\r
158 std::string messagebody;
\r
159 std::string messagetruststr="";
\r
160 std::string trustlisttruststr="";
\r
161 UUIDGenerator uuid;
\r
164 StringFunctions::Convert(origmessagetrust,messagetruststr);
\r
165 StringFunctions::Convert(origtrustlisttrust,trustlisttruststr);
\r
166 messagebody="Trust Changed for "+identityname+"\r\n";
\r
167 messagebody+="Local Message Trust : "+messagetruststr+"\r\n";
\r
168 messagebody+="Local Trust List Trust : "+trustlisttruststr+"\r\n";
\r
169 SQLite3DB::Statement insert=m_db->Prepare("INSERT INTO tblMessage(FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body) VALUES('FMS',?,?,?,?,?,?);");
\r
170 insert.Bind(0,now.Format("%Y-%m-%d"));
\r
171 insert.Bind(1,now.Format("%H:%M:%S"));
\r
172 insert.Bind(2,identityname+" Trust Changed");
\r
173 insert.Bind(3,uuid.Generate());
\r
174 insert.Bind(4,boardid);
\r
175 insert.Bind(5,messagebody);
\r
177 lastid=insert.GetLastInsertRowID();
\r
179 insert=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);");
\r
180 insert.Bind(0,lastid);
\r
181 insert.Bind(1,boardid);
\r
184 m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"Message::HandleAdministrationMessage updated "+identityname+" to "+messagetruststr+" , "+trustlisttruststr);
\r
195 void Message::Initialize()
\r
201 m_replyboardname="";
\r
205 m_inreplyto.clear();
\r
208 const bool Message::Load(const long messageid, const long boardid)
\r
215 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
218 sql+=" AND tblMessageBoard.BoardID=?";
\r
222 SQLite3DB::Statement st=m_db->Prepare(sql);
\r
223 st.Bind(0,messageid);
\r
226 st.Bind(1,boardid);
\r
230 if(st.RowReturned())
\r
232 std::string tempdate;
\r
233 std::string temptime;
\r
235 st.ResultInt(0,tempint);
\r
236 m_messageid=tempint;
\r
237 st.ResultText(1,m_messageuuid);
\r
238 st.ResultText(2,m_subject);
\r
239 st.ResultText(3,m_body);
\r
240 st.ResultText(4,m_replyboardname);
\r
241 st.ResultText(5,tempdate);
\r
242 st.ResultText(6,temptime);
\r
243 m_datetime.Set(tempdate + " " + temptime);
\r
244 st.ResultText(7,m_fromname);
\r
247 // strip off any \r\n in subject
\r
248 m_subject=StringFunctions::Replace(m_subject,"\r\n","");
\r
251 st=m_db->Prepare("SELECT tblBoard.BoardName FROM tblBoard INNER JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID WHERE tblMessageBoard.MessageID=?;");
\r
252 st.Bind(0,messageid);
\r
254 while(st.RowReturned())
\r
256 std::string tempval;
\r
257 st.ResultText(0,tempval);
\r
258 m_boards.push_back(tempval);
\r
263 // get in reply to list
\r
264 st=m_db->Prepare("SELECT ReplyToMessageUUID, ReplyOrder FROM tblMessageReplyTo INNER JOIN tblMessage ON tblMessageReplyTo.MessageID=tblMessage.MessageID WHERE tblMessage.MessageID=?;");
\r
265 st.Bind(0,messageid);
\r
267 while(st.RowReturned())
\r
269 std::string tempval;
\r
271 st.ResultText(0,tempval);
\r
272 st.ResultInt(1,tempint);
\r
273 m_inreplyto[tempint]=tempval;
\r
287 const bool Message::Load(const std::string &messageuuid)
\r
289 SQLite3DB::Statement st=m_db->Prepare("SELECT MessageID FROM tblMessage WHERE MessageUUID=?;");
\r
290 st.Bind(0,messageuuid);
\r
293 if(st.RowReturned())
\r
296 st.ResultInt(0,messageid);
\r
298 return Load(messageid);
\r
306 const bool Message::LoadNext(const long messageid, const long boardid)
\r
308 std::string sql="SELECT tblMessage.MessageID FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID WHERE tblMessage.MessageID>?";
\r
311 sql+=" AND tblMessageBoard.BoardID=?";
\r
315 SQLite3DB::Statement st=m_db->Prepare(sql);
\r
317 st.Bind(0,messageid);
\r
320 st.Bind(1,boardid);
\r
324 if(st.RowReturned())
\r
327 st.ResultInt(0,result);
\r
328 return Load(result,boardid);
\r
336 const bool Message::LoadPrevious(const long messageid, const long boardid)
\r
338 std::string sql="SELECT tblMessage.MessageID FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID WHERE tblMessage.MessageID<?";
\r
341 sql+=" AND tblMessageBoard.BoardID=?";
\r
343 sql+=" ORDER BY tblMessage.MessageID DESC;";
\r
345 SQLite3DB::Statement st=m_db->Prepare(sql);
\r
347 st.Bind(0,messageid);
\r
350 st.Bind(1,boardid);
\r
354 if(st.RowReturned())
\r
357 st.ResultInt(0,result);
\r
358 return Load(result,boardid);
\r
366 const bool Message::ParseNNTPMessage(const std::string &nntpmessage)
\r
371 UUIDGenerator uuid;
\r
373 mime.Load(nntpmessage.c_str(),nntpmessage.size());
\r
376 // date is always set to now regardless of what message has
\r
377 m_datetime.SetToGMTime();
\r
378 // messageuuid is always a unique id we generate regardless of message message-id
\r
379 m_messageuuid=uuid.Generate();
\r
381 if(mime.GetFieldValue("From"))
\r
383 m_fromname=mime.GetFieldValue("From");
\r
384 // remove any path folding
\r
385 m_fromname=StringFunctions::Replace(m_fromname,"\r\n","");
\r
386 // strip off everything between () and <> and any whitespace
\r
387 std::string::size_type startpos=m_fromname.find("(");
\r
388 std::string::size_type endpos;
\r
389 if(startpos!=std::string::npos)
\r
391 endpos=m_fromname.find(")",startpos);
\r
392 if(endpos!=std::string::npos)
\r
394 m_fromname.erase(startpos,(endpos-startpos)+1);
\r
397 startpos=m_fromname.find("<");
\r
398 if(startpos!=std::string::npos)
\r
400 endpos=m_fromname.find(">",startpos);
\r
401 if(endpos!=std::string::npos)
\r
403 m_fromname.erase(startpos,(endpos-startpos)+1);
\r
406 m_fromname=StringFunctions::TrimWhitespace(m_fromname);
\r
408 // trim off " from beginning and end
\r
409 if(m_fromname.size()>0 && m_fromname[0]=='\"')
\r
411 m_fromname.erase(0,1);
\r
413 if(m_fromname.size()>0 && m_fromname[m_fromname.size()-1]=='\"')
\r
415 m_fromname.erase(m_fromname.size()-1,1);
\r
418 m_fromname=StringFunctions::TrimWhitespace(m_fromname);
\r
422 m_fromname="Anonymous";
\r
424 // get boards posted to
\r
425 if(mime.GetFieldValue("Newsgroups"))
\r
427 std::string temp=mime.GetFieldValue("Newsgroups");
\r
428 // remove any path folding
\r
429 temp=StringFunctions::Replace(temp,"\r\n","");
\r
430 std::vector<std::string> parts;
\r
431 StringFunctions::SplitMultiple(temp,", \t",parts);
\r
432 for(std::vector<std::string>::iterator i=parts.begin(); i!=parts.end(); i++)
\r
434 (*i)=StringFunctions::Replace((*i),"<","");
\r
435 (*i)=StringFunctions::Replace((*i),">","");
\r
436 (*i)=StringFunctions::TrimWhitespace((*i));
\r
439 m_boards.push_back((*i));
\r
443 // followup-to board - must be done after board vector populated
\r
444 if(mime.GetFieldValue("Followup-To"))
\r
446 m_replyboardname=mime.GetFieldValue("Followup-To");
\r
447 // remove any path folding
\r
448 m_replyboardname=StringFunctions::Replace(m_replyboardname,"\r\n","");
\r
452 if(m_boards.size()>0)
\r
454 m_replyboardname=m_boards[0];
\r
458 if(mime.GetFieldValue("Subject"))
\r
460 m_subject=mime.GetFieldValue("Subject");
\r
461 // remove any path folding
\r
462 m_subject=StringFunctions::Replace(m_subject,"\r\n","");
\r
466 m_subject="No Subject";
\r
469 if(mime.GetFieldValue("References"))
\r
471 std::string temp=mime.GetFieldValue("References");
\r
472 // remove any path folding
\r
473 temp=StringFunctions::Replace(temp,"\r\n","");
\r
474 std::vector<std::string> parts;
\r
476 StringFunctions::SplitMultiple(temp,", \t",parts);
\r
477 for(std::vector<std::string>::reverse_iterator i=parts.rbegin(); i!=parts.rend(); i++)
\r
479 // get rid of < and > and any whitespace
\r
480 (*i)=StringFunctions::Replace((*i),"<","");
\r
481 (*i)=StringFunctions::Replace((*i),">","");
\r
482 (*i)=StringFunctions::TrimWhitespace((*i));
\r
483 // erase @ and everything after
\r
484 if((*i).find("@")!=std::string::npos)
\r
486 (*i).erase((*i).find("@"));
\r
490 m_inreplyto[count++]=(*i);
\r
495 CMimeBody::CBodyList mbl;
\r
496 mime.GetBodyPartList(mbl);
\r
498 // append all text parts of nntp message to body
\r
499 for(CMimeBody::CBodyList::iterator i=mbl.begin(); i!=mbl.end(); i++)
\r
501 if((*i)->IsText() && (*i)->GetContent())
\r
503 m_body+=(char *)(*i)->GetContent();
\r
510 void Message::StartFreenetInsert()
\r
514 int localidentityid=-1;
\r
516 xml.SetMessageID(m_messageuuid);
\r
517 xml.SetSubject(m_subject);
\r
518 xml.SetBody(m_body);
\r
519 xml.SetReplyBoard(m_replyboardname);
\r
520 xml.SetDate(m_datetime.Format("%Y-%m-%d"));
\r
521 xml.SetTime(m_datetime.Format("%H:%M:%S"));
\r
523 for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)
\r
525 xml.AddBoard((*i));
\r
528 for(std::map<long,std::string>::iterator j=m_inreplyto.begin(); j!=m_inreplyto.end(); j++)
\r
530 xml.AddInReplyTo((*j).first,(*j).second);
\r
533 // find identity to insert with
\r
534 SQLite3DB::Statement st=m_db->Prepare("SELECT LocalIdentityID FROM tblLocalIdentity WHERE Name=?;");
\r
535 st.Bind(0,m_fromname);
\r
538 // couldn't find identity with this name - insert a new identity
\r
539 if(!st.RowReturned())
\r
543 st=m_db->Prepare("INSERT INTO tblLocalIdentity(Name) VALUES(?);");
\r
544 st.Bind(0,m_fromname);
\r
546 localidentityid=st.GetLastInsertRowID();
\r
550 st.ResultInt(0,localidentityid);
\r
553 st=m_db->Prepare("INSERT INTO tblMessageInserts(LocalIdentityID,MessageUUID,MessageXML) VALUES(?,?,?);");
\r
554 st.Bind(0,localidentityid);
\r
555 st.Bind(1,m_messageuuid);
\r
556 st.Bind(2,xml.GetXML());
\r