version 0.3.24
authorSomeDude <SomeDude@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw>
Sun, 7 Dec 2008 11:41:00 +0000 (12:41 +0100)
committerDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Sun, 7 Dec 2008 11:41:00 +0000 (12:41 +0100)
13 files changed:
CMakeLists.txt
include/global.h
include/http/ipagehandler.h
readme.txt
src/http/fmshttprequesthandlerfactory.cpp
src/http/ipagehandler.cpp
src/http/pages/announceidentitypage.cpp
src/http/pages/browseboardspage.cpp [deleted file]
src/http/pages/browsemessagespage.cpp [deleted file]
src/http/pages/forumcreatepostpage.cpp
src/http/pages/forumviewthreadpage.cpp
src/http/pages/peertrustpage.cpp
src/threadbuilder.cpp

index a5aef9e..4585bbc 100644 (file)
@@ -79,8 +79,6 @@ src/http/multipartparser.cpp
 src/http/pages/addpeerpage.cpp\r
 src/http/pages/announceidentitypage.cpp\r
 src/http/pages/boardspage.cpp\r
-src/http/pages/browseboardspage.cpp\r
-src/http/pages/browsemessagespage.cpp\r
 src/http/pages/confirmpage.cpp\r
 src/http/pages/controlboardpage.cpp\r
 src/http/pages/createidentitypage.cpp\r
index aff023f..eb9d33d 100644 (file)
@@ -7,10 +7,10 @@
 \r
 #define VERSION_MAJOR          "0"\r
 #define VERSION_MINOR          "3"\r
-#define VERSION_RELEASE                "23"\r
+#define VERSION_RELEASE                "24"\r
 #define FMS_VERSION                    VERSION_MAJOR"."VERSION_MINOR"."VERSION_RELEASE\r
-#define FMS_FREESITE_USK       "USK@0npnMrqZNKRCRoGojZV93UNHCMN-6UU3rRSAmP6jNLE,~BG-edFtdCC1cSH4O3BWdeIYa8Sw5DfyrSV-TKdO5ec,AQACAAE/fms/84/"\r
-#define FMS_VERSION_EDITION    "25"\r
+#define FMS_FREESITE_USK       "USK@0npnMrqZNKRCRoGojZV93UNHCMN-6UU3rRSAmP6jNLE,~BG-edFtdCC1cSH4O3BWdeIYa8Sw5DfyrSV-TKdO5ec,AQACAAE/fms/85/"\r
+#define FMS_VERSION_EDITION    "26"\r
 \r
 typedef Poco::ScopedLock<Poco::FastMutex> Guard;\r
 \r
index 16afb7c..f6f2cc0 100644 (file)
@@ -39,6 +39,8 @@ protected:
 \r
        // replaces html elements with encoded characters (i.e. < becomes &lt;)\r
        const std::string SanitizeOutput(const std::string &input);\r
+       // don't replace space with &nbsp;, because browser might convert to unicode non breaking space character\r
+       const std::string SanitizeTextAreaOutput(const std::string &input);\r
 \r
        std::string m_template;\r
        std::string m_pagename;\r
index caaf69d..a919c4d 100644 (file)
@@ -24,12 +24,12 @@ keep the same database unless otherwise noted in the release information.
 \r
 INSTALLATION\r
 ------------\r
-Place the binary, any templates, and the fonts directory in a directory of your\r
-choice.  Windows users may need to download the runtime DLLs available from the\r
-fms Freesite and place in the fms directory if they are not already installed\r
-on the system.  On the first run, a database file will also be created in this\r
-directory.  Make sure the user that runs FMS has read/write access to this\r
-directory.\r
+Place the binary, any templates, and the fonts and images directories in a\r
+directory of your choice.  Windows users may need to download the runtime DLLs\r
+available from the fms Freesite and place in the fms directory if they are not\r
+already installed on the system.  On the first run, a database file will also\r
+be created in this directory.  Make sure the user that runs FMS has read/write\r
+access to this directory.\r
 \r
 RUNNING\r
 -------\r
@@ -64,6 +64,8 @@ WEB INTERFACE
 -------------\r
 By default, a web interface for administration will be running at http://\r
 localhost:8080.  You can use the interface to configure and administer FMS.\r
+There is also a forum built into the web interface so you can read and send\r
+messages without needing to use a newsreader.\r
 \r
 NNTP CONFIGURATION\r
 ------------------\r
