From: SomeDude Date: Tue, 2 Dec 2008 17:38:00 +0000 (+0100) Subject: version 0.3.23 X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=221236a4d3aac4144529d418ce368db5c98facb0;p=fms.git version 0.3.23 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cf50e0..a5aef9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,33 +18,29 @@ src/base64.cpp src/bitmapvalidator.cpp src/board.cpp src/boardlist.cpp -src/db src/dbconversions.cpp src/dbmaintenancethread.cpp src/dbsetup.cpp src/fmsapp.cpp -src/freenet src/global.cpp src/hex.cpp -src/http src/ipaddressacl.cpp src/localidentity.cpp src/main.cpp src/message.cpp src/messagelist.cpp -src/nntp +src/messagethread.cpp src/option.cpp src/optionssetup.cpp src/socketdefines.cpp src/stringfunctions.cpp -src/threadwrapper +src/threadbuilder.cpp src/db/sqlite3db.cpp src/db/sqlite3recordset.cpp src/db/sqlite3statement.cpp src/freenet/boardlistinserter.cpp src/freenet/boardlistrequester.cpp src/freenet/boardlistxml.cpp -src/freenet/captcha src/freenet/fcpv2.cpp src/freenet/fileinserter.cpp src/freenet/fmsversionrequester.cpp @@ -71,7 +67,6 @@ src/freenet/trustlistinserter.cpp src/freenet/trustlistrequester.cpp src/freenet/trustlistxml.cpp src/freenet/unkeyedidcreator.cpp -src/freenet/captcha/easybmp src/freenet/captcha/simplecaptcha.cpp src/freenet/captcha/easybmp/EasyBMP.cpp src/freenet/captcha/easybmp/EasyBMP_Font.cpp @@ -81,14 +76,19 @@ src/http/httpthread.cpp src/http/identityexportxml.cpp src/http/ipagehandler.cpp src/http/multipartparser.cpp -src/http/pages src/http/pages/addpeerpage.cpp src/http/pages/announceidentitypage.cpp src/http/pages/boardspage.cpp +src/http/pages/browseboardspage.cpp +src/http/pages/browsemessagespage.cpp src/http/pages/confirmpage.cpp src/http/pages/controlboardpage.cpp src/http/pages/createidentitypage.cpp src/http/pages/execquerypage.cpp +src/http/pages/forumcreatepostpage.cpp +src/http/pages/forummainpage.cpp +src/http/pages/forumthreadspage.cpp +src/http/pages/forumviewthreadpage.cpp src/http/pages/homepage.cpp src/http/pages/insertedfilespage.cpp src/http/pages/localidentitiespage.cpp @@ -98,9 +98,9 @@ src/http/pages/peermaintenancepage.cpp src/http/pages/peertrustpage.cpp src/http/pages/recentlyaddedpage.cpp src/http/pages/showcaptchapage.cpp +src/http/pages/showimagepage.cpp src/http/pages/versioninfopage.cpp src/nntp/extensiontrust.cpp -src/nntp/mime src/nntp/nntpconnection.cpp src/nntp/nntplistener.cpp src/nntp/uwildmat.cpp @@ -211,6 +211,7 @@ IF(NOT WIN32) ENDIF(NOT WIN32) IF(SQLITE3_LIBRARY) + MESSAGE(STATUS "Linking against system SQLite3 library.") TARGET_LINK_LIBRARIES(fms ${SQLITE3_LIBRARY}) ELSE(SQLITE3_LIBRARY) IF(NOT USE_BUNDLED_SQLITE) diff --git a/forum-template.htm b/forum-template.htm new file mode 100644 index 0000000..1877675 --- /dev/null +++ b/forum-template.htm @@ -0,0 +1,217 @@ + + + + + + + +
+ + [CONTENT] + +
+ + + diff --git a/images/new_posts.png b/images/new_posts.png new file mode 100644 index 0000000..cd61b8b Binary files /dev/null and b/images/new_posts.png differ diff --git a/images/no_new_posts.png b/images/no_new_posts.png new file mode 100644 index 0000000..52fde59 Binary files /dev/null and b/images/no_new_posts.png differ diff --git a/include/db/sqlite3db/sqlite3db.h b/include/db/sqlite3db/sqlite3db.h index 470ba85..8c2ee39 100644 --- a/include/db/sqlite3db/sqlite3db.h +++ b/include/db/sqlite3db/sqlite3db.h @@ -18,7 +18,7 @@ class DB:public Singleton { public: DB(); - DB(std::string filename); + DB(const std::string &filename); ~DB(); const bool Open(const std::string &filename); diff --git a/include/db/sqlite3db/sqlite3recordset.h b/include/db/sqlite3db/sqlite3recordset.h index 06c7919..3489130 100644 --- a/include/db/sqlite3db/sqlite3recordset.h +++ b/include/db/sqlite3db/sqlite3recordset.h @@ -14,12 +14,12 @@ public: virtual ~Recordset(); virtual void Free() { if(m_rs) { sqlite3_free_table(m_rs); m_rs=NULL; } } - virtual const bool Empty() { return (m_rs==NULL || m_rows==0) ? true : false ; } + virtual const bool Empty() const { return (m_rs==NULL || m_rows==0) ? true : false ; } - virtual const int Count() { return m_rows; } - virtual const bool AtBeginning() { return m_currentrow==0; } - virtual const bool AtEnd() { return m_currentrow>=m_rows; } - virtual const int Cols() { return m_cols; } + virtual const int Count() const { return m_rows; } + virtual const bool AtBeginning() const { return m_currentrow==0; } + virtual const bool AtEnd() const { return m_currentrow>=m_rows; } + virtual const int Cols() const { return m_cols; } virtual const bool Next() { if(m_currentrow=0) { m_currentrow--; return true; } else { return false; } } diff --git a/include/db/sqlite3db/sqlite3statement.h b/include/db/sqlite3db/sqlite3statement.h index bdca9dc..d245d49 100644 --- a/include/db/sqlite3db/sqlite3statement.h +++ b/include/db/sqlite3db/sqlite3statement.h @@ -57,8 +57,6 @@ private: long m_lastinsertrowid; static std::map m_statementcount; - //std::vector textptrs; - //std::vector > m_boundtext; }; //class diff --git a/include/dbconversions.h b/include/dbconversions.h index 8d090f4..4db308c 100644 --- a/include/dbconversions.h +++ b/include/dbconversions.h @@ -13,6 +13,7 @@ void ConvertDB0109To0110(); void ConvertDB0110To0111(); void ConvertDB0111To0112(); void ConvertDB0112To0113(); +void ConvertDB0113To0114(); // TODO remove sometime after 0.1.17 void FixCapitalBoardNames(); diff --git a/include/freenet/iindexinserter.h b/include/freenet/iindexinserter.h index bb0e9e7..ba5c988 100644 --- a/include/freenet/iindexinserter.h +++ b/include/freenet/iindexinserter.h @@ -73,7 +73,7 @@ void IIndexInserter::FCPConnected() } if(m_fcpuniquename.find("|")!=std::string::npos) { - m_log->fatal("IIndexInserter::FCPConnected fcpuniquename contains | character! This is not a valid character!"); + m_log->fatal("IIndexInserter::FCPConnected fcpuniquename : "+m_fcpuniquename+" contains | character! This is not a valid character!"); } m_inserting.clear(); @@ -91,6 +91,8 @@ const bool IIndexInserter::HandleMessage(FCPMessage &message) if(message["Identifier"].find(m_fcpuniquename)==0) { + m_log->trace("IIndexInserter::HandleMessage "+m_fcpuniquename+" received "+message.GetName()+" ID="+message["Identifier"]+" URI="+message["URI"]); + if(message.GetName()=="URIGenerated") { return true; diff --git a/include/freenet/iindexrequester.h b/include/freenet/iindexrequester.h index 678e43e..6173868 100644 --- a/include/freenet/iindexrequester.h +++ b/include/freenet/iindexrequester.h @@ -14,6 +14,8 @@ #include #include +#include + #ifdef XMEM #include #endif @@ -82,7 +84,7 @@ void IIndexRequester::FCPConnected() } if(m_fcpuniquename.find("|")!=std::string::npos) { - m_log->fatal("IIndexRequester::FCPConnected fcpuniquename contains | character! This is not a valid character!"); + m_log->fatal("IIndexRequester::FCPConnected fcpuniquename "+m_fcpuniquename+" contains | character! This is not a valid character!"); } m_lastreceived=Poco::Timestamp(); @@ -208,11 +210,16 @@ void IIndexRequester::RegisterWithThread(FreenetMasterThread *thread) template void IIndexRequester::RemoveFromRequestList(const IDTYPE id) { +/* typename std::vector::iterator i=m_requesting.begin(); while(i!=m_requesting.end() && (*i)!=id) { i++; } +*/ + // better + typename std::vector::iterator i=std::find(m_requesting.begin(),m_requesting.end(),id); + if(i!=m_requesting.end()) { m_requesting.erase(i); diff --git a/include/freenet/introductionpuzzlerequester.h b/include/freenet/introductionpuzzlerequester.h index 2be2d0e..dc24327 100644 --- a/include/freenet/introductionpuzzlerequester.h +++ b/include/freenet/introductionpuzzlerequester.h @@ -11,9 +11,6 @@ public: IntroductionPuzzleRequester(); IntroductionPuzzleRequester(FCPv2 *fcp); - void FCPDisconnected(); - void FCPConnected(); - private: void Initialize(); void StartRequest(const long &identityid); diff --git a/include/global.h b/include/global.h index acf93ed..aff023f 100644 --- a/include/global.h +++ b/include/global.h @@ -7,10 +7,10 @@ #define VERSION_MAJOR "0" #define VERSION_MINOR "3" -#define VERSION_RELEASE "22" +#define VERSION_RELEASE "23" #define FMS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_RELEASE -#define FMS_FREESITE_USK "USK@0npnMrqZNKRCRoGojZV93UNHCMN-6UU3rRSAmP6jNLE,~BG-edFtdCC1cSH4O3BWdeIYa8Sw5DfyrSV-TKdO5ec,AQACAAE/fms/82/" -#define FMS_VERSION_EDITION "24" +#define FMS_FREESITE_USK "USK@0npnMrqZNKRCRoGojZV93UNHCMN-6UU3rRSAmP6jNLE,~BG-edFtdCC1cSH4O3BWdeIYa8Sw5DfyrSV-TKdO5ec,AQACAAE/fms/84/" +#define FMS_VERSION_EDITION "25" typedef Poco::ScopedLock Guard; diff --git a/include/http/ipagehandler.h b/include/http/ipagehandler.h index 11bdc22..16afb7c 100644 --- a/include/http/ipagehandler.h +++ b/include/http/ipagehandler.h @@ -16,9 +16,9 @@ class IPageHandler:public Poco::Net::HTTPRequestHandler,public ILogger { public: IPageHandler() {} - IPageHandler(const std::string &templatestr) { m_template=templatestr; } + IPageHandler(const std::string &templatestr, const std::string &pagename):m_template(templatestr),m_pagename(pagename) { } virtual ~IPageHandler() {} - virtual const bool WillHandleURI(const std::string &uri)=0; + virtual const bool WillHandleURI(const std::string &uri); virtual IPageHandler *New()=0; // returns a new instance of the object @@ -41,6 +41,7 @@ protected: const std::string SanitizeOutput(const std::string &input); std::string m_template; + std::string m_pagename; }; diff --git a/include/http/pages/addpeerpage.h b/include/http/pages/addpeerpage.h index ac050e2..1425b10 100644 --- a/include/http/pages/addpeerpage.h +++ b/include/http/pages/addpeerpage.h @@ -7,7 +7,7 @@ class AddPeerPage:public IPageHandler,public IDatabase { public: - AddPeerPage(const std::string &templatestr):IPageHandler(templatestr) {} + AddPeerPage(const std::string &templatestr):IPageHandler(templatestr,"addpeer.htm") {} IPageHandler *New() { return new AddPeerPage(m_template); } diff --git a/include/http/pages/announceidentitypage.h b/include/http/pages/announceidentitypage.h index 0ac5be9..b4bf78a 100644 --- a/include/http/pages/announceidentitypage.h +++ b/include/http/pages/announceidentitypage.h @@ -7,7 +7,7 @@ class AnnounceIdentityPage:public IPageHandler,public IDatabase { public: - AnnounceIdentityPage(const std::string &templatestr):IPageHandler(templatestr) {} + AnnounceIdentityPage(const std::string &templatestr):IPageHandler(templatestr,"announceidentity.htm") {} IPageHandler *New() { return new AnnounceIdentityPage(m_template); } diff --git a/include/http/pages/boardspage.h b/include/http/pages/boardspage.h index a8e1c1a..0e4383c 100644 --- a/include/http/pages/boardspage.h +++ b/include/http/pages/boardspage.h @@ -7,7 +7,7 @@ class BoardsPage:public IPageHandler,public IDatabase { public: - BoardsPage(const std::string &templatestr):IPageHandler(templatestr) {} + BoardsPage(const std::string &templatestr):IPageHandler(templatestr,"boards.htm") {} IPageHandler *New() { return new BoardsPage(m_template); } diff --git a/include/http/pages/browseboardspage.h b/include/http/pages/browseboardspage.h new file mode 100644 index 0000000..5a3c266 --- /dev/null +++ b/include/http/pages/browseboardspage.h @@ -0,0 +1,21 @@ +#ifndef _browseboardspage_ +#define _browseboardspage_ + +#include "../ipagehandler.h" +#include "../../idatabase.h" + +class BrowseBoardsPage:public IPageHandler,public IDatabase +{ +public: + BrowseBoardsPage(const std::string &templatestr):IPageHandler(templatestr,"boardsbrowse.htm") {} + + IPageHandler *New() { return new BrowseBoardsPage(m_template); } + +private: + const std::string GeneratePage(const std::string &method, const std::map &queryvars); + + const std::string BuildQueryString(const long startrow, const std::string &boardsearch, const std::string &sortby, const std::string &sortorder); + const std::string ReverseSort(const std::string &sortname, const std::string ¤tsortby, const std::string ¤tsortorder); +}; + +#endif // _browseboardspage_ diff --git a/include/http/pages/browsemessagespage.h b/include/http/pages/browsemessagespage.h new file mode 100644 index 0000000..da67947 --- /dev/null +++ b/include/http/pages/browsemessagespage.h @@ -0,0 +1,19 @@ +#ifndef _browsemessagespage_ +#define _browsemessagespage_ + +#include "../ipagehandler.h" +#include "../../idatabase.h" + +class BrowseMessagesPage:public IPageHandler,public IDatabase +{ +public: + BrowseMessagesPage(const std::string &templatestr):IPageHandler(templatestr,"browsemessages.htm") {} + + IPageHandler *New() { return new BrowseMessagesPage(m_template); } + +private: + const std::string GeneratePage(const std::string &method, const std::map &queryvars); + const std::string BuildQueryString(const long startrow, const std::string &boardidstr, const std::string &messageidstr); +}; + +#endif // _browsemessagespage_ diff --git a/include/http/pages/confirmpage.h b/include/http/pages/confirmpage.h index 2ad4ed9..aaf0c78 100644 --- a/include/http/pages/confirmpage.h +++ b/include/http/pages/confirmpage.h @@ -6,7 +6,7 @@ class ConfirmPage:public IPageHandler { public: - ConfirmPage(const std::string &templatestr):IPageHandler(templatestr) {} + ConfirmPage(const std::string &templatestr):IPageHandler(templatestr,"confirm.htm") {} IPageHandler *New() { return new ConfirmPage(m_template); } diff --git a/include/http/pages/controlboardpage.h b/include/http/pages/controlboardpage.h index 7484989..0f8fcde 100644 --- a/include/http/pages/controlboardpage.h +++ b/include/http/pages/controlboardpage.h @@ -7,7 +7,7 @@ class ControlBoardPage:public IPageHandler,public IDatabase { public: - ControlBoardPage(const std::string &templatestr):IPageHandler(templatestr) {} + ControlBoardPage(const std::string &templatestr):IPageHandler(templatestr,"controlboard.htm") {} IPageHandler *New() { return new ControlBoardPage(m_template); } diff --git a/include/http/pages/createidentitypage.h b/include/http/pages/createidentitypage.h index e6d938c..a1a912f 100644 --- a/include/http/pages/createidentitypage.h +++ b/include/http/pages/createidentitypage.h @@ -7,7 +7,7 @@ class CreateIdentityPage:public IPageHandler,public IDatabase { public: - CreateIdentityPage(const std::string &templatestr):IPageHandler(templatestr) {} + CreateIdentityPage(const std::string &templatestr):IPageHandler(templatestr,"createidentity.htm") {} IPageHandler *New() { return new CreateIdentityPage(m_template); } diff --git a/include/http/pages/execquerypage.h b/include/http/pages/execquerypage.h index 37255b9..caedd08 100644 --- a/include/http/pages/execquerypage.h +++ b/include/http/pages/execquerypage.h @@ -7,7 +7,7 @@ class ExecQueryPage:public IPageHandler,public IDatabase { public: - ExecQueryPage(const std::string &templatestr):IPageHandler(templatestr) {} + ExecQueryPage(const std::string &templatestr):IPageHandler(templatestr,"execquery.htm") {} IPageHandler *New() { return new ExecQueryPage(m_template); } diff --git a/include/http/pages/forumcreatepostpage.h b/include/http/pages/forumcreatepostpage.h new file mode 100644 index 0000000..7f2b592 --- /dev/null +++ b/include/http/pages/forumcreatepostpage.h @@ -0,0 +1,19 @@ +#ifndef _forumcreatepostpage_ +#define _forumcreatepostpage_ + +#include "forumpage.h" + +class ForumCreatePostPage:public ForumPage +{ +public: + ForumCreatePostPage(const std::string &templatestr):ForumPage(templatestr,"forumcreatepost.htm") {} + + IPageHandler *New() { return new ForumCreatePostPage(m_template); } +private: + const std::string GeneratePage(const std::string &method, const std::map &queryvars); + + const std::string LocalIdentityDropDown(const std::string &name, const std::string &selectedid); + +}; + +#endif // _forumcreatepostpage_ diff --git a/include/http/pages/forummainpage.h b/include/http/pages/forummainpage.h new file mode 100644 index 0000000..63af3c5 --- /dev/null +++ b/include/http/pages/forummainpage.h @@ -0,0 +1,17 @@ +#ifndef _forummainpage_ +#define _forummainpage_ + +#include "forumpage.h" + +class ForumMainPage:public ForumPage +{ +public: + ForumMainPage(const std::string &templatestr):ForumPage(templatestr,"forummain.htm") {} + + IPageHandler *New() { return new ForumMainPage(m_template); } + +private: + const std::string GeneratePage(const std::string &method, const std::map &queryvars); +}; + +#endif // _forummainpage_ diff --git a/include/http/pages/forumpage.h b/include/http/pages/forumpage.h new file mode 100644 index 0000000..3124b9e --- /dev/null +++ b/include/http/pages/forumpage.h @@ -0,0 +1,52 @@ +#ifndef _forumpage_ +#define _forumpage_ + +#include "../ipagehandler.h" +#include "../../idatabase.h" + +class ForumPage:public IPageHandler,public IDatabase +{ +public: + ForumPage(const std::string &templatestr, const std::string &pagename):IPageHandler(templatestr,pagename) {} + + virtual IPageHandler *New()=0; // returns a new instance of the object + +protected: + const std::string FixFromName(const std::string &fromname) + { + std::string tempname=fromname; + if(tempname.size()>30) + { + tempname.erase(27); + tempname+="..."; + } + tempname=SanitizeOutput(tempname); + return tempname; + } + + const std::string FixSubject(const std::string &subject) + { + std::string tempsubject=subject; + if(tempsubject.size()>30) + { + tempsubject.erase(27); + tempsubject+="..."; + } + tempsubject=SanitizeOutput(tempsubject); + return tempsubject; + } + + const std::string CreateForumHeader() + { + std::string content="\r\n"; + content+="\r\n"; + content+="
Home | Browse Forums
\r\n"; + return content; + } + +private: + virtual const std::string GeneratePage(const std::string &method, const std::map &queryvars)=0; + +}; + +#endif // _forumpage_ diff --git a/include/http/pages/forumthreadspage.h b/include/http/pages/forumthreadspage.h new file mode 100644 index 0000000..71131c1 --- /dev/null +++ b/include/http/pages/forumthreadspage.h @@ -0,0 +1,17 @@ +#ifndef _forumthreads_page_ +#define _forumthreads_page_ + +#include "forumpage.h" + +class ForumThreadsPage:public ForumPage +{ +public: + ForumThreadsPage(const std::string &templatestr):ForumPage(templatestr,"forumthreads.htm") {} + + IPageHandler *New() { return new ForumThreadsPage(m_template); } + +private: + const std::string GeneratePage(const std::string &method, const std::map &queryvars); +}; + +#endif // _forumthreads_page_ diff --git a/include/http/pages/forumviewthreadpage.h b/include/http/pages/forumviewthreadpage.h new file mode 100644 index 0000000..78c2e2c --- /dev/null +++ b/include/http/pages/forumviewthreadpage.h @@ -0,0 +1,19 @@ +#ifndef _forumviewthreadpage_ +#define _forumviewthreadpage_ + +#include "forumpage.h" + +class ForumViewThreadPage:public ForumPage +{ +public: + ForumViewThreadPage(const std::string &templatestr):ForumPage(templatestr,"forumviewthread.htm") {} + + IPageHandler *New() { return new ForumViewThreadPage(m_template); } +private: + const std::string GeneratePage(const std::string &method, const std::map &queryvars); + + const std::string FixBody(const std::string &body); + +}; + +#endif // _forumviewthreadpage_ diff --git a/include/http/pages/homepage.h b/include/http/pages/homepage.h index 1a4b832..0b8c5e2 100644 --- a/include/http/pages/homepage.h +++ b/include/http/pages/homepage.h @@ -7,7 +7,7 @@ class HomePage:public IPageHandler,public IDatabase { public: - HomePage(const std::string &templatestr):IPageHandler(templatestr) {} + HomePage(const std::string &templatestr):IPageHandler(templatestr,"index.htm") {} IPageHandler *New() { return new HomePage(m_template); } diff --git a/include/http/pages/insertedfilespage.h b/include/http/pages/insertedfilespage.h index 80c4b0e..d9d4832 100644 --- a/include/http/pages/insertedfilespage.h +++ b/include/http/pages/insertedfilespage.h @@ -7,7 +7,7 @@ class InsertedFilesPage:public IPageHandler,public IDatabase { public: - InsertedFilesPage(const std::string &templatestr):IPageHandler(templatestr) {} + InsertedFilesPage(const std::string &templatestr):IPageHandler(templatestr,"insertedfiles.htm") {} IPageHandler *New() { return new InsertedFilesPage(m_template); } diff --git a/include/http/pages/localidentitiespage.h b/include/http/pages/localidentitiespage.h index d994fd2..162777c 100644 --- a/include/http/pages/localidentitiespage.h +++ b/include/http/pages/localidentitiespage.h @@ -7,7 +7,7 @@ class LocalIdentitiesPage:public IPageHandler,public IDatabase { public: - LocalIdentitiesPage(const std::string &templatestr):IPageHandler(templatestr) {} + LocalIdentitiesPage(const std::string &templatestr):IPageHandler(templatestr,"localidentities.htm") {} IPageHandler *New() { return new LocalIdentitiesPage(m_template); } diff --git a/include/http/pages/optionspage.h b/include/http/pages/optionspage.h index 447b00f..9589205 100644 --- a/include/http/pages/optionspage.h +++ b/include/http/pages/optionspage.h @@ -7,7 +7,7 @@ class OptionsPage:public IPageHandler,public IDatabase { public: - OptionsPage(const std::string &templatestr):IPageHandler(templatestr) {} + OptionsPage(const std::string &templatestr):IPageHandler(templatestr,"options.htm") {} IPageHandler *New() { return new OptionsPage(m_template); } diff --git a/include/http/pages/peerdetailspage.h b/include/http/pages/peerdetailspage.h index 20d9149..1c69303 100644 --- a/include/http/pages/peerdetailspage.h +++ b/include/http/pages/peerdetailspage.h @@ -7,7 +7,7 @@ class PeerDetailsPage:public IPageHandler,public IDatabase { public: - PeerDetailsPage(const std::string templatestr):IPageHandler(templatestr) {} + PeerDetailsPage(const std::string templatestr):IPageHandler(templatestr,"peerdetails.htm") {} IPageHandler *New() { return new PeerDetailsPage(m_template); } diff --git a/include/http/pages/peermaintenancepage.h b/include/http/pages/peermaintenancepage.h index 95e4966..efacffa 100644 --- a/include/http/pages/peermaintenancepage.h +++ b/include/http/pages/peermaintenancepage.h @@ -7,7 +7,7 @@ class PeerMaintenancePage:public IPageHandler,public IDatabase { public: - PeerMaintenancePage(const std::string &templatestr):IPageHandler(templatestr) {} + PeerMaintenancePage(const std::string &templatestr):IPageHandler(templatestr,"peermaintenance.htm") {} IPageHandler *New() { return new PeerMaintenancePage(m_template); } diff --git a/include/http/pages/peertrustpage.h b/include/http/pages/peertrustpage.h index cce9ae6..a62ad68 100644 --- a/include/http/pages/peertrustpage.h +++ b/include/http/pages/peertrustpage.h @@ -7,12 +7,11 @@ class PeerTrustPage:public IPageHandler,public IDatabase { public: - PeerTrustPage(const std::string &templatestr):IPageHandler(templatestr) {} + PeerTrustPage(const std::string &templatestr):IPageHandler(templatestr,"peertrust.htm") {} IPageHandler *New() { return new PeerTrustPage(m_template); } private: - const bool WillHandleURI(const std::string &uri); const std::string GeneratePage(const std::string &method, const std::map &queryvars); const std::string GetClassString(const std::string &trustlevel); diff --git a/include/http/pages/recentlyaddedpage.h b/include/http/pages/recentlyaddedpage.h index ec9c1cc..9f00760 100644 --- a/include/http/pages/recentlyaddedpage.h +++ b/include/http/pages/recentlyaddedpage.h @@ -7,12 +7,11 @@ class RecentlyAddedPage:public IPageHandler,public IDatabase { public: - RecentlyAddedPage(const std::string &templatestr):IPageHandler(templatestr) {} + RecentlyAddedPage(const std::string &templatestr):IPageHandler(templatestr,"recentlyadded.htm") {} IPageHandler *New() { return new RecentlyAddedPage(m_template); } private: - const bool WillHandleURI(const std::string &uri); const std::string GeneratePage(const std::string &method, const std::map &queryvars); }; diff --git a/include/http/pages/showimagepage.h b/include/http/pages/showimagepage.h new file mode 100644 index 0000000..2c8c648 --- /dev/null +++ b/include/http/pages/showimagepage.h @@ -0,0 +1,22 @@ +#ifndef _showimagepage_ +#define _showimagepage_ + +#include "../ipagehandler.h" + +class ShowImagePage:public IPageHandler +{ +public: + + void handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response); + + IPageHandler *New() { return new ShowImagePage; } + +private: + const bool WillHandleURI(const std::string &uri); + const std::string GeneratePage(const std::string &method, const std::map &queryvars) {return "";} + + static std::map > m_imagecache; + +}; + +#endif // _showcaptchapage_ diff --git a/include/http/pages/versioninfopage.h b/include/http/pages/versioninfopage.h index 1d87554..9f22d4e 100644 --- a/include/http/pages/versioninfopage.h +++ b/include/http/pages/versioninfopage.h @@ -7,12 +7,11 @@ class VersionInfoPage:public IPageHandler,public IDatabase { public: - VersionInfoPage(const std::string &templatestr):IPageHandler(templatestr) {} + VersionInfoPage(const std::string &templatestr):IPageHandler(templatestr,"versioninfo.htm") {} IPageHandler *New() { return new VersionInfoPage(m_template); } private: - const bool WillHandleURI(const std::string &uri); const std::string GeneratePage(const std::string &method, const std::map &queryvars); }; diff --git a/include/message.h b/include/message.h index cfc8734..8c56633 100644 --- a/include/message.h +++ b/include/message.h @@ -46,6 +46,7 @@ public: const bool Load(const std::string &messageuuid); const bool ParseNNTPMessage(const std::string &nntpmessage); + const bool Create(const long localidentityid, const long boardid, const std::string &subject, const std::string &body, const std::string &references); const bool PostedToAdministrationBoard() { return CheckForAdministrationBoard(m_boards); } diff --git a/include/messagethread.h b/include/messagethread.h new file mode 100644 index 0000000..0dfe628 --- /dev/null +++ b/include/messagethread.h @@ -0,0 +1,41 @@ +#ifndef _messagethread_ +#define _messagethread_ + +#include "idatabase.h" + +class MessageThread:public IDatabase +{ +public: + struct threadnode + { + long m_messageid; + long m_level; + std::string m_subject; + std::string m_fromname; + std::string m_date; + }; + + void Clear() { m_nodes.clear(); } + + const bool Load(const std::string &messageidstr, const long boardid, const bool bydate=false); + const bool Load(const long messageid, const long boardid, const bool bydate=false); + + const std::vector GetNodes() { return m_nodes; } + +private: + const threadnode GetOriginalMessageNode(const long messageid, const long boardid); + void AddChildren(const long messageid, const long level, const long boardid); + + class datecompare + { + public: + const bool operator()(const threadnode &node1, const threadnode &node2) const + { + return node1.m_date m_nodes; +}; + +#endif // _messagethread_ diff --git a/include/threadbuilder.h b/include/threadbuilder.h new file mode 100644 index 0000000..5c0fc42 --- /dev/null +++ b/include/threadbuilder.h @@ -0,0 +1,16 @@ +#ifndef _threadbuilder_ +#define _threadbuilder_ + +#include "idatabase.h" + +class ThreadBuilder:public IDatabase +{ +public: + + const bool Build(const long messageid, const long boardid, const bool bydate=false); + +private: + +}; + +#endif // _threadbuilder_ diff --git a/src/db/sqlite3db.cpp b/src/db/sqlite3db.cpp index 86a4f87..f8bb003 100644 --- a/src/db/sqlite3db.cpp +++ b/src/db/sqlite3db.cpp @@ -12,7 +12,7 @@ DB::DB() Initialize(); } -DB::DB(std::string filename) +DB::DB(const std::string &filename) { Initialize(); Open(filename); @@ -22,7 +22,7 @@ DB::~DB() { if(IsOpen()) { - Close(); + Close(); } } @@ -39,12 +39,12 @@ const bool DB::Close() } else { - return false; + return false; } } else { - return false; + return false; } } @@ -60,7 +60,7 @@ const bool DB::Execute(const std::string &sql) } else { - return false; + return false; } } else @@ -82,7 +82,7 @@ const bool DB::ExecuteInsert(const std::string &sql, long &insertid) } else { - return false; + return false; } } else @@ -106,7 +106,7 @@ const int DB::GetLastError(std::string &errormessage) } else { - return SQLITE_OK; + return SQLITE_OK; } } @@ -119,7 +119,7 @@ void DB::Initialize() const bool DB::IsOpen() { Poco::ScopedLock g(m_mutex); - return m_db ? true : false; + return m_db ? true : false; } const bool DB::Open(const std::string &filename) @@ -138,12 +138,12 @@ const bool DB::Open(const std::string &filename) } else { - return false; + return false; } } else { - return false; + return false; } } diff --git a/src/db/sqlite3statement.cpp b/src/db/sqlite3statement.cpp index 789afb1..31c6ea5 100644 --- a/src/db/sqlite3statement.cpp +++ b/src/db/sqlite3statement.cpp @@ -9,63 +9,36 @@ namespace SQLite3DB std::map Statement::m_statementcount; -Statement::Statement() +Statement::Statement():m_statement(0),m_parametercount(0),m_resultcolumncount(0),m_rowreturned(false),m_lastinsertrowid(-1) { - m_statement=NULL; - m_parametercount=0; - m_resultcolumncount=0; - m_rowreturned=false; - m_lastinsertrowid=-1; + } -Statement::Statement(sqlite3_stmt *statement) +Statement::Statement(sqlite3_stmt *statement):m_statement(statement),m_rowreturned(false),m_lastinsertrowid(-1) { - m_statement=statement; m_parametercount=sqlite3_bind_parameter_count(m_statement); m_resultcolumncount=sqlite3_column_count(m_statement); - m_rowreturned=false; - m_lastinsertrowid=-1; - + if(m_statement) { m_statementcount[m_statement]++; } } -Statement::Statement(const Statement &rhs) +Statement::Statement(const Statement &rhs):m_statement(0),m_parametercount(0),m_resultcolumncount(0),m_rowreturned(false),m_lastinsertrowid(-1) { - m_statement=NULL; - m_parametercount=0; - m_resultcolumncount=0; - m_rowreturned=false; - m_lastinsertrowid=-1; *this=rhs; } Statement::~Statement() { - Finalize(); - - /* - std::vector::iterator i; - for(i=textptrs.begin(); i!=textptrs.end(); i++) - { - if((*i)) - { - delete [] (*i); - } - } - */ - } const bool Statement::Bind(const int column) { if(Valid() && column>=0 && column g(DB::instance()->m_mutex); - //PThread::Guard g(DB::Instance()->m_mutex); if(sqlite3_bind_null(m_statement,column+1)==SQLITE_OK) { return true; @@ -85,8 +58,6 @@ const bool Statement::Bind(const int column, const int value) { if(Valid() && column>=0 && column g(DB::instance()->m_mutex); - //PThread::Guard g(DB::Instance()->m_mutex); if(sqlite3_bind_int(m_statement,column+1,value)==SQLITE_OK) { return true; @@ -106,8 +77,6 @@ const bool Statement::Bind(const int column, const double value) { if(Valid() && column>=0 && column g(DB::instance()->m_mutex); - //PThread::Guard g(DB::Instance()->m_mutex); if(sqlite3_bind_double(m_statement,column+1,value)==SQLITE_OK) { return true; @@ -127,8 +96,6 @@ const bool Statement::Bind(const int column, const std::string &value) { if(Valid() && column>=0 && column g(DB::instance()->m_mutex); - //PThread::Guard g(DB::Instance()->m_mutex); if(sqlite3_bind_text(m_statement,column+1,value.c_str(),value.size(),SQLITE_TRANSIENT)==SQLITE_OK) { return true; @@ -148,8 +115,6 @@ const bool Statement::Bind(const int column, const void *data, const int length) { if(Valid() && column>=0 && column g(DB::instance()->m_mutex); - //PThread::Guard g(DB::Instance()->m_mutex); if(sqlite3_bind_blob(m_statement,column+1,data,length,SQLITE_TRANSIENT)==SQLITE_OK) { return true; @@ -190,6 +155,7 @@ Statement &Statement::operator=(const Statement &rhs) m_parametercount=rhs.m_parametercount; m_resultcolumncount=rhs.m_resultcolumncount; m_rowreturned=rhs.m_rowreturned; + m_lastinsertrowid=rhs.m_lastinsertrowid; if(m_statement) { diff --git a/src/dbconversions.cpp b/src/dbconversions.cpp index 1fa11cd..b0cb73e 100644 --- a/src/dbconversions.cpp +++ b/src/dbconversions.cpp @@ -233,6 +233,16 @@ void ConvertDB0112To0113() db->Execute("UPDATE tblDBVersion SET Major=1, Minor=13;"); } +void ConvertDB0113To0114() +{ + SQLite3DB::DB *db=SQLite3DB::DB::Instance(); + + db->Execute("ALTER TABLE tblBoard ADD COLUMN Forum TEXT CHECK(Forum IN ('true','false')) DEFAULT 'false';"); + db->Execute("ALTER TABLE tblMessage ADD COLUMN Read INTEGER CHECK(Read IN (0,1)) DEFAULT 0;"); + + db->Execute("UPDATE tblDBVersion SET Major=1, Minor=14;"); +} + void FixCapitalBoardNames() { SQLite3DB::DB *db=SQLite3DB::DB::Instance(); diff --git a/src/dbmaintenancethread.cpp b/src/dbmaintenancethread.cpp index f8c3357..3f4bdbc 100644 --- a/src/dbmaintenancethread.cpp +++ b/src/dbmaintenancethread.cpp @@ -1,6 +1,7 @@ #include "../include/dbmaintenancethread.h" #include "../include/stringfunctions.h" #include "../include/option.h" +#include "../include/threadbuilder.h" #include #include @@ -36,12 +37,62 @@ DBMaintenanceThread::DBMaintenanceThread() void DBMaintenanceThread::Do10MinuteMaintenance() { + ThreadBuilder tb; + SQLite3DB::Statement boardst=m_db->Prepare("SELECT BoardID FROM tblBoard WHERE Forum='true';"); + // select messages for a board that aren't in a thread + SQLite3DB::Statement selectst=m_db->Prepare("SELECT tblMessage.MessageID FROM tblMessage \ + INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID\ + LEFT JOIN tblThreadPost ON tblMessage.MessageID=tblThreadPost.MessageID \ + LEFT JOIN tblThread ON tblThreadPost.ThreadID=tblThread.ThreadID\ + WHERE tblMessageBoard.BoardID=? AND tblThread.BoardID IS NULL;"); + + boardst.Step(); + while(boardst.RowReturned()) + { + int boardid=-1; + + boardst.ResultInt(0,boardid); + + selectst.Bind(0,boardid); + selectst.Step(); + + while(selectst.RowReturned()) + { + int messageid=-1; + + selectst.ResultInt(0,messageid); + + tb.Build(messageid,boardid,true); + + selectst.Step(); + } + selectst.Reset(); + + boardst.Step(); + } + + // now rebuild threads where the message has been deleted + SQLite3DB::Statement st=m_db->Prepare("SELECT tblThreadPost.MessageID, tblThread.BoardID FROM tblThreadPost INNER JOIN tblThread ON tblThreadPost.ThreadID=tblThread.ThreadID LEFT JOIN tblMessage ON tblThreadPost.MessageID=tblMessage.MessageID WHERE tblMessage.MessageID IS NULL;"); + st.Step(); + while(st.RowReturned()) + { + int messageid=-1; + int boardid=-1; + + st.ResultInt(0,messageid); + st.ResultInt(1,boardid); + + tb.Build(messageid,boardid,true); + + st.Step(); + } + m_log->debug("PeriodicDBMaintenance::Do10MinuteMaintenance"); } void DBMaintenanceThread::Do30MinuteMaintenance() { - + // UNCOMMENT method in run when code is placed here m_log->debug("PeriodicDBMaintenance::Do30MinuteMaintenance"); } @@ -283,6 +334,7 @@ void DBMaintenanceThread::run() m_log->debug("DBMaintenanceThread::run thread started."); Poco::DateTime now; + int i=0; do { @@ -293,11 +345,13 @@ void DBMaintenanceThread::run() Do10MinuteMaintenance(); m_last10minute=Poco::Timestamp(); } + /* if((m_last30minute+Poco::Timespan(0,0,30,0,0))<=now) { Do30MinuteMaintenance(); m_last30minute=Poco::Timestamp(); } + */ if((m_last1hour+Poco::Timespan(0,1,0,0,0))<=now) { Do1HourMaintenance(); @@ -314,7 +368,12 @@ void DBMaintenanceThread::run() m_last1day=Poco::Timestamp(); } - Poco::Thread::sleep(1000); + i=0; + while(i++<5 && !IsCancelled()) + { + Poco::Thread::sleep(1000); + } + }while(!IsCancelled()); m_log->debug("DBMaintenanceThread::run thread exiting."); diff --git a/src/dbsetup.cpp b/src/dbsetup.cpp index 5f4c129..1b037f7 100644 --- a/src/dbsetup.cpp +++ b/src/dbsetup.cpp @@ -104,13 +104,19 @@ void SetupDB() major=1; minor=13; } + if(major==1 && minor==13) + { + ConvertDB0113To0114(); + major=1; + minor=14; + } } else { - db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,13);"); + db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,14);"); } - db->Execute("UPDATE tblDBVersion SET Major=1, Minor=13;"); + db->Execute("UPDATE tblDBVersion SET Major=1, Minor=14;"); db->Execute("CREATE TABLE IF NOT EXISTS tblFMSVersion(\ Major INTEGER,\ @@ -283,13 +289,14 @@ void SetupDB() BoardDescription TEXT,\ DateAdded DATETIME,\ SaveReceivedMessages BOOL CHECK(SaveReceivedMessages IN('true','false')) DEFAULT 'true',\ - AddedMethod TEXT\ + AddedMethod TEXT,\ + Forum TEXT CHECK(Forum IN('true','false')) DEFAULT 'false'\ );"); - db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('fms','Freenet Message System','2007-12-01 12:00:00','Initial Board');"); - db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('freenet','Discussion about Freenet','2007-12-01 12:00:00','Initial Board');"); - db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('public','Public discussion','2007-12-01 12:00:00','Initial Board');"); - db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('test','Test board','2007-12-01 12:00:00','Initial Board');"); + db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod,Forum) VALUES('fms','Freenet Message System','2007-12-01 12:00:00','Initial Board','true');"); + db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod,Forum) VALUES('freenet','Discussion about Freenet','2007-12-01 12:00:00','Initial Board','true');"); + db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod,Forum) VALUES('public','Public discussion','2007-12-01 12:00:00','Initial Board','true');"); + db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod,Forum) VALUES('test','Test board','2007-12-01 12:00:00','Initial Board','true');"); db->Execute("CREATE TABLE IF NOT EXISTS tblMessage(\ MessageID INTEGER PRIMARY KEY,\ @@ -301,7 +308,8 @@ void SetupDB() MessageUUID TEXT UNIQUE,\ ReplyBoardID INTEGER,\ Body TEXT,\ - MessageIndex INTEGER\ + MessageIndex INTEGER,\ + Read INTEGER CHECK(Read IN(0,1)) DEFAULT 0\ );"); db->Execute("CREATE INDEX IF NOT EXISTS idxMessage_IdentityID ON tblMessage (IdentityID);"); @@ -313,6 +321,7 @@ void SetupDB() );"); db->Execute("CREATE INDEX IF NOT EXISTS idxMessageReplyTo_MessageID ON tblMessageReplyTo (MessageID);"); + db->Execute("CREATE INDEX IF NOT EXISTS idxMessageReplyTo_ReplyToMessageUUID ON tblMessageReplyTo (ReplyToMessageUUID);"); db->Execute("CREATE TABLE IF NOT EXISTS tblMessageBoard(\ MessageID INTEGER,\ @@ -389,7 +398,35 @@ void SetupDB() Day DATE,\ RequestIndex INTEGER,\ Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\ - );"); + );"); + + // begin thread db schema + db->Execute("CREATE TABLE IF NOT EXISTS tblThread(\ + ThreadID INTEGER PRIMARY KEY,\ + BoardID INTEGER,\ + FirstMessageID INTEGER,\ + LastMessageID INTEGER\ + );"); + + db->Execute("CREATE INDEX IF NOT EXISTS idxThread_BoardID ON tblThread(BoardID);"); + db->Execute("CREATE INDEX IF NOT EXISTS idxThread_FirstMessageID ON tblThread(FirstMessageID);"); + db->Execute("CREATE INDEX IF NOT EXISTS idxThread_LastMessageID ON tblThread(LastMessageID);"); + + db->Execute("CREATE TABLE IF NOT EXISTS tblThreadPost(\ + ThreadID INTEGER,\ + MessageID INTEGER,\ + PostOrder INTEGER\ + );"); + + db->Execute("CREATE INDEX IF NOT EXISTS idxThreadPost_ThreadID ON tblThreadPost(ThreadID);"); + db->Execute("CREATE INDEX IF NOT EXISTS idxThreadPost_MessageID ON tblThreadPost(MessageID);"); + + db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteOnThread AFTER DELETE ON tblThread\ + FOR EACH ROW\ + BEGIN\ + DELETE FROM tblThreadPost WHERE ThreadID=old.ThreadID;\ + END;"); + // end thread db schema // MessageInserter will insert a record into this temp table which the MessageListInserter will query for and insert a MessageList when needed db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpMessageListInsert(\ diff --git a/src/fmsapp.cpp b/src/fmsapp.cpp index 01fcf9a..9737299 100644 --- a/src/fmsapp.cpp +++ b/src/fmsapp.cpp @@ -262,6 +262,10 @@ void FMSApp::StartThreads() { logger().trace("FMSApp::StartThreads starting HTTPThread"); m_threads.Start(new HTTPThread()); + if(isInteractive()) + { + std::cout << "Started HTTP Thread" << std::endl; + } } else { @@ -274,6 +278,10 @@ void FMSApp::StartThreads() { logger().trace("FMSApp::StartThreads starting NNTPListener"); m_threads.Start(new NNTPListener()); + if(isInteractive()) + { + std::cout << "Started NNTP Thread" << std::endl; + } } else { @@ -286,6 +294,10 @@ void FMSApp::StartThreads() { logger().trace("FMSApp::StartThreads starting FreenetMasterThread"); m_threads.Start(new FreenetMasterThread()); + if(isInteractive()) + { + std::cout << "Started Freenet FCP Thread" << std::endl; + } } else { diff --git a/src/freenet/introductionpuzzlerequester.cpp b/src/freenet/introductionpuzzlerequester.cpp index c1efe0f..80aacb1 100644 --- a/src/freenet/introductionpuzzlerequester.cpp +++ b/src/freenet/introductionpuzzlerequester.cpp @@ -24,17 +24,6 @@ IntroductionPuzzleRequester::IntroductionPuzzleRequester(FCPv2 *fcp):IIndexReque Initialize(); } -void IntroductionPuzzleRequester::FCPConnected() -{ - m_requesting.clear(); - PopulateIDList(); -} - -void IntroductionPuzzleRequester::FCPDisconnected() -{ - -} - const bool IntroductionPuzzleRequester::HandleAllData(FCPMessage &message) { Poco::DateTime now; diff --git a/src/freenet/messageinserter.cpp b/src/freenet/messageinserter.cpp index 0c03204..d248cd3 100644 --- a/src/freenet/messageinserter.cpp +++ b/src/freenet/messageinserter.cpp @@ -65,6 +65,8 @@ const bool MessageInserter::HandlePutFailed(FCPMessage &message) st.Step(); } + m_log->trace("MessageInserter::HandlePutFailed error code "+message["Code"]+" fatal="+message["Fatal"]); + RemoveFromInsertList(idparts[1]); return true; diff --git a/src/freenet/messagelistinserter.cpp b/src/freenet/messagelistinserter.cpp index 9307b19..aa1e814 100644 --- a/src/freenet/messagelistinserter.cpp +++ b/src/freenet/messagelistinserter.cpp @@ -168,7 +168,7 @@ const bool MessageListInserter::StartInsert(const long &localidentityid) date-=Poco::Timespan(m_daysbackward,0,0,0,0); StringFunctions::Convert(localidentityid,localidentityidstr); - SQLite3DB::Statement st=m_db->Prepare("SELECT Day, InsertIndex, MessageXML, PrivateKey FROM tblMessageInserts INNER JOIN tblLocalIdentity ON tblMessageInserts.LocalIdentityID=tblLocalIdentity.LocalIdentityID WHERE tblLocalIdentity.LocalIdentityID=? AND Day>=?;"); + SQLite3DB::Statement st=m_db->Prepare("SELECT Day, InsertIndex, MessageXML, PrivateKey FROM tblMessageInserts INNER JOIN tblLocalIdentity ON tblMessageInserts.LocalIdentityID=tblLocalIdentity.LocalIdentityID WHERE tblLocalIdentity.LocalIdentityID=? AND Day>=? AND tblMessageInserts.MessageUUID IS NOT NULL;"); st.Bind(0,localidentityid); st.Bind(1,Poco::DateTimeFormatter::format(date,"%Y-%m-%d")); st.Step(); diff --git a/src/http/fmshttprequesthandlerfactory.cpp b/src/http/fmshttprequesthandlerfactory.cpp index 6adb09f..c4606c0 100644 --- a/src/http/fmshttprequesthandlerfactory.cpp +++ b/src/http/fmshttprequesthandlerfactory.cpp @@ -18,6 +18,13 @@ #include "../../include/http/pages/peertrustpage.h" #include "../../include/http/pages/versioninfopage.h" #include "../../include/http/pages/recentlyaddedpage.h" +#include "../../include/http/pages/browseboardspage.h" +#include "../../include/http/pages/browsemessagespage.h" +#include "../../include/http/pages/forummainpage.h" +#include "../../include/http/pages/showimagepage.h" +#include "../../include/http/pages/forumthreadspage.h" +#include "../../include/http/pages/forumviewthreadpage.h" +#include "../../include/http/pages/forumcreatepostpage.h" FMSHTTPRequestHandlerFactory::FMSHTTPRequestHandlerFactory() { @@ -39,6 +46,24 @@ FMSHTTPRequestHandlerFactory::FMSHTTPRequestHandlerFactory() m_log->error("HTTPThread::HTTPThread could not open template.htm"); } + // load forum template + std::string forumtemplate="Home