index c4606c0..84952d2 100644 (file)
@@ -18,8 +18,6 @@
 #include "../../include/http/pages/peertrustpage.h"\r
 #include "../../include/http/pages/versioninfopage.h"\r
 #include "../../include/http/pages/recentlyaddedpage.h"\r
-#include "../../include/http/pages/browseboardspage.h"\r
-#include "../../include/http/pages/browsemessagespage.h"\r
 #include "../../include/http/pages/forummainpage.h"\r
 #include "../../include/http/pages/showimagepage.h"\r
 #include "../../include/http/pages/forumthreadspage.h"\r
@@ -81,8 +79,6 @@ FMSHTTPRequestHandlerFactory::FMSHTTPRequestHandlerFactory()
        m_pagehandlers.push_back(new PeerTrustPage(templatestr));\r
        m_pagehandlers.push_back(new VersionInfoPage(templatestr));\r
        m_pagehandlers.push_back(new RecentlyAddedPage(templatestr));\r
-       m_pagehandlers.push_back(new BrowseBoardsPage(templatestr));\r
-       m_pagehandlers.push_back(new BrowseMessagesPage(templatestr));\r
        m_pagehandlers.push_back(new ShowImagePage());\r
        m_pagehandlers.push_back(new ForumMainPage(forumtemplate));\r
        m_pagehandlers.push_back(new ForumThreadsPage(forumtemplate));\r
index 52e96f6..560c912 100644 (file)
@@ -152,6 +152,16 @@ const std::string IPageHandler::SanitizeOutput(const std::string &input)
        return output;\r
 }\r
 \r
+const std::string IPageHandler::SanitizeTextAreaOutput(const std::string &input)\r
+{\r
+       // must do & first because all other elements have & in them!\r
+       std::string output=StringFunctions::Replace(input,"&","&amp;");\r
+       output=StringFunctions::Replace(output,"<","&lt;");\r
+       output=StringFunctions::Replace(output,">","&gt;");\r
+       output=StringFunctions::Replace(output,"\"","&quot;");\r
+       return output;\r
+}\r
+\r
 const bool IPageHandler::ValidateFormPassword(const std::map<std::string,std::string> &vars)\r
 {\r
        Poco::DateTime date;\r
index e8f7fd4..bf95295 100644 (file)
@@ -26,7 +26,7 @@ const std::string AnnounceIdentityPage::CreateLocalIdentityDropDown(const std::s
                st.ResultText(1,name);\r
                st.ResultText(2,pubkey);\r
 \r
-               rval+="<option value=\""+id+"\" title=\""+pubkey+"\">"+SanitizeOutput(CreateShortIdentityName(name,pubkey))+"</option>";\r
+               rval+="<option value=\""+id+"\" title=\""+pubkey+"\""+(selected==id?" selected":"")+">"+SanitizeOutput(CreateShortIdentityName(name,pubkey))+"</option>";\r
                st.Step();\r
        }\r
        rval+="</select>";\r
@@ -47,11 +47,11 @@ const std::string AnnounceIdentityPage::GeneratePage(const std::string &method,
        std::string pubkey="";\r
        int requestindex=0;\r
        bool willshow=false;\r
+       std::string localidentityidstr="";\r
 \r
        if(queryvars.find("formaction")!=queryvars.end() && (*queryvars.find("formaction")).second=="announce" && ValidateFormPassword(queryvars))\r
        {\r
                SQLite3DB::Statement insert=m_db->Prepare("INSERT INTO tblIdentityIntroductionInserts(LocalIdentityID,Day,UUID,Solution) VALUES(?,?,?,?);");\r
-               std::string localidentityidstr="";\r
                int localidentityid=0;\r
                std::vector<std::string> uuids;\r
                std::vector<std::string> days;\r
@@ -87,7 +87,7 @@ const std::string AnnounceIdentityPage::GeneratePage(const std::string &method,
        content+="<input type=\"hidden\" name=\"formaction\" value=\"announce\">";\r
        content+="<table>";\r
        content+="<tr><td colspan=\"4\"><center>Select Identity : ";\r
-       content+=CreateLocalIdentityDropDown("localidentityid","");\r
+       content+=CreateLocalIdentityDropDown("localidentityid",localidentityidstr);\r
        content+="</td></tr>";\r
        content+="<tr><td colspan=\"4\"><center>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.</td></tr>";\r
        content+="<tr>";\r
diff --git a/src/http/pages/browseboardspage.cpp b/src/http/pages/browseboardspage.cpp
deleted file mode 100644 (file)
index e759cd6..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-#include "../../../include/http/pages/browseboardspage.h"\r
-#include "../../../include/stringfunctions.h"\r
-\r
-#ifdef XMEM\r
-       #include <xmem.h>\r
-#endif\r
-\r
-const std::string BrowseBoardsPage::BuildQueryString(const long startrow, const std::string &boardsearch, const std::string &sortby, const std::string &sortorder)\r
-{\r
-       std::string returnval="";\r
-       std::string tempval="";\r
-\r
-       if(startrow>=0)\r
-       {\r
-               StringFunctions::Convert(startrow,tempval);\r
-               returnval+="startrow="+tempval;\r
-       }\r
-\r
-       if(boardsearch!="")\r
-       {\r
-               if(returnval!="")\r
-               {\r
-                       returnval+="&";\r
-               }\r
-               returnval+="boardsearch="+boardsearch;\r
-       }\r
-\r
-       if(sortby!="")\r
-       {\r
-               if(returnval!="")\r
-               {\r
-                       returnval+="&";\r
-               }\r
-               returnval+="sortby="+sortby;\r
-               if(sortorder=="ASC" || sortorder=="DESC")\r
-               {\r
-                       if(returnval!="")\r
-                       {\r
-                               returnval+="&";\r
-                       }\r
-                       returnval+="sortorder="+sortorder;\r
-               }\r
-               else\r
-               {\r
-                       if(returnval!="")\r
-                       {\r
-                               returnval+="&";\r
-                       }\r
-                       returnval+="sortorder=ASC";\r
-               }\r
-       }\r
-\r
-       return returnval;\r
-\r
-}\r
-\r
-const std::string BrowseBoardsPage::GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars)\r
-{\r
-       std::string content="";\r
-       std::string sql="";\r
-       std::string boardname="";\r
-       int rowsperpage=25;\r
-       std::string rowsperpagestr="26";        // 1 more than rowsperpage so we know if there are more boards\r
-       long startrow=0;\r
-       std::string startrowstr="0";\r
-       int messagecount=0;\r
-       std::string messagecountstr="0";\r
-       std::string lastdate="";\r
-       int count=0;\r
-       std::string boardsearch="";\r
-       std::string sortby="";\r
-       std::string sortorder="";\r
-\r
-       // if startrow is specified\r
-       if(queryvars.find("startrow")!=queryvars.end())\r
-       {\r
-               startrowstr=(*queryvars.find("startrow")).second;\r
-               // convert back and forth, just in case a number wasn't passed in startrow\r
-               StringFunctions::Convert(startrowstr,startrow);\r
-               if(startrow<0)\r
-               {\r
-                       startrow=0;\r
-               }\r
-               StringFunctions::Convert(startrow,startrowstr);\r
-       }\r
-       if(queryvars.find("boardsearch")!=queryvars.end())\r
-       {\r
-               boardsearch=(*queryvars.find("boardsearch")).second;\r
-       }\r
-       if(queryvars.find("sortby")!=queryvars.end() && queryvars.find("sortorder")!=queryvars.end())\r
-       {\r
-               sortby=(*queryvars.find("sortby")).second;\r
-               sortorder=(*queryvars.find("sortorder")).second;\r
-               if(sortby!="BoardName" && sortby!="MessageCount" && sortby!="LastMessage")\r
-               {\r
-                       sortby="BoardName";\r
-               }\r
-               if(sortorder!="ASC" && sortorder!="DESC")\r
-               {\r
-                       sortorder="ASC";\r
-               }\r
-       }\r
-       else\r
-       {\r
-               sortby="BoardName";\r
-               sortorder="ASC";\r
-       }\r
-\r
-       content="<h2>Browse Messages</h2>";\r
-       content+="<form name=\"frmfilter\" method=\"post\" action=\""+m_pagename+"\">";\r
-       content+="<input type=\"text\" name=\"boardsearch\" value=\""+SanitizeOutput(boardsearch)+"\">";\r
-       content+="<input type=\"submit\" value=\"Filter\">";\r
-       content+="</form>";\r
-\r
-       content+="<table class=\"small90\">";\r
-       content+="<tr>";\r
-       content+="<th><a href=\""+m_pagename+"?"+BuildQueryString(startrow,boardsearch,"BoardName",ReverseSort("BoardName",sortby,sortorder))+"\">Board</a></th>";\r
-       content+="<th><a href=\""+m_pagename+"?"+BuildQueryString(startrow,boardsearch,"MessageCount",ReverseSort("MessageCount",sortby,sortorder))+"\">Message Count</a></th>";\r
-       content+="<th><a href=\""+m_pagename+"?"+BuildQueryString(startrow,boardsearch,"LastMessage",ReverseSort("LastMessage",sortby,sortorder))+"\">Last Message</a></th>";\r
-       content+="</tr>";\r
-\r
-       sql="SELECT tblBoard.BoardID, tblBoard.BoardName, COUNT(tblMessageBoard.MessageID) AS 'MessageCount', MAX(tblMessage.MessageDate || ' ' || tblMessage.MessageTime) AS 'LastMessage'";\r
-       sql+="FROM tblBoard LEFT JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID ";\r
-       sql+="LEFT JOIN tblMessage ON tblMessageBoard.MessageID=tblMessage.MessageID ";\r
-       sql+="WHERE (tblMessageBoard.MessageID>=0 OR tblMessageBoard.MessageID IS NULL) ";\r
-       if(boardsearch!="")\r
-       {\r
-               sql+="AND tblBoard.BoardName LIKE '%' || ? || '%' ";\r
-       }\r
-       sql+="GROUP BY tblBoard.BoardID ";\r
-       sql+="ORDER BY "+sortby+" COLLATE NOCASE "+sortorder+" ";\r
-       sql+="LIMIT "+startrowstr+","+rowsperpagestr+";";\r
-       \r
-       SQLite3DB::Statement st=m_db->Prepare(sql);\r
-       if(boardsearch!="")\r
-       {\r
-               st.Bind(0,boardsearch);\r
-       }\r
-       \r
-       st.Step();\r
-       while(st.RowReturned() && count++<rowsperpage)\r
-       {\r
-               boardname="";\r
-               messagecount=0;\r
-               lastdate="";\r
-               std::string boardidstr="0";\r
-               st.ResultText(0,boardidstr);\r
-               st.ResultText(1,boardname);\r
-               st.ResultInt(2,messagecount);\r
-               st.ResultText(3,lastdate);\r
-\r
-               StringFunctions::Convert(messagecount,messagecountstr);\r
-\r
-               content+="<tr>";\r
-               content+="<td><a href=\"browsemessages.htm?boardid="+boardidstr+"\">"+SanitizeOutput(boardname)+"</a></td>";\r
-               content+="<td>"+SanitizeOutput(messagecountstr)+"</td>";\r
-               content+="<td>"+SanitizeOutput(lastdate)+"</td>";\r
-               content+="</tr>\r\n";\r
-               st.Step();\r
-       }\r
-\r
-       if(startrow>0 || st.RowReturned())\r
-       {\r
-               content+="<tr>";\r
-\r
-               if(startrow>0)\r
-               {\r
-                       int thisstartrow=startrow-rowsperpage;\r
-                       if(thisstartrow<0)\r
-                       {\r
-                               thisstartrow=0;\r
-                       }\r
-                       content+="<td><a href=\"boardsbrowse.htm?"+BuildQueryString(thisstartrow,boardsearch,sortby,sortorder)+"\">&lt;--</a></td>";\r
-               }\r
-               else\r
-               {\r
-                       content+="<td></td>";\r
-               }\r
-\r
-               content+="<td></td>";\r
-\r
-               if(st.RowReturned())\r
-               {\r
-                       int thisstartrow=startrow+rowsperpage;\r
-                       content+="<td><a href=\"boardsbrowse.htm?"+BuildQueryString(thisstartrow,boardsearch,sortby,sortorder)+"\">--&gt;</a></td>";\r
-               }\r
-\r
-               content+="</tr>";\r
-       }\r
-       content+="</table>";\r
-       \r
-       return StringFunctions::Replace(m_template,"[CONTENT]",content);\r
-}\r
-\r
-const std::string BrowseBoardsPage::ReverseSort(const std::string &sortname, const std::string &currentsortby, const std::string &currentsortorder)\r
-{\r
-       if(sortname==currentsortby)\r
-       {\r
-               if(currentsortorder=="ASC")\r
-               {\r
-                       return "DESC";\r
-               }\r
-               else\r
-               {\r
-                       return "ASC";\r
-               }\r
-       }\r
-       else\r
-       {\r
-               return currentsortorder;\r
-       }\r
-}\r
diff --git a/src/http/pages/browsemessagespage.cpp b/src/http/pages/browsemessagespage.cpp
deleted file mode 100644 (file)
index 9601064..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-#include "../../../include/http/pages/browsemessagespage.h"\r
-#include "../../../include/stringfunctions.h"\r
-#include "../../../include/global.h"\r
-#include "../../../include/messagethread.h"\r
-\r
-#ifdef XMEM\r
-       #include <xmem.h>\r
-#endif\r
-\r
-const std::string BrowseMessagesPage::BuildQueryString(const long startrow, const std::string &boardidstr, const std::string &messageidstr)\r
-{\r
-       std::string returnval="";\r
-       std::string tempval="";\r
-\r
-       if(startrow>=0)\r
-       {\r
-               StringFunctions::Convert(startrow,tempval);\r
-               returnval+="startrow="+tempval;\r
-       }\r
-\r
-       if(boardidstr!="")\r
-       {\r
-               if(returnval!="")\r
-               {\r
-                       returnval+="&";\r
-               }\r
-               returnval+="boardid="+boardidstr;\r
-       }\r
-\r
-       if(messageidstr!="")\r
-       {\r
-               if(returnval!="")\r
-               {\r
-                       returnval+="&";\r
-               }       \r
-               returnval+="messageid="+messageidstr;\r
-       }\r
-\r
-       return returnval;\r
-\r
-}\r
-\r
-const std::string BrowseMessagesPage::GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars)\r
-{\r
-       std::string content="";\r
-       long boardid=-1;\r
-       std::string boardidstr="";\r
-       std::string messageidstr="";\r
-       int startrow=0;\r
-       std::string startrowstr="0";\r
-       int rowsperpage=50;\r
-       std::string rowsperpagestr="51";        // one more than rowsperpage so we can know if there are more messages\r
-       std::string sql="";\r
-       int rowcount=0;\r
-       int page=0;\r
-\r
-       // if startrow is specified\r
-       if(queryvars.find("startrow")!=queryvars.end())\r
-       {\r
-               startrowstr=(*queryvars.find("startrow")).second;\r
-               // convert back and forth, just in case a number wasn't passed in startrow\r
-               StringFunctions::Convert(startrowstr,startrow);\r
-               if(startrow<0)\r
-               {\r
-                       startrow=0;\r
-               }\r
-               StringFunctions::Convert(startrow,startrowstr);\r
-       }\r
-       if(queryvars.find("boardid")!=queryvars.end())\r
-       {\r
-               boardidstr=(*queryvars.find("boardid")).second;\r
-               StringFunctions::Convert(boardidstr,boardid);\r
-       }\r
-       if(queryvars.find("messageid")!=queryvars.end())\r
-       {\r
-               messageidstr=(*queryvars.find("messageid")).second;\r
-               page=1;\r
-       }\r
-\r
-       if(page==0)\r
-       {\r
-               sql="SELECT Subject, FromName, MessageDate || ' ' || MessageTime, Body, tblMessage.MessageID ";\r
-               sql+="FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID ";\r
-               if(boardidstr!="")\r
-               {\r
-                       sql+="WHERE tblMessageBoard.BoardID=? ";\r
-               }\r
-               sql+="ORDER BY MessageDate || ' ' || MessageTime DESC ";\r
-               sql+="LIMIT "+startrowstr+","+rowsperpagestr+";";\r
-\r
-               SQLite3DB::Statement st=m_db->Prepare(sql);\r
-               if(boardidstr!="")\r
-               {\r
-                       st.Bind(0,boardidstr);\r
-               }\r
-               st.Step();\r
-\r
-               content+="<table class=\"small90\">";\r
-               content+="<tr><th>Subject</th><th>From</th><th>Date</th></tr>";\r
-\r
-               rowcount=0;\r
-               while(st.RowReturned() && rowcount++<rowsperpage)\r
-               {\r
-                       std::string subject="";\r
-                       std::string fromname="";\r
-                       std::string messagedate="";\r
-                       std::string body="";\r
-                       std::string messageidstr="";\r
-\r
-                       st.ResultText(0,subject);\r
-                       st.ResultText(1,fromname);\r
-                       st.ResultText(2,messagedate);\r
-                       st.ResultText(3,body);\r
-                       st.ResultText(4,messageidstr);\r
-\r
-                       if(body.size()>400)\r
-                       {\r
-                               body.erase(400);\r
-                               body+="...";\r
-                       }\r
-\r
-                       content+="<tr>";\r
-                       content+="<td title=\""+StringFunctions::Replace(SanitizeOutput(body),"\n","\r\n")+"\"><a href=\""+m_pagename+"?"+BuildQueryString(startrow,boardidstr,messageidstr)+"\">"+SanitizeOutput(subject)+"</a></td>";\r
-                       content+="<td>"+fromname+"</td>";\r
-                       content+="<td>"+SanitizeOutput(messagedate)+"</td>";\r
-                       content+="</tr>\r\n";\r
-\r
-                       st.Step();\r
-               }\r
-               \r
-               if(startrow>0 || st.RowReturned())\r
-               {\r
-                       content+="<tr>";\r
-\r
-                       if(startrow>0)\r
-                       {\r
-                               int thisstartrow=startrow-rowsperpage;\r
-                               if(thisstartrow<0)\r
-                               {\r
-                                       thisstartrow=0;\r
-                               }\r
-                               content+="<td><a href=\""+m_pagename+"?"+BuildQueryString(thisstartrow,boardidstr,"")+"\">&lt;--</a></td>";\r
-                       }\r
-                       else\r
-                       {\r
-                               content+="<td></td>";\r
-                       }\r
-\r
-                       content+="<td></td>";\r
-\r
-                       if(st.RowReturned())\r
-                       {\r
-                               int thisstartrow=startrow+rowsperpage;\r
-                               content+="<td><a href=\""+m_pagename+"?"+BuildQueryString(thisstartrow,boardidstr,"")+"\">--&gt;</a></td>";\r
-                       }\r
-                       content+="</tr>";\r
-               }\r
-\r
-               content+="</table>";\r
-       }\r
-       else if(page==1)\r
-       {\r
-               sql="SELECT Body, FromName, MessageDate || ' ' || MessageTime, Subject FROM tblMessage WHERE MessageID=?;";\r
-               SQLite3DB::Statement st=m_db->Prepare(sql);\r
-               st.Bind(0,messageidstr);\r
-\r
-               st.Step();\r
-               if(st.RowReturned())\r
-               {\r
-                       std::string body="";\r
-                       std::string fromname="";\r
-                       std::string messagedate="";\r
-                       std::string subject="";\r
-                       std::string boards="";\r
-\r
-                       st.ResultText(0,body);\r
-                       st.ResultText(1,fromname);\r
-                       st.ResultText(2,messagedate);\r
-                       st.ResultText(3,subject);\r
-\r
-                       // get boards message was posted to\r
-                       SQLite3DB::Statement st2=m_db->Prepare("SELECT tblBoard.BoardID, tblBoard.BoardName FROM tblBoard INNER JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID WHERE tblMessageBoard.MessageID=?;");\r
-                       st2.Bind(0,messageidstr);\r
-                       st2.Step();\r
-                       while(st2.RowReturned())\r
-                       {\r
-                               std::string boardname="";\r
-                               std::string innerboardidstr="";\r
-\r
-                               st2.ResultText(0,innerboardidstr);\r
-                               st2.ResultText(1,boardname);\r
-                               \r
-                               if(boards!="")\r
-                               {\r
-                                       boards+=",&nbsp;";\r
-                               }\r
-\r
-                               boards+="<a href=\""+m_pagename+"?"+BuildQueryString(0,innerboardidstr,"")+"\">"+SanitizeOutput(boardname)+"</a>";\r
-\r
-                               st2.Step();\r
-                       }\r
-\r
-                       content+="<div class=\"post\">";\r
-                       content+="<div class=\"postboards\">";\r
-                       content+=boards;\r
-                       content+="</div>";\r
-                       content+="<div class=\"postsubject\">";\r
-                       content+=SanitizeOutput(subject);\r
-                       content+="</div>";\r
-                       content+="<div class=\"postfrom\">";\r
-                       content+=SanitizeOutput(fromname);\r
-                       content+="</div>";\r
-                       content+="<div class=\"postdate\">";\r
-                       content+=SanitizeOutput(messagedate);\r
-                       content+="</div>";\r
-                       content+="<div class=\"postbody\">";\r
-                       content+=SanitizeOutput(body);\r
-                       content+="</div>";\r
-                       content+="</div>\r\n";\r
-\r
-                       long currentlevel=0;\r
-                       MessageThread thread;\r
-                       thread.Load(messageidstr,boardid);\r
-\r
-                       std::vector<MessageThread::threadnode> nodes=thread.GetNodes();\r
-                       if(nodes.size()>1)\r
-                       {\r
-                               content+="<ul class=\"messagethread\">";\r
-                               for(std::vector<MessageThread::threadnode>::const_iterator i=nodes.begin(); i!=nodes.end(); i++)\r
-                               {\r
-                                       if((*i).m_level>currentlevel)\r
-                                       {\r
-                                               content+="<ul class=\"messagethread\">";\r
-                                       }\r
-                                       else if((*i).m_level<currentlevel)\r
-                                       {\r
-                                               content+="</ul>";\r
-                                       }\r
-                                       currentlevel=(*i).m_level;\r
-\r
-                                       std::string tempstr="";\r
-                                       StringFunctions::Convert((*i).m_messageid,tempstr);\r
-\r
-                                       content+="<li>";\r
-                                       if(tempstr!=messageidstr)\r
-                                       {\r
-                                               content+="<a href=\""+m_pagename+"?"+BuildQueryString(0,boardidstr,tempstr)+"\">"+SanitizeOutput((*i).m_subject)+"</a> - "+SanitizeOutput((*i).m_fromname);\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               content+=SanitizeOutput((*i).m_subject)+" - "+SanitizeOutput((*i).m_fromname);\r
-                                       }\r
-                                       content+="</li>\r\n";\r
-                               }\r
-                               while(currentlevel-->0)\r
-                               {\r
-                                       content+="</ul>";\r
-                               }\r
-                               content+="</ul>\r\n";\r
-                       }\r
-               }\r
-       }\r
-\r
-       return StringFunctions::Replace(m_template,"[CONTENT]",content);\r
-}\r
index ac9ed16..1896143 100644 (file)
@@ -118,7 +118,7 @@ const std::string ForumCreatePostPage::GeneratePage(const std::string &method, c
                                replyst.ResultText(0,subject);\r
                                replyst.ResultText(1,body);\r
 \r
-                               if(subject.size()<3 || (subject.substr(0,2)!="re:" && subject.substr(0,2)!="Re:"))\r
+                               if(subject.size()<3 || (subject.substr(0,3)!="re:" && subject.substr(0,3)!="Re:"))\r
                                {\r
                                        subject="Re: "+subject;\r
                                }\r
@@ -184,7 +184,7 @@ const std::string ForumCreatePostPage::GeneratePage(const std::string &method, c
                content+="<table class=\"createpost\">";\r
                content+="<tr><td class=\"identity\">From</td><td>"+LocalIdentityDropDown("localidentityid",localidentityidstr)+"</td></tr>";\r
                content+="<tr><td class=\"subject\">Subject</td><td><input type=\"text\" name=\"subject\" maxlength=\"60\" size=\"60\" value=\""+SanitizeOutput(subject)+"\"></td></tr>";\r
-               content+="<tr><td class=\"body\">Message</td><td><textarea name=\"body\" cols=\"80\" rows=\"30\">"+SanitizeOutput(body)+"</textarea></td></tr>";\r
+               content+="<tr><td class=\"body\">Message</td><td><textarea name=\"body\" cols=\"80\" rows=\"30\">"+SanitizeTextAreaOutput(body)+"</textarea></td></tr>";\r
                content+="<tr><td colspan=\"2\" class=\"send\"><input type=\"submit\" value=\"Send\"></td></tr>";\r
                content+="</table>\r\n";\r
                content+="</form>";\r
index 0b69926..d99768d 100644 (file)
@@ -10,6 +10,8 @@ const std::string ForumViewThreadPage::FixBody(const std::string &body)
        static std::string whitespace=" \t\r\n";\r
        std::string output=body;\r
 \r
+       output=StringFunctions::Replace(output,"\r\n","\n");\r
+\r
        // put \n after 80 contiguous characters in the body\r
        std::string::size_type prevpos=0;\r
        std::string::size_type pos=output.find_first_of(whitespace);\r
@@ -42,6 +44,7 @@ const std::string ForumViewThreadPage::GeneratePage(const std::string &method, c
        std::string boardidstr="";\r
        std::string currentpagestr="";\r
        std::string boardname="";\r
+       std::string firstunreadidstr="";\r
 \r
        if(queryvars.find("threadid")!=queryvars.end())\r
        {\r
@@ -58,6 +61,14 @@ const std::string ForumViewThreadPage::GeneratePage(const std::string &method, c
 \r
        content+=CreateForumHeader();\r
 \r
+       SQLite3DB::Statement firstunreadst=m_db->Prepare("SELECT tblMessage.MessageID FROM tblThreadPost INNER JOIN tblMessage ON tblThreadPost.MessageID=tblMessage.MessageID WHERE ThreadID=? AND tblMessage.Read=0;");\r
+       firstunreadst.Bind(0,threadidstr);\r
+       firstunreadst.Step();\r
+       if(firstunreadst.RowReturned())\r
+       {\r
+               firstunreadst.ResultText(0,firstunreadidstr);\r
+       }\r
+\r
        SQLite3DB::Statement updateread=m_db->Prepare("UPDATE tblMessage SET Read=1 WHERE tblMessage.MessageID IN (SELECT MessageID FROM tblThreadPost WHERE ThreadID=?);");\r
        updateread.Bind(0,threadidstr);\r
        updateread.Step();\r
@@ -76,6 +87,12 @@ const std::string ForumViewThreadPage::GeneratePage(const std::string &method, c
        content+="<table class=\"forumheader\">";\r
        content+="<tr>";\r
        content+="<td> Forum : <a href=\"forumthreads.htm?boardid="+boardidstr+"&currentpage="+currentpagestr+"\">"+SanitizeOutput(boardname)+"</a></td>";\r
+       if(firstunreadidstr!="")\r
+       {\r
+               content+="<td>";\r
+               content+="<a href=\"#"+firstunreadidstr+"\">First Unread Message</a>";\r
+               content+="</td>";\r
+       }\r
        content+="</tr>";\r
        content+="</table>\r\n";\r
 \r
@@ -123,7 +140,7 @@ const std::string ForumViewThreadPage::GeneratePage(const std::string &method, c
 \r
                        content+="<table class=\"trust\">";\r
                        content+="<tr>";\r
-                       content+="<td colspan=\"3\" style=\"text-align:center;\"><a href=\"peertrust.htm?namesearch="+name+"\">Trust</a></td>";\r
+                       content+="<td colspan=\"3\" style=\"text-align:center;\"><a href=\"peertrust.htm?namesearch="+StringFunctions::UriEncode(name)+"\">Trust</a></td>";\r
                        content+="</tr>";\r
                        content+="<tr>";\r
                        content+="<td></td><td>Local</td><td>Peer</td>";\r
index d80ae18..91d960f 100644 (file)
@@ -23,7 +23,7 @@ const std::string PeerTrustPage::BuildQueryString(const long startrow, const std
                {\r
                        returnval+="&";\r
                }\r
-               returnval+="namesearch="+namesearch;\r
+               returnval+="namesearch="+StringFunctions::UriEncode(namesearch);\r
        }\r
 \r
        if(sortby!="")\r
index 521cccc..175a34a 100644 (file)
@@ -62,10 +62,17 @@ const bool ThreadBuilder::Build(const long messageid, const long boardid, const
                st.Bind(0,threadid);\r
                st.Step();\r
 \r
+               SQLite3DB::Statement deleteotherst=m_db->Prepare("DELETE FROM tblThread WHERE ThreadID IN (SELECT tblThread.ThreadID FROM tblThreadPost INNER JOIN tblThread ON tblThreadPost.ThreadID=tblThread.ThreadID WHERE tblThread.BoardID=? AND tblThreadPost.MessageID=?);");\r
+\r
                count=0;\r
                st=m_db->Prepare("INSERT INTO tblThreadPost(ThreadID,MessageID,PostOrder) VALUES(?,?,?);");\r
                for(std::vector<MessageThread::threadnode>::const_iterator i=m_threadmessages.begin(); i!=m_threadmessages.end(); i++, count++)\r
                {\r
+                       deleteotherst.Bind(0,boardid);\r
+                       deleteotherst.Bind(1,(*i).m_messageid);\r
+                       deleteotherst.Step();\r
+                       deleteotherst.Reset();\r
+\r
                        st.Bind(0,threadid);\r
                        st.Bind(1,(*i).m_messageid);\r
                        st.Bind(2,count);\r