Could not open forum-template.htm! Place in program directory and restart!


[CONTENT]"; + infile=fopen("forum-template.htm","rb"); + if(infile) + { + fseek(infile,0,SEEK_END); + long len=ftell(infile); + std::vector data(len,0); + fseek(infile,0,SEEK_SET); + fread(&data[0],1,len,infile); + fclose(infile); + forumtemplate.assign(data.begin(),data.end()); + } + else + { + m_log->error("HTTPThread::HTTPThread could not open forum-template.htm"); + } + // push back page handlers m_pagehandlers.push_back(new OptionsPage(templatestr)); m_pagehandlers.push_back(new CreateIdentityPage(templatestr)); @@ -56,6 +81,13 @@ FMSHTTPRequestHandlerFactory::FMSHTTPRequestHandlerFactory() m_pagehandlers.push_back(new PeerTrustPage(templatestr)); m_pagehandlers.push_back(new VersionInfoPage(templatestr)); m_pagehandlers.push_back(new RecentlyAddedPage(templatestr)); + m_pagehandlers.push_back(new BrowseBoardsPage(templatestr)); + m_pagehandlers.push_back(new BrowseMessagesPage(templatestr)); + m_pagehandlers.push_back(new ShowImagePage()); + m_pagehandlers.push_back(new ForumMainPage(forumtemplate)); + m_pagehandlers.push_back(new ForumThreadsPage(forumtemplate)); + m_pagehandlers.push_back(new ForumViewThreadPage(forumtemplate)); + m_pagehandlers.push_back(new ForumCreatePostPage(forumtemplate)); // homepage must be last - catch all page handler m_pagehandlers.push_back(new HomePage(templatestr)); diff --git a/src/http/ipagehandler.cpp b/src/http/ipagehandler.cpp index c9e4a1a..52e96f6 100644 --- a/src/http/ipagehandler.cpp +++ b/src/http/ipagehandler.cpp @@ -197,3 +197,15 @@ const bool IPageHandler::ValidateFormPassword(const std::map
Select Identity : "; content+=CreateLocalIdentityDropDown("localidentityid",""); content+=""; - content+="
Type the answers of a few of the following puzzles. You don't need to get them all correct, but remember that they are case sensitive. Getting announced will take some time. DO NOT continuously solve captchas. Solve 30 at most, wait a day, and if your identity has not been announced, repeat until it is."; + content+="
Type the answers of a few of the following puzzles. You don't need to get them all correct, but remember that they are case sensitive. Getting announced will take some time and you must assign trust to other identities to see yourself announced. DO NOT continuously solve captchas. Solve 30 at most, wait a day, and if your identity has not been announced, repeat until it is."; content+=""; date-=Poco::Timespan(1,0,0,0,0); @@ -98,7 +98,7 @@ const std::string AnnounceIdentityPage::GeneratePage(const std::string &method, if(st.RowReturned()==false) { - content+="
You must wait for some puzzles to be downloaded. Check back later."; + content+="
You must wait for some puzzles to be downloaded. Make sure you have assigned trust to some other identities' trust lists and check back later."; } while(st.RowReturned() && shown<20) diff --git a/src/http/pages/boardspage.cpp b/src/http/pages/boardspage.cpp index e9cc2a3..397aefa 100644 --- a/src/http/pages/boardspage.cpp +++ b/src/http/pages/boardspage.cpp @@ -75,23 +75,29 @@ const std::string BoardsPage::GeneratePage(const std::string &method, const std: std::vector descriptions; std::vector oldsavemessages; std::vector savemessages; + std::vector oldforums; + std::vector forums; CreateArgArray(queryvars,"boardid",boardids); CreateArgArray(queryvars,"oldboarddescription",olddescriptions); CreateArgArray(queryvars,"boarddescription",descriptions); CreateArgArray(queryvars,"oldsavereceivedmessages",oldsavemessages); CreateArgArray(queryvars,"savereceivedmessages",savemessages); + CreateArgArray(queryvars,"oldforum",oldforums); + CreateArgArray(queryvars,"forum",forums); olddescriptions.resize(boardids.size(),""); descriptions.resize(boardids.size(),""); oldsavemessages.resize(boardids.size(),""); savemessages.resize(boardids.size(),""); + oldforums.resize(boardids.size(),""); + forums.resize(boardids.size(),""); - SQLite3DB::Statement updatest=m_db->Prepare("UPDATE tblBoard SET BoardDescription=?, SaveReceivedMessages=? WHERE BoardID=?;"); + SQLite3DB::Statement updatest=m_db->Prepare("UPDATE tblBoard SET BoardDescription=?, SaveReceivedMessages=?, Forum=? WHERE BoardID=?;"); for(int i=0; i"; content+=""; content+="
"; @@ -190,7 +204,7 @@ const std::string BoardsPage::GeneratePage(const std::string &method, const std: content+="
"+CreateFormPassword()+""; content+=""; - content+="NameDescriptionSave Received Messages *Added Method"; + content+="NameDescriptionSave Received Messages *ForumAdded Method"; content+=""; while(st.RowReturned() && rownum"+SanitizeOutput(addedmethod)+""; + content+=""; + content+=""; + content+=""; content+="\r\n"; st.Step(); rownum++; @@ -238,17 +263,17 @@ const std::string BoardsPage::GeneratePage(const std::string &method, const std: if(startrow>0) { StringFunctions::Convert(startrow-rowsperpage,tempstr); - content+="<-- Previous Page"; - cols+=1; + content+="<-- Previous Page"; + cols+=2; } if(startrow+rowsperpageNext Page -->"; + content+="Next Page -->"; } content+=""; } diff --git a/src/http/pages/browseboardspage.cpp b/src/http/pages/browseboardspage.cpp new file mode 100644 index 0000000..e759cd6 --- /dev/null +++ b/src/http/pages/browseboardspage.cpp @@ -0,0 +1,212 @@ +#include "../../../include/http/pages/browseboardspage.h" +#include "../../../include/stringfunctions.h" + +#ifdef XMEM + #include +#endif + +const std::string BrowseBoardsPage::BuildQueryString(const long startrow, const std::string &boardsearch, const std::string &sortby, const std::string &sortorder) +{ + std::string returnval=""; + std::string tempval=""; + + if(startrow>=0) + { + StringFunctions::Convert(startrow,tempval); + returnval+="startrow="+tempval; + } + + if(boardsearch!="") + { + if(returnval!="") + { + returnval+="&"; + } + returnval+="boardsearch="+boardsearch; + } + + if(sortby!="") + { + if(returnval!="") + { + returnval+="&"; + } + returnval+="sortby="+sortby; + if(sortorder=="ASC" || sortorder=="DESC") + { + if(returnval!="") + { + returnval+="&"; + } + returnval+="sortorder="+sortorder; + } + else + { + if(returnval!="") + { + returnval+="&"; + } + returnval+="sortorder=ASC"; + } + } + + return returnval; + +} + +const std::string BrowseBoardsPage::GeneratePage(const std::string &method, const std::map &queryvars) +{ + std::string content=""; + std::string sql=""; + std::string boardname=""; + int rowsperpage=25; + std::string rowsperpagestr="26"; // 1 more than rowsperpage so we know if there are more boards + long startrow=0; + std::string startrowstr="0"; + int messagecount=0; + std::string messagecountstr="0"; + std::string lastdate=""; + int count=0; + std::string boardsearch=""; + std::string sortby=""; + std::string sortorder=""; + + // if startrow is specified + if(queryvars.find("startrow")!=queryvars.end()) + { + startrowstr=(*queryvars.find("startrow")).second; + // convert back and forth, just in case a number wasn't passed in startrow + StringFunctions::Convert(startrowstr,startrow); + if(startrow<0) + { + startrow=0; + } + StringFunctions::Convert(startrow,startrowstr); + } + if(queryvars.find("boardsearch")!=queryvars.end()) + { + boardsearch=(*queryvars.find("boardsearch")).second; + } + if(queryvars.find("sortby")!=queryvars.end() && queryvars.find("sortorder")!=queryvars.end()) + { + sortby=(*queryvars.find("sortby")).second; + sortorder=(*queryvars.find("sortorder")).second; + if(sortby!="BoardName" && sortby!="MessageCount" && sortby!="LastMessage") + { + sortby="BoardName"; + } + if(sortorder!="ASC" && sortorder!="DESC") + { + sortorder="ASC"; + } + } + else + { + sortby="BoardName"; + sortorder="ASC"; + } + + content="

Browse Messages

"; + content+=""; + content+=""; + content+=""; + content+=""; + + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + + sql="SELECT tblBoard.BoardID, tblBoard.BoardName, COUNT(tblMessageBoard.MessageID) AS 'MessageCount', MAX(tblMessage.MessageDate || ' ' || tblMessage.MessageTime) AS 'LastMessage'"; + sql+="FROM tblBoard LEFT JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID "; + sql+="LEFT JOIN tblMessage ON tblMessageBoard.MessageID=tblMessage.MessageID "; + sql+="WHERE (tblMessageBoard.MessageID>=0 OR tblMessageBoard.MessageID IS NULL) "; + if(boardsearch!="") + { + sql+="AND tblBoard.BoardName LIKE '%' || ? || '%' "; + } + sql+="GROUP BY tblBoard.BoardID "; + sql+="ORDER BY "+sortby+" COLLATE NOCASE "+sortorder+" "; + sql+="LIMIT "+startrowstr+","+rowsperpagestr+";"; + + SQLite3DB::Statement st=m_db->Prepare(sql); + if(boardsearch!="") + { + st.Bind(0,boardsearch); + } + + st.Step(); + while(st.RowReturned() && count++"+SanitizeOutput(boardname)+""; + content+=""; + content+=""; + content+="\r\n"; + st.Step(); + } + + if(startrow>0 || st.RowReturned()) + { + content+=""; + + if(startrow>0) + { + int thisstartrow=startrow-rowsperpage; + if(thisstartrow<0) + { + thisstartrow=0; + } + content+=""; + } + else + { + content+=""; + } + + content+=""; + + if(st.RowReturned()) + { + int thisstartrow=startrow+rowsperpage; + content+=""; + } + + content+=""; + } + content+="
BoardMessage CountLast Message
"+SanitizeOutput(messagecountstr)+""+SanitizeOutput(lastdate)+"
<---->
"; + + return StringFunctions::Replace(m_template,"[CONTENT]",content); +} + +const std::string BrowseBoardsPage::ReverseSort(const std::string &sortname, const std::string ¤tsortby, const std::string ¤tsortorder) +{ + if(sortname==currentsortby) + { + if(currentsortorder=="ASC") + { + return "DESC"; + } + else + { + return "ASC"; + } + } + else + { + return currentsortorder; + } +} diff --git a/src/http/pages/browsemessagespage.cpp b/src/http/pages/browsemessagespage.cpp new file mode 100644 index 0000000..9601064 --- /dev/null +++ b/src/http/pages/browsemessagespage.cpp @@ -0,0 +1,265 @@ +#include "../../../include/http/pages/browsemessagespage.h" +#include "../../../include/stringfunctions.h" +#include "../../../include/global.h" +#include "../../../include/messagethread.h" + +#ifdef XMEM + #include +#endif + +const std::string BrowseMessagesPage::BuildQueryString(const long startrow, const std::string &boardidstr, const std::string &messageidstr) +{ + std::string returnval=""; + std::string tempval=""; + + if(startrow>=0) + { + StringFunctions::Convert(startrow,tempval); + returnval+="startrow="+tempval; + } + + if(boardidstr!="") + { + if(returnval!="") + { + returnval+="&"; + } + returnval+="boardid="+boardidstr; + } + + if(messageidstr!="") + { + if(returnval!="") + { + returnval+="&"; + } + returnval+="messageid="+messageidstr; + } + + return returnval; + +} + +const std::string BrowseMessagesPage::GeneratePage(const std::string &method, const std::map &queryvars) +{ + std::string content=""; + long boardid=-1; + std::string boardidstr=""; + std::string messageidstr=""; + int startrow=0; + std::string startrowstr="0"; + int rowsperpage=50; + std::string rowsperpagestr="51"; // one more than rowsperpage so we can know if there are more messages + std::string sql=""; + int rowcount=0; + int page=0; + + // if startrow is specified + if(queryvars.find("startrow")!=queryvars.end()) + { + startrowstr=(*queryvars.find("startrow")).second; + // convert back and forth, just in case a number wasn't passed in startrow + StringFunctions::Convert(startrowstr,startrow); + if(startrow<0) + { + startrow=0; + } + StringFunctions::Convert(startrow,startrowstr); + } + if(queryvars.find("boardid")!=queryvars.end()) + { + boardidstr=(*queryvars.find("boardid")).second; + StringFunctions::Convert(boardidstr,boardid); + } + if(queryvars.find("messageid")!=queryvars.end()) + { + messageidstr=(*queryvars.find("messageid")).second; + page=1; + } + + if(page==0) + { + sql="SELECT Subject, FromName, MessageDate || ' ' || MessageTime, Body, tblMessage.MessageID "; + sql+="FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID "; + if(boardidstr!="") + { + sql+="WHERE tblMessageBoard.BoardID=? "; + } + sql+="ORDER BY MessageDate || ' ' || MessageTime DESC "; + sql+="LIMIT "+startrowstr+","+rowsperpagestr+";"; + + SQLite3DB::Statement st=m_db->Prepare(sql); + if(boardidstr!="") + { + st.Bind(0,boardidstr); + } + st.Step(); + + content+=""; + content+=""; + + rowcount=0; + while(st.RowReturned() && rowcount++400) + { + body.erase(400); + body+="..."; + } + + content+=""; + content+=""; + content+=""; + content+=""; + content+="\r\n"; + + st.Step(); + } + + if(startrow>0 || st.RowReturned()) + { + content+=""; + + if(startrow>0) + { + int thisstartrow=startrow-rowsperpage; + if(thisstartrow<0) + { + thisstartrow=0; + } + content+=""; + } + else + { + content+=""; + } + + content+=""; + + if(st.RowReturned()) + { + int thisstartrow=startrow+rowsperpage; + content+=""; + } + content+=""; + } + + content+="
SubjectFromDate
"+SanitizeOutput(subject)+""+fromname+""+SanitizeOutput(messagedate)+"
<---->
"; + } + else if(page==1) + { + sql="SELECT Body, FromName, MessageDate || ' ' || MessageTime, Subject FROM tblMessage WHERE MessageID=?;"; + SQLite3DB::Statement st=m_db->Prepare(sql); + st.Bind(0,messageidstr); + + st.Step(); + if(st.RowReturned()) + { + std::string body=""; + std::string fromname=""; + std::string messagedate=""; + std::string subject=""; + std::string boards=""; + + st.ResultText(0,body); + st.ResultText(1,fromname); + st.ResultText(2,messagedate); + st.ResultText(3,subject); + + // get boards message was posted to + SQLite3DB::Statement st2=m_db->Prepare("SELECT tblBoard.BoardID, tblBoard.BoardName FROM tblBoard INNER JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID WHERE tblMessageBoard.MessageID=?;"); + st2.Bind(0,messageidstr); + st2.Step(); + while(st2.RowReturned()) + { + std::string boardname=""; + std::string innerboardidstr=""; + + st2.ResultText(0,innerboardidstr); + st2.ResultText(1,boardname); + + if(boards!="") + { + boards+=", "; + } + + boards+=""+SanitizeOutput(boardname)+""; + + st2.Step(); + } + + content+="
"; + content+="
"; + content+=boards; + content+="
"; + content+="
"; + content+=SanitizeOutput(subject); + content+="
"; + content+="
"; + content+=SanitizeOutput(fromname); + content+="
"; + content+="
"; + content+=SanitizeOutput(messagedate); + content+="
"; + content+="
"; + content+=SanitizeOutput(body); + content+="
"; + content+="
\r\n"; + + long currentlevel=0; + MessageThread thread; + thread.Load(messageidstr,boardid); + + std::vector nodes=thread.GetNodes(); + if(nodes.size()>1) + { + content+="
    "; + for(std::vector::const_iterator i=nodes.begin(); i!=nodes.end(); i++) + { + if((*i).m_level>currentlevel) + { + content+="
      "; + } + else if((*i).m_level"+SanitizeOutput((*i).m_subject)+" - "+SanitizeOutput((*i).m_fromname); + } + else + { + content+=SanitizeOutput((*i).m_subject)+" - "+SanitizeOutput((*i).m_fromname); + } + content+="\r\n"; + } + while(currentlevel-->0) + { + content+="
    "; + } + content+="
\r\n"; + } + } + } + + return StringFunctions::Replace(m_template,"[CONTENT]",content); +} diff --git a/src/http/pages/forumcreatepostpage.cpp b/src/http/pages/forumcreatepostpage.cpp new file mode 100644 index 0000000..ac9ed16 --- /dev/null +++ b/src/http/pages/forumcreatepostpage.cpp @@ -0,0 +1,227 @@ +#include "../../../include/http/pages/forumcreatepostpage.h" +#include "../../../include/stringfunctions.h" +#include "../../../include/message.h" + +#ifdef XMEM + #include +#endif + +const std::string ForumCreatePostPage::GeneratePage(const std::string &method, const std::map &queryvars) +{ + int page=0; + std::string content=""; + std::string boardidstr=""; + std::string currentpagestr=""; + std::string threadidstr=""; + std::string replytomessageidstr=""; + std::string error=""; + std::string boardname=""; + std::string subject=""; + std::string body=""; + std::string localidentityidstr=""; + + if(queryvars.find("boardid")!=queryvars.end()) + { + boardidstr=(*queryvars.find("boardid")).second; + } + if(queryvars.find("currentpage")!=queryvars.end()) + { + currentpagestr=(*queryvars.find("currentpage")).second; + } + if(queryvars.find("threadid")!=queryvars.end()) + { + threadidstr=(*queryvars.find("threadid")).second; + } + if(queryvars.find("replytomessageid")!=queryvars.end()) + { + replytomessageidstr=(*queryvars.find("replytomessageid")).second; + } + + if(queryvars.find("formaction")!=queryvars.end() && (*queryvars.find("formaction")).second=="send") + { + if(queryvars.find("localidentityid")!=queryvars.end() && (*queryvars.find("localidentityid")).second!="") + { + localidentityidstr=(*queryvars.find("localidentityid")).second; + } + else + { + error="You must select a local identity as the sender
"; + } + + if(queryvars.find("subject")!=queryvars.end() && (*queryvars.find("subject")).second!="") + { + subject=(*queryvars.find("subject")).second; + } + else + { + error+="You must enter a subject
"; + } + + if(queryvars.find("body")!=queryvars.end() && (*queryvars.find("body")).second!="") + { + body=(*queryvars.find("body")).second; + body=StringFunctions::Replace(body,"\r\n","\n"); + } + else + { + error+="You must enter a message body
"; + } + + if(error=="") + { + Message mess; + + long localidentityid=-1; + long boardid=-1; + std::string references=""; + + StringFunctions::Convert(localidentityidstr,localidentityid); + StringFunctions::Convert(boardidstr,boardid); + + if(replytomessageidstr!="") + { + SQLite3DB::Statement st=m_db->Prepare("SELECT MessageUUID FROM tblMessage WHERE MessageID=?;"); + st.Bind(0,replytomessageidstr); + st.Step(); + if(st.RowReturned()) + { + st.ResultText(0,references); + } + } + + if(mess.Create(localidentityid,boardid,subject,body,references)) + { + if(mess.PostedToAdministrationBoard()==true) + { + mess.HandleAdministrationMessage(); + } + if(mess.StartFreenetInsert()) + { + page=1; + } + } + else + { + error="Could not create message"; + } + } + } + else + { + if(replytomessageidstr!="") + { + SQLite3DB::Statement replyst=m_db->Prepare("SELECT Subject, Body FROM tblMessage WHERE MessageID=?;"); + replyst.Bind(0,replytomessageidstr); + replyst.Step(); + if(replyst.RowReturned()) + { + replyst.ResultText(0,subject); + replyst.ResultText(1,body); + + if(subject.size()<3 || (subject.substr(0,2)!="re:" && subject.substr(0,2)!="Re:")) + { + subject="Re: "+subject; + } + + if(body.size()>0) + { + if(body[0]=='>') + { + body=">"+body; + } + else + { + body="> "+body; + } + std::string::size_type pos=body.find("\n"); + while(pos!=std::string::npos) + { + if(pos+1') + { + body.insert(pos+1,">"); + } + else + { + body.insert(pos+1,"> "); + } + pos=body.find("\n",pos+2); + } + body+="\n"; + } + } + } + } + + SQLite3DB::Statement boardnamest=m_db->Prepare("SELECT BoardName FROM tblBoard WHERE BoardID=?;"); + boardnamest.Bind(0,boardidstr); + boardnamest.Step(); + if(boardnamest.RowReturned()) + { + boardnamest.ResultText(0,boardname); + } + + content+=CreateForumHeader(); + + content+=""; + content+=""; + content+=""; + content+=""; + content+="
Forum : "+SanitizeOutput(boardname)+"
\r\n"; + + if(error!="") + { + content+="
"+error+"
\r\n"; + } + + if(page==0) + { + content+="
"; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+="
From"+LocalIdentityDropDown("localidentityid",localidentityidstr)+"
Subject
Message
\r\n"; + content+="
"; + } + else if(page==1) + { + content+="You have sent your message. It will show up in the thread after it has been successfully inserted and retrieved by FMS."; + } + + return StringFunctions::Replace(m_template,"[CONTENT]",content); +} + +const std::string ForumCreatePostPage::LocalIdentityDropDown(const std::string &name, const std::string &selectedid) +{ + std::string html=""; + return html; +} diff --git a/src/http/pages/forummainpage.cpp b/src/http/pages/forummainpage.cpp new file mode 100644 index 0000000..ae97874 --- /dev/null +++ b/src/http/pages/forummainpage.cpp @@ -0,0 +1,93 @@ +#include "../../../include/http/pages/forummainpage.h" +#include "../../../include/stringfunctions.h" + +#ifdef XMEM + #include +#endif + +const std::string ForumMainPage::GeneratePage(const std::string &method, const std::map &queryvars) +{ + std::string content=""; + + content+=CreateForumHeader(); + + content+="\r\n"; + content+="\r\n"; + + SQLite3DB::Statement newmessagesst=m_db->Prepare("SELECT tblMessage.MessageID FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID INNER JOIN tblThreadPost ON tblMessage.MessageID=tblThreadPost.MessageID WHERE tblMessageBoard.BoardID=? AND tblMessage.Read=0 LIMIT 0,1;"); + SQLite3DB::Statement lastmessagest=m_db->Prepare("SELECT tblMessage.MessageID, tblMessage.IdentityID, tblMessage.FromName, tblMessage.Subject, tblMessage.MessageDate || ' ' || tblMessage.MessageTime, tblThread.ThreadID FROM tblMessage INNER JOIN tblThreadPost ON tblMessage.MessageID=tblThreadPost.MessageID INNER JOIN tblThread ON tblThreadPost.ThreadID=tblThread.ThreadID WHERE tblThread.BoardID=? ORDER BY tblMessage.MessageDate || tblMessage.MessageTime DESC LIMIT 0,1;"); + + SQLite3DB::Statement st=m_db->Prepare("SELECT tblBoard.BoardID, BoardName, BoardDescription, COUNT(tblThreadPost.MessageID) FROM tblBoard LEFT JOIN tblThread ON tblBoard.BoardID=tblThread.BoardID LEFT JOIN tblThreadPost ON tblThread.ThreadID=tblThreadPost.ThreadID WHERE Forum='true' GROUP BY tblBoard.BoardID ORDER BY BoardName COLLATE NOCASE;"); + st.Step(); + while(st.RowReturned()) + { + int boardid=-1; + std::string boardidstr="-1"; + std::string boardname=""; + std::string boarddescription=""; + std::string postcountstr=""; + + st.ResultInt(0,boardid); + st.ResultText(0,boardidstr); + st.ResultText(1,boardname); + st.ResultText(2,boarddescription); + st.ResultText(3,postcountstr); + + content+=""; + content+=""; + + content+=""; + content+=""; + + lastmessagest.Bind(0,boardid); + lastmessagest.Step(); + content+=""; + lastmessagest.Reset(); + + content+="\r\n"; + st.Step(); + } + + content+="
NewForumPostsLast Post
"; + + newmessagesst.Bind(0,boardid); + newmessagesst.Step(); + if(newmessagesst.RowReturned()) + { + content+=""; + } + else + { + content+=""; + } + newmessagesst.Reset(); + + content+=""; + content+=""+SanitizeOutput(boardname)+"
"; + content+=""+SanitizeOutput(boarddescription)+""; + content+="
"; + content+=postcountstr+" posts"; + content+=""; + if(lastmessagest.RowReturned()) + { + std::string messageidstr=""; + std::string identityidstr=""; + std::string fromname=""; + std::string messagedate=""; + std::string subject=""; + std::string threadidstr=""; + + lastmessagest.ResultText(0,messageidstr); + lastmessagest.ResultText(1,identityidstr); + lastmessagest.ResultText(2,fromname); + lastmessagest.ResultText(3,subject); + lastmessagest.ResultText(4,messagedate); + lastmessagest.ResultText(5,threadidstr); + + content+="Last post on "+messagedate+" in
"; + content+=""+FixSubject(subject)+" by "+FixFromName(fromname)+""; + } + content+="
\r\n"; + + return StringFunctions::Replace(m_template,"[CONTENT]",content); +} diff --git a/src/http/pages/forumthreadspage.cpp b/src/http/pages/forumthreadspage.cpp new file mode 100644 index 0000000..0777fe1 --- /dev/null +++ b/src/http/pages/forumthreadspage.cpp @@ -0,0 +1,197 @@ +#include "../../../include/http/pages/forumthreadspage.h" +#include "../../../include/stringfunctions.h" +#include + +const std::string ForumThreadsPage::GeneratePage(const std::string &method, const std::map &queryvars) +{ + int currentpage=1; + std::string currentpagestr="1"; + std::string content=""; + int startrow=0; + std::string startrowstr="0"; + int rowsperpage=25; + std::string rowsperpagestr="25"; + std::string sql=""; + int boardid=-1; + std::string boardidstr="-1"; + int count=0; + int threadcount=0; + SQLite3DB::Statement newthreadpostst=m_db->Prepare("SELECT tblMessage.MessageID FROM tblThreadPost INNER JOIN tblMessage ON tblThreadPost.MessageID=tblMessage.MessageID WHERE tblThreadPost.ThreadID=? AND tblMessage.Read=0 LIMIT 0,1;"); + SQLite3DB::Statement replycountst=m_db->Prepare("SELECT COUNT(*)-1 FROM tblThreadPost WHERE ThreadID=?;"); + SQLite3DB::Statement boardnamest=m_db->Prepare("SELECT tblBoard.BoardName FROM tblBoard WHERE BoardID=?;"); + SQLite3DB::Statement threadcountst=m_db->Prepare("SELECT COUNT(*) FROM tblThread WHERE BoardID=?;"); + + if(queryvars.find("boardid")!=queryvars.end()) + { + boardidstr=(*queryvars.find("boardid")).second; + StringFunctions::Convert(boardidstr,boardid); + } + if(queryvars.find("currentpage")!=queryvars.end()) + { + currentpagestr=(*queryvars.find("currentpage")).second; + StringFunctions::Convert(currentpagestr,currentpage); + if(currentpage<0) + { + currentpage=0; + } + StringFunctions::Convert(currentpage,currentpagestr); + } + if(queryvars.find("formaction")!=queryvars.end() && (*queryvars.find("formaction")).second=="markallread" && boardid!=-1) + { + SQLite3DB::Statement markst=m_db->Prepare("UPDATE tblMessage SET Read=1 WHERE tblMessage.Read=0 AND tblMessage.MessageID IN (SELECT MessageID FROM tblThread INNER JOIN tblThreadPost ON tblThread.ThreadID=tblThreadPost.ThreadID WHERE tblThread.BoardID=?);"); + markst.Bind(0,boardid); + markst.Step(); + } + + startrow=(currentpage-1)*rowsperpage; + StringFunctions::Convert(startrow,startrowstr); + + content+=CreateForumHeader(); + + content+=""; + content+=""; + + boardnamest.Bind(0,boardid); + boardnamest.Step(); + if(boardnamest.RowReturned()) + { + std::string boardname=""; + boardnamest.ResultText(0,boardname); + content+=""; + } + content+=""; + content+=""; + content+=""; + content+="
Forum : "+SanitizeOutput(boardname)+"Mark All ReadNew Post
\r\n"; + + content+=""; + content+="\r\n"; + + sql="SELECT tblThread.ThreadID, tblThread.LastMessageID, tblLastMessage.FromName, tblLastMessage.MessageDate || ' ' || tblLastMessage.MessageTime, tblFirstMessage.Subject, tblFirstMessage.FromName, tblFirstMessage.IdentityID, tblLastMessage.IdentityID"; + sql+=" FROM tblThread INNER JOIN tblMessage AS tblLastMessage ON tblThread.LastMessageID=tblLastMessage.MessageID INNER JOIN tblMessage AS tblFirstMessage ON tblThread.FirstMessageID=tblFirstMessage.MessageID"; + sql+=" WHERE tblThread.BoardID=?"; + sql+=" ORDER BY tblLastMessage.MessageDate || tblLastMessage.MessageTime DESC"; + sql+=" LIMIT "+startrowstr+","+rowsperpagestr+";"; + + SQLite3DB::Statement threadst=m_db->Prepare(sql); + threadst.Bind(0,boardid); + threadst.Step(); + count=0; + while(threadst.RowReturned() && count++"; + + newthreadpostst.Bind(0,threadidstr); + newthreadpostst.Step(); + if(newthreadpostst.RowReturned()) + { + content+=""; + } + else + { + content+=""; + } + newthreadpostst.Reset(); + + content+=""; + content+=""; + content+=""; + + content+=""; + + content+=""; + + content+="\r\n"; + + threadst.Step(); + } + + threadcountst.Bind(0,boardid); + threadcountst.Step(); + if(threadcountst.RowReturned()) + { + threadcountst.ResultInt(0,threadcount); + } + + if(threadcount>=rowsperpage) + { + int totalpages=ceil(static_cast(threadcount)/static_cast(rowsperpage)); + int lastwrote=0; + content+=""; + + content+=""; + + content+="\r\n"; + } + + content+="
NewSubjectStarted ByRepliesLast Post
"; + content+=""+SanitizeOutput(firstmessagesubject)+""; + content+=""; + content+=""+FixFromName(firstmessagefromname)+""; + content+=""; + + replycountst.Bind(0,threadidstr); + replycountst.Step(); + if(replycountst.RowReturned()) + { + std::string count="0"; + replycountst.ResultText(0,count); + content+=count; + } + else + { + content+="0"; + } + replycountst.Reset(); + + content+=""; + content+=lastmessagedate+"
by "+FixFromName(lastmessagefromname)+""; + content+="
Pages : "; + + for(int i=1; i<=totalpages; i++) + { + if(i==1 || (i>currentpage-3 && i"+pagestr+""; + } + else + { + content+=" "+pagestr; + } + lastwrote=i; + } + } + + content+="
"; + + content+="
\r\n"; + + return StringFunctions::Replace(m_template,"[CONTENT]",content); +} diff --git a/src/http/pages/forumviewthreadpage.cpp b/src/http/pages/forumviewthreadpage.cpp new file mode 100644 index 0000000..0b69926 --- /dev/null +++ b/src/http/pages/forumviewthreadpage.cpp @@ -0,0 +1,158 @@ +#include "../../../include/http/pages/forumviewthreadpage.h" +#include "../../../include/stringfunctions.h" + +#ifdef XMEM + #include +#endif + +const std::string ForumViewThreadPage::FixBody(const std::string &body) +{ + static std::string whitespace=" \t\r\n"; + std::string output=body; + + // put \n after 80 contiguous characters in the body + std::string::size_type prevpos=0; + std::string::size_type pos=output.find_first_of(whitespace); + while(pos!=std::string::npos) + { + while(pos-prevpos>80) + { + output.insert(prevpos+80,"\n"); + prevpos+=81; // 81 because of the extra newline we just inserted + } + prevpos=pos; + pos=output.find_first_of(whitespace,pos+1); + } + while(output.size()-prevpos>80) // check the last line of the message (no whitespace after it) + { + output.insert(prevpos+80,"\n"); + prevpos+=81; + } + + output=StringFunctions::Replace(output,"<","<"); + output=StringFunctions::Replace(output,">",">"); + output=StringFunctions::Replace(output,"\n","
"); + return output; +} + +const std::string ForumViewThreadPage::GeneratePage(const std::string &method, const std::map &queryvars) +{ + std::string content=""; + std::string threadidstr=""; + std::string boardidstr=""; + std::string currentpagestr=""; + std::string boardname=""; + + if(queryvars.find("threadid")!=queryvars.end()) + { + threadidstr=(*queryvars.find("threadid")).second; + } + if(queryvars.find("currentpage")!=queryvars.end()) + { + currentpagestr=(*queryvars.find("currentpage")).second; + } + if(queryvars.find("boardid")!=queryvars.end()) + { + boardidstr=(*queryvars.find("boardid")).second; + } + + content+=CreateForumHeader(); + + SQLite3DB::Statement updateread=m_db->Prepare("UPDATE tblMessage SET Read=1 WHERE tblMessage.MessageID IN (SELECT MessageID FROM tblThreadPost WHERE ThreadID=?);"); + updateread.Bind(0,threadidstr); + updateread.Step(); + + SQLite3DB::Statement trustst=m_db->Prepare("SELECT LocalMessageTrust, LocalTrustListTrust, PeerMessageTrust, PeerTrustListTrust, Name FROM tblIdentity WHERE IdentityID=?;"); + + SQLite3DB::Statement boardnamest=m_db->Prepare("SELECT tblBoard.BoardName FROM tblBoard INNER JOIN tblThread ON tblBoard.BoardID=tblThread.BoardID WHERE tblThread.ThreadID=?;"); + boardnamest.Bind(0,threadidstr); + boardnamest.Step(); + + if(boardnamest.RowReturned()) + { + boardnamest.ResultText(0,boardname); + } + + content+=""; + content+=""; + content+=""; + content+=""; + content+="
Forum : "+SanitizeOutput(boardname)+"
\r\n"; + + SQLite3DB::Statement st=m_db->Prepare("SELECT tblMessage.MessageID, tblMessage.IdentityID, tblMessage.FromName, tblMessage.Subject, tblMessage.MessageDate || ' ' || tblMessage.MessageTime, tblMessage.Body FROM tblMessage INNER JOIN tblThreadPost ON tblMessage.MessageID=tblThreadPost.MessageID WHERE tblThreadPost.ThreadID=? ORDER BY tblThreadPost.PostOrder;"); + st.Bind(0,threadidstr); + + content+=""; + st.Step(); + while(st.RowReturned()) + { + std::string messageidstr=""; + std::string identityidstr=""; + std::string fromname=""; + std::string subject=""; + std::string datetime=""; + std::string body=""; + + st.ResultText(0,messageidstr); + st.ResultText(1,identityidstr); + st.ResultText(2,fromname); + st.ResultText(3,subject); + st.ResultText(4,datetime); + st.ResultText(5,body); + + content+=""; + content+=""; + content+=""; + content+=""; + content+="\r\n"; + content+=""; + content+=""; + content+=""; + trustst.Reset(); + + st.Step(); + } + content+="
"; + content+=""; + content+=""+FixFromName(fromname)+"
"; + + trustst.Bind(0,identityidstr); + trustst.Step(); + if(trustst.RowReturned()) + { + std::string localmessagetrust=""; + std::string localtrustlisttrust=""; + std::string peermessagetrust=""; + std::string peertrustlisttrust=""; + std::string name=""; + + trustst.ResultText(0,localmessagetrust); + trustst.ResultText(1,localtrustlisttrust); + trustst.ResultText(2,peermessagetrust); + trustst.ResultText(3,peertrustlisttrust); + trustst.ResultText(4,name); + + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+=""; + content+="
Trust
LocalPeer
Message"+localmessagetrust+""+peermessagetrust+"
Trust List"+localtrustlisttrust+""+peertrustlisttrust+"
"; + } + + content+="
"; + content+=SanitizeOutput(subject)+" on "+datetime; + content+="Reply
"; + content+=FixBody(body); + content+="
"; + + return StringFunctions::Replace(m_template,"[CONTENT]",content); +} diff --git a/src/http/pages/homepage.cpp b/src/http/pages/homepage.cpp index 3ebe2f1..ec4ea32 100644 --- a/src/http/pages/homepage.cpp +++ b/src/http/pages/homepage.cpp @@ -66,6 +66,10 @@ const std::string HomePage::GeneratePage(const std::string &method, const std::m content+="You can see the release info here
"; showgenericupdate=false; } + else + { + content+="Release info
"; + } } diff --git a/src/http/pages/localidentitiespage.cpp b/src/http/pages/localidentitiespage.cpp index 400260f..7910789 100644 --- a/src/http/pages/localidentitiespage.cpp +++ b/src/http/pages/localidentitiespage.cpp @@ -33,7 +33,7 @@ const std::string LocalIdentitiesPage::GeneratePage(const std::string &method, c content+="
"; - content+=""; + content+="
NameSingle UsePublish Trust ListPublish Board ListPublish FreesiteMin Message DelayMax Message DelayAnnounced? *
"; SQLite3DB::Statement st=m_db->Prepare("SELECT LocalIdentityID,tblLocalIdentity.Name,tblLocalIdentity.PublicKey,tbLLocalIdentity.PublishTrustList,tblLocalIdentity.SingleUse,tblLocalIdentity.PublishBoardList,tblIdentity.IdentityID,tblLocalIdentity.PublishFreesite,tblLocalIdentity.MinMessageDelay,tblLocalIdentity.MaxMessageDelay FROM tblLocalIdentity LEFT JOIN tblIdentity ON tblLocalIdentity.PublicKey=tblIdentity.PublicKey ORDER BY tblLocalIdentity.Name;"); st.Step(); @@ -116,7 +116,7 @@ const std::string LocalIdentitiesPage::GeneratePage(const std::string &method, c } content+="
NameSingle UsePublish Trust ListPublish Board ListPublish FreesiteMin Message DelayMax Message DelayAnnounced? *
"; - content+="

* An identity is considered successfully announced when you have downloaded a trust list from someone that contains the identity. The number in parenthesis is how many trust lists that identity appears in.

"; + content+="

* An identity is considered successfully announced when you have downloaded a trust list from someone that contains the identity. You must trust other identities' trust lists for this to happen. The number in parenthesis is how many trust lists the identity appears in.

"; content+="

Single Use Identities will automatically be deleted 7 days after creation.

"; content+="

Messages that each identity sends may be delayed by a random number of minutes between min and max. Set both to 0 to send messages as soon as possible.

"; diff --git a/src/http/pages/peertrustpage.cpp b/src/http/pages/peertrustpage.cpp index fe03c91..d80ae18 100644 --- a/src/http/pages/peertrustpage.cpp +++ b/src/http/pages/peertrustpage.cpp @@ -261,14 +261,14 @@ const std::string PeerTrustPage::GeneratePage(const std::string &method, const s // search drop down content+="
"; - content+="
"; + content+=""; content+=""; content+=""; content+="
"; content+="
"; content+="
"; - content+="
"; + content+=""; content+="Load Trust List of "; content+=CreateLocalIdentityDropDown("localidentityid",localidentityid); content+=""; @@ -285,14 +285,14 @@ const std::string PeerTrustPage::GeneratePage(const std::string &method, const s content+=""; } content+=""; - content+=""; - content+=""; + content+=""; + content+=""; content+=""; - content+=""; - content+=""; + content+=""; + content+=""; content+=""; - content+=""; - content+=""; + content+=""; + content+=""; content+="\r\n"; // get count of identities we are showing @@ -425,7 +425,7 @@ const std::string PeerTrustPage::GeneratePage(const std::string &method, const s if(startrow>0) { StringFunctions::Convert(startrow-rowsperpage,tempstr); - content+=""; + content+=""; cols+=3; } if(startrow+rowsperpageNext Page -->"; + content+=""; } content+=""; } @@ -484,15 +484,3 @@ const std::string PeerTrustPage::ReverseSort(const std::string &sortname, const return currentsortorder; } } - -const bool PeerTrustPage::WillHandleURI(const std::string &uri) -{ - if(uri.find("peertrust.")!=std::string::npos) - { - return true; - } - else - { - return false; - } -} diff --git a/src/http/pages/recentlyaddedpage.cpp b/src/http/pages/recentlyaddedpage.cpp index 2b09ce8..313544e 100644 --- a/src/http/pages/recentlyaddedpage.cpp +++ b/src/http/pages/recentlyaddedpage.cpp @@ -81,15 +81,3 @@ const std::string RecentlyAddedPage::GeneratePage(const std::string &method, con return StringFunctions::Replace(m_template,"[CONTENT]",content); } - -const bool RecentlyAddedPage::WillHandleURI(const std::string &uri) -{ - if(uri.find("recentlyadded.")!=std::string::npos) - { - return true; - } - else - { - return false; - } -} diff --git a/src/http/pages/showcaptchapage.cpp b/src/http/pages/showcaptchapage.cpp index 088fffa..736ba85 100644 --- a/src/http/pages/showcaptchapage.cpp +++ b/src/http/pages/showcaptchapage.cpp @@ -13,7 +13,10 @@ void ShowCaptchaPage::handleRequest(Poco::Net::HTTPServerRequest &request, Poco: std::map queryvars; CreateQueryVarMap(request,queryvars); - response.setChunkedTransferEncoding(true); + if(request.getVersion()==Poco::Net::HTTPRequest::HTTP_1_1) + { + response.setChunkedTransferEncoding(true); + } std::string content=""; if(queryvars.find("UUID")!=queryvars.end()) diff --git a/src/http/pages/showimagepage.cpp b/src/http/pages/showimagepage.cpp new file mode 100644 index 0000000..8b653ee --- /dev/null +++ b/src/http/pages/showimagepage.cpp @@ -0,0 +1,64 @@ +#include "../../../include/http/pages/showimagepage.h" + +#ifdef XMEM + #include +#endif + +std::map > ShowImagePage::m_imagecache; + +void ShowImagePage::handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response) +{ + m_log->trace("ShowImagePage::handleRequest from "+request.clientAddress().toString()); + + std::map queryvars; + CreateQueryVarMap(request,queryvars); + + if(request.getVersion()==Poco::Net::HTTPRequest::HTTP_1_1) + { + response.setChunkedTransferEncoding(true); + } + + std::string content=""; + if(queryvars.find("image")!=queryvars.end()) + { + if(m_imagecache.find((*queryvars.find("image")).second)!=m_imagecache.end()) + { + content+=std::string(m_imagecache[(*queryvars.find("image")).second].begin(),m_imagecache[(*queryvars.find("image")).second].end()); + } + else + { + FILE *infile=fopen((*queryvars.find("image")).second.c_str(),"rb"); + if(infile) + { + fseek(infile,0,SEEK_END); + long filelen=ftell(infile); + fseek(infile,0,SEEK_SET); + + if(filelen>0) + { + std::vector data(filelen,0); + fread(&data[0],1,data.size(),infile); + content+=std::string(data.begin(),data.end()); + m_imagecache[(*queryvars.find("image")).second]=data; + } + + fclose(infile); + } + } + } + + std::ostream &ostr = response.send(); + ostr << content; +} + +const bool ShowImagePage::WillHandleURI(const std::string &uri) +{ + if(uri.find("showimage.htm")!=std::string::npos) + { + return true; + } + else + { + return false; + } +} diff --git a/src/http/pages/versioninfopage.cpp b/src/http/pages/versioninfopage.cpp index 670e9da..13b88ba 100644 --- a/src/http/pages/versioninfopage.cpp +++ b/src/http/pages/versioninfopage.cpp @@ -4,59 +4,71 @@ #include +#ifdef XMEM + #include +#endif + const std::string VersionInfoPage::GeneratePage(const std::string &method, const std::map &queryvars) { std::string content=""; + bool hascriteria=false; std::string major=VERSION_MAJOR; std::string minor=VERSION_MINOR; std::string release=VERSION_RELEASE; + std::string sql=""; if(queryvars.find("Major")!=queryvars.end()) { major=(*queryvars.find("Major")).second; + hascriteria=true; } if(queryvars.find("Minor")!=queryvars.end()) { minor=(*queryvars.find("Minor")).second; + hascriteria=true; } if(queryvars.find("Release")!=queryvars.end()) { release=(*queryvars.find("Release")).second; + hascriteria=true; } - SQLite3DB::Statement st=m_db->Prepare("SELECT Notes, Changes FROM tblFMSVersion WHERE Major=? AND Minor=? AND Release=?;"); - st.Bind(0,major); - st.Bind(1,minor); - st.Bind(2,release); + sql="SELECT Notes, Changes, Major, Minor, Release FROM tblFMSVersion "; + if(hascriteria==true) + { + sql+="WHERE Major=? AND Minor=? AND Release=? "; + } + sql+="ORDER BY Major DESC, Minor DESC, Release DESC;"; + SQLite3DB::Statement st=m_db->Prepare(sql); + if(hascriteria==true) + { + st.Bind(0,major); + st.Bind(1,minor); + st.Bind(2,release); + } st.Step(); - if(st.RowReturned()) + while(st.RowReturned()) { std::string notes=""; std::string changes=""; st.ResultText(0,notes); st.ResultText(1,changes); + st.ResultText(2,major); + st.ResultText(3,minor); + st.ResultText(4,release); + content+="
"; content+="

Release "+major+"."+minor+"."+release+"

"; content+="

Notes

"; content+=StringFunctions::Replace(notes,"\n","
"); content+="

Changes

"; content+=StringFunctions::Replace(changes,"\n","
"); + content+="
"; + st.Step(); } return StringFunctions::Replace(m_template,"[CONTENT]",content); } - -const bool VersionInfoPage::WillHandleURI(const std::string &uri) -{ - if(uri.find("versioninfo.")!=std::string::npos) - { - return true; - } - else - { - return false; - } -} diff --git a/src/message.cpp b/src/message.cpp index 8a3935d..0445e29 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -49,6 +49,63 @@ const bool Message::CheckForAdministrationBoard(const std::vector & return false; } +const bool Message::Create(const long localidentityid, const long boardid, const std::string &subject, const std::string &body, const std::string &references) +{ + Initialize(); + + Poco::UUIDGenerator uuidgen; + Poco::UUID uuid; + + // get header info + // date is always set to now regardless of what message has + m_datetime=Poco::Timestamp(); + + // messageuuid is always a unique id we generate regardless of message message-id + try + { + uuid=uuidgen.createRandom(); + m_messageuuid=uuid.toString(); + StringFunctions::UpperCase(m_messageuuid,m_messageuuid); + } + catch(...) + { + m_log->fatal("Message::ParseNNTPMessage could not create UUID"); + } + + // get from + SQLite3DB::Statement st=m_db->Prepare("SELECT Name FROM tblLocalIdentity WHERE LocalIdentityID=?;"); + st.Bind(0,localidentityid); + st.Step(); + if(st.RowReturned()) + { + st.ResultText(0,m_fromname); + } + + // get boards posted to + std::string boardname=""; + SQLite3DB::Statement boardst=m_db->Prepare("SELECT BoardName FROM tblBoard WHERE BoardID=?;"); + boardst.Bind(0,boardid); + boardst.Step(); + if(boardst.RowReturned()) + { + boardst.ResultText(0,boardname); + } + + m_boards.push_back(boardname); + m_replyboardname=boardname; + + m_subject=subject; + + m_body=body; + + if(references!="") + { + m_inreplyto[0]=references; + } + + return true; +} + const int Message::FindLocalIdentityID(const std::string &name) { SQLite3DB::Statement st=m_db->Prepare("SELECT LocalIdentityID FROM tblLocalIdentity WHERE Name=?;"); diff --git a/src/messagethread.cpp b/src/messagethread.cpp new file mode 100644 index 0000000..37e3693 --- /dev/null +++ b/src/messagethread.cpp @@ -0,0 +1,120 @@ +#include "../include/messagethread.h" +#include "../include/stringfunctions.h" + +#include + +#ifdef XMEM + #include +#endif + +void MessageThread::AddChildren(const long messageid, const long level, const long boardid) +{ + SQLite3DB::Statement st=m_db->Prepare("SELECT tblMessageReplyTo.MessageID, tblMessage1.Subject, tblMessage1.FromName, tblMessage1.MessageDate || ' ' || tblMessage1.MessageTime FROM tblMessage INNER JOIN tblMessageReplyTo ON tblMessage.MessageUUID=tblMessageReplyTo.ReplyToMessageUUID INNER JOIN tblMessage AS 'tblMessage1' ON tblMessageReplyTo.MessageID=tblMessage1.MessageID INNER JOIN tblMessageBoard ON tblMessage1.MessageID=tblMessageBoard.MessageID WHERE tblMessage.MessageID=? AND tblMessageBoard.BoardID=? AND tblMessageReplyTo.ReplyOrder=0 ORDER BY tblMessage1.MessageDate || ' ' || tblMessage1.MessageTime;"); + st.Bind(0,messageid); + st.Bind(1,boardid); + st.Step(); + while(st.RowReturned()) + { + int childid=0; + std::string subject=""; + std::string fromname=""; + std::string datetime=""; + st.ResultInt(0,childid); + st.ResultText(1,subject); + st.ResultText(2,fromname); + st.ResultText(3,datetime); + + threadnode node; + node.m_messageid=childid; + node.m_level=level; + node.m_subject=subject; + node.m_fromname=fromname; + node.m_date=datetime; + m_nodes.push_back(node); + + AddChildren(childid,level+1,boardid); + + st.Step(); + } +} + +const MessageThread::threadnode MessageThread::GetOriginalMessageNode(const long messageid, const long boardid) +{ + SQLite3DB::Statement st=m_db->Prepare("SELECT tblMessage.MessageID, tblMessage.Subject, tblMessage.FromName, tblMessage.MessageDate || ' ' || tblMessage.MessageTime FROM tblMessageReplyTo INNER JOIN tblMessage ON tblMessageReplyTo.ReplyToMessageUUID=tblMessage.MessageUUID INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID WHERE tblMessageReplyTo.ReplyOrder=0 AND tblMessageReplyTo.MessageID=? AND tblMessageBoard.BoardID=?;"); + st.Bind(0,messageid); + st.Bind(1,boardid); + st.Step(); + if(st.RowReturned()) + { + int id=0; + std::string subject=""; + std::string fromname=""; + std::string datetime=""; + st.ResultInt(0,id); + st.ResultText(1,subject); + st.ResultText(2,fromname); + st.ResultText(3,datetime); + + threadnode node; + node.m_messageid=id; + node.m_level=0; + node.m_subject=subject; + node.m_fromname=fromname; + node.m_date=datetime; + + return GetOriginalMessageNode(node.m_messageid,boardid); + } + else + { + threadnode node; + node.m_messageid=-1; + node.m_level=0; + node.m_subject=""; + node.m_fromname=""; + node.m_date=""; + + SQLite3DB::Statement st2=m_db->Prepare("SELECT Subject, FromName, MessageDate || ' ' || MessageTime FROM tblMessage WHERE MessageID=?;"); + st2.Bind(0,messageid); + st2.Step(); + + if(st2.RowReturned()) + { + node.m_messageid=messageid; + st2.ResultText(0,node.m_subject); + st2.ResultText(1,node.m_fromname); + st2.ResultText(2,node.m_date); + } + + return node; + } +} + +const bool MessageThread::Load(const long messageid, const long boardid, const bool bydate) +{ + threadnode originalmessagenode=GetOriginalMessageNode(messageid,boardid); + + if(originalmessagenode.m_messageid>=0) + { + m_nodes.push_back(originalmessagenode); + + AddChildren(originalmessagenode.m_messageid,1,boardid); + + if(bydate==true) + { + std::sort(m_nodes.begin(),m_nodes.end(),datecompare()); + } + + return true; + } + else + { + return false; + } +} + +const bool MessageThread::Load(const std::string &messageidstr, const long boardid, const bool bydate) +{ + long messageid=0; + StringFunctions::Convert(messageidstr,messageid); + return Load(messageid,boardid,bydate); +} diff --git a/src/nntp/nntpconnection.cpp b/src/nntp/nntpconnection.cpp index 84d07ff..0212e23 100644 --- a/src/nntp/nntpconnection.cpp +++ b/src/nntp/nntpconnection.cpp @@ -17,11 +17,10 @@ #include #endif -NNTPConnection::NNTPConnection(SOCKET sock) +NNTPConnection::NNTPConnection(SOCKET sock):m_socket(sock) { - std::string tempval; + std::string tempval(""); - m_socket=sock; m_tempbuffer.resize(32768); m_status.m_isposting=false; diff --git a/src/nntp/nntplistener.cpp b/src/nntp/nntplistener.cpp index 6355ebc..04fa1e1 100644 --- a/src/nntp/nntplistener.cpp +++ b/src/nntp/nntplistener.cpp @@ -159,7 +159,7 @@ void NNTPListener::StartListen() } else { - m_log->error("NNTPListener::StartListen socket listen failed"); + m_log->error("NNTPListener::StartListen socket listen failed on "+sa.toString()); #ifdef _WIN32 closesocket(sock); #else @@ -169,7 +169,7 @@ void NNTPListener::StartListen() } else { - m_log->error("NNTPListener::StartListen socket bind failed"); + m_log->error("NNTPListener::StartListen socket bind failed on "+sa.toString()); #ifdef _WIN32 closesocket(sock); #else @@ -179,7 +179,7 @@ void NNTPListener::StartListen() } else { - m_log->error("NNTPListener::StartListen couldn't create socket"); + m_log->error("NNTPListener::StartListen couldn't create socket on "+sa.toString()); } } catch(Poco::Exception &e) diff --git a/src/threadbuilder.cpp b/src/threadbuilder.cpp new file mode 100644 index 0000000..521cccc --- /dev/null +++ b/src/threadbuilder.cpp @@ -0,0 +1,85 @@ +#include "../include/threadbuilder.h" +#include "../include/messagethread.h" + +const bool ThreadBuilder::Build(const long messageid, const long boardid, const bool bydate) +{ + int count=0; + int threadid=-1; + MessageThread mt; + std::vector m_threadmessages; + + mt.Load(messageid,boardid,bydate); + m_threadmessages=mt.GetNodes(); + + // find threadid of this thread if it already exists in a thread + SQLite3DB::Statement st=m_db->Prepare("SELECT tblThread.ThreadID FROM tblThread INNER JOIN tblThreadPost ON tblThread.ThreadID=tblThreadPost.ThreadID WHERE tblThread.BoardID=? AND tblThreadPost.MessageID=?;"); + st.Bind(0,boardid); + st.Bind(1,messageid); + + st.Step(); + if(st.RowReturned()) + { + st.ResultInt(0,threadid); + } + else + { + st.Reset(); + // message doesn't exist in a thread, try to find a message in the thread that is already in a thread + for(std::vector::const_iterator i=m_threadmessages.begin(); i!=m_threadmessages.end() && threadid==-1; i++) + { + st.Bind(0,boardid); + st.Bind(1,(*i).m_messageid); + st.Step(); + + if(st.RowReturned()) + { + st.ResultInt(0,threadid); + } + + st.Reset(); + + } + + // thread doesn't exist - create it + if(threadid==-1) + { + st=m_db->Prepare("INSERT INTO tblThread(BoardID) VALUES(?);"); + st.Bind(0,boardid); + st.Step(true); + threadid=st.GetLastInsertRowID(); + } + } + + if(m_threadmessages.size()>0) + { + st=m_db->Prepare("UPDATE tblThread SET FirstMessageID=?, LastMessageID=? WHERE ThreadID=?;"); + st.Bind(0,m_threadmessages[0].m_messageid); + st.Bind(1,m_threadmessages[m_threadmessages.size()-1].m_messageid); + st.Bind(2,threadid); + st.Step(); + + st=m_db->Prepare("DELETE FROM tblThreadPost WHERE ThreadID=?;"); + st.Bind(0,threadid); + st.Step(); + + count=0; + st=m_db->Prepare("INSERT INTO tblThreadPost(ThreadID,MessageID,PostOrder) VALUES(?,?,?);"); + for(std::vector::const_iterator i=m_threadmessages.begin(); i!=m_threadmessages.end(); i++, count++) + { + st.Bind(0,threadid); + st.Bind(1,(*i).m_messageid); + st.Bind(2,count); + st.Step(); + st.Reset(); + } + } + else + { + st=m_db->Prepare("DELETE FROM tblThread WHERE ThreadID=?;"); + st.Bind(0,threadid); + st.Step(); + } + + return true; + +} diff --git a/template.htm b/template.htm index 7509afd..248c006 100644 --- a/template.htm +++ b/template.htm @@ -1,7 +1,7 @@ -FMS : Freenet Message System +FMS : Freenet Message System @@ -236,9 +271,10 @@ td { padding-left:5px; padding-right:5px; }
  • Add Peer
  • Peer Maintenance
  • Peer Trust
  • -
  • Boards
  • +
  • Board Maintenance
  • Control Boards
  • Inserted Files
  • +
  • Browse Forums
  • NameLocal Message Trust
    NameLocal Message TrustMessage CommentPeer Message TrustLocal Trust List TrustPeer Message TrustLocal Trust List TrustTrust CommentPeer Trust List TrustMessage CountPeer Trust List TrustMessage Count
    <-- Previous Page<-- Previous PageNext Page -->