virtual const char *GetField(const int field);\r
virtual const int GetInt(const int field);\r
virtual const double GetDouble(const int field);\r
+ virtual const char *GetColumnName(const int column);\r
\r
virtual void Open(const std::string &sql, DB *db);\r
\r
#ifndef _identity_requester_\r
#define _identity_requester_\r
\r
-#include "../idatabase.h"\r
-#include "../ilogger.h"\r
-#include "../datetime.h"\r
-#include "ifreenetregistrable.h"\r
-#include "ifcpconnected.h"\r
-#include "ifcpmessagehandler.h"\r
-#include "iperiodicprocessor.h"\r
+#include "iindexrequester.h"\r
\r
-class IdentityRequester:public IFreenetRegistrable,public IFCPConnected,public IFCPMessageHandler,public IPeriodicProcessor,public IDatabase,public ILogger\r
+class IdentityRequester:public IIndexRequester<long>\r
{\r
public:\r
IdentityRequester();\r
IdentityRequester(FCPv2 *fcp);\r
\r
- void FCPConnected();\r
- void FCPDisconnected();\r
-\r
- const bool HandleMessage(FCPMessage &message);\r
-\r
- void Process();\r
-\r
- void RegisterWithThread(FreenetMasterThread *thread);\r
-\r
private:\r
void Initialize();\r
void PopulateIDList(); // clear and re-populate m_ids with identities we want to query\r
- void StartRequest(const long identityid);\r
+ void StartRequest(const long &identityid);\r
const bool HandleAllData(FCPMessage &message);\r
const bool HandleGetFailed(FCPMessage &message);\r
- void RemoveFromRequestList(const long identityid);\r
-\r
- DateTime m_tempdate;\r
- long m_maxrequests;\r
- std::string m_messagebase;\r
- std::vector<long> m_requesting; // list of ids we are currently requesting from\r
- std::map<long,bool> m_ids; // map of all ids we know and whether we have requested file from them yet\r
\r
};\r
\r
virtual void RemoveFromRequestList(const IDTYPE id);\r
\r
DateTime m_tempdate;\r
+ DateTime m_lastreceived;\r
+ DateTime m_lastpopulated;\r
std::string m_messagebase;\r
std::map<IDTYPE,bool> m_ids; // map of all ids we know and whether we have requested file from them yet\r
std::vector<IDTYPE> m_requesting; // list of ids we are currently requesting from\r
\r
m_requesting.clear();\r
PopulateIDList();\r
+ m_lastreceived.SetToGMTime();\r
+ m_lastpopulated.SetToGMTime();\r
}\r
\r
template <class IDTYPE>\r
\r
if(message["Identifier"].find(m_fcpuniquename)==0)\r
{\r
+\r
+ m_lastreceived.SetToGMTime();\r
+\r
if(message.GetName()=="DataFound")\r
{\r
return true;\r
\r
Option::Instance()->Get("MessageBase",m_messagebase);\r
m_tempdate.SetToGMTime();\r
+ m_lastreceived.SetToGMTime();\r
+ m_lastpopulated.SetToGMTime();\r
+ m_lastpopulated.Add(0,-10);\r
}\r
\r
template <class IDTYPE>\r
void IIndexRequester<IDTYPE>::Process()\r
{\r
+ DateTime now;\r
+ now.SetToGMTime();\r
+\r
// max is the smaller of the config value or the total number of ids we will request from\r
typename std::map<IDTYPE,bool>::size_type max=m_maxrequests>m_ids.size() ? m_ids.size() : m_maxrequests;\r
\r
}\r
else\r
{\r
- // we requested from all ids in the list, repopulate the list\r
- PopulateIDList();\r
+ // we requested from all ids in the list, repopulate the list (only every 10 minutes)\r
+ if(m_lastpopulated<(now-1.0/144.0))\r
+ {\r
+ PopulateIDList();\r
+ m_lastpopulated.SetToGMTime();\r
+ }\r
}\r
}\r
// special case - if there were 0 ids on the list when we started then we will never get a chance to repopulate the list\r
// this will recheck for ids every minute\r
- DateTime now;\r
- now.SetToGMTime();\r
if(m_ids.size()==0 && m_tempdate<(now-(1.0/1440.0)))\r
{\r
PopulateIDList();\r
m_tempdate=now;\r
}\r
+ // if we haven't received any messages to this object in 10 minutes, clear the requests and repopulate id list\r
+ if(m_ids.size()>0 && m_lastreceived<(now-(1.0/144.0)))\r
+ {\r
+ m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"IIndexRequester<IDTYPE>::Process() Object has not received any messages in 10 minutes. Restarting requests.");\r
+ FCPConnected();\r
+ }\r
\r
}\r
\r
#ifndef _trustlistrequester_\r
#define _trustlistrequester_\r
\r
-#include "../idatabase.h"\r
-#include "../ilogger.h"\r
-#include "../datetime.h"\r
-#include "ifreenetregistrable.h"\r
-#include "ifcpconnected.h"\r
-#include "ifcpmessagehandler.h"\r
-#include "iperiodicprocessor.h"\r
+#include "iindexrequester.h"\r
\r
-class TrustListRequester:public IFreenetRegistrable,public IFCPConnected,public IFCPMessageHandler,public IPeriodicProcessor,public IDatabase,public ILogger\r
+class TrustListRequester:public IIndexRequester<long>//public IFreenetRegistrable,public IFCPConnected,public IFCPMessageHandler,public IPeriodicProcessor,public IDatabase,public ILogger\r
{\r
public:\r
TrustListRequester();\r
TrustListRequester(FCPv2 *fcp);\r
\r
- void FCPDisconnected();\r
- void FCPConnected();\r
-\r
- const bool HandleMessage(FCPMessage &message);\r
-\r
- void Process();\r
-\r
- void RegisterWithThread(FreenetMasterThread *thread);\r
-\r
private:\r
void Initialize();\r
void PopulateIDList(); // clear and re-populate m_ids with identities we want to query\r
- void StartRequest(const long identityid);\r
+ void StartRequest(const long &identityid);\r
const bool HandleAllData(FCPMessage &message);\r
const bool HandleGetFailed(FCPMessage &message);\r
- void RemoveFromRequestList(const long identityid);\r
\r
- DateTime m_tempdate;\r
- std::string m_messagebase;\r
- long m_maxrequests;\r
- std::vector<long> m_requesting; // list of ids we are currently requesting from\r
- std::map<long,bool> m_ids; // map of all ids we know and whether we have requested file from them yet\r
- \r
};\r
\r
#endif // _trustlistrequester_\r
//#include <zthread/Thread.h>\r
#include "pthreadwrapper/thread.h"\r
\r
-#define FMS_VERSION "0.1.14"\r
+#define FMS_VERSION "0.1.15"\r
\r
// opens database and creates tables and initial inserts if necessary\r
void SetupDB();\r
}\r
}\r
\r
+const char *Recordset::GetColumnName(const int column)\r
+{\r
+ if(column>=0 && column<m_cols)\r
+ {\r
+ return m_rs[column];\r
+ }\r
+ else\r
+ {\r
+ return NULL;\r
+ }\r
+}\r
+\r
const double Recordset::GetDouble(const int field)\r
{\r
const char *result=GetField(field);\r
if(name!="" && description!="")\r
{\r
std::string lowername=name;\r
- StringFunctions::Convert(lowername,lowername);\r
+ StringFunctions::LowerCase(lowername,lowername);\r
m_boards.push_back(board(lowername,description));\r
}\r
}\r
\r
for(std::vector<board>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
{\r
+ std::string boardname=(*i).m_name;\r
+ StringFunctions::Convert(boardname,boardname);\r
TiXmlElement *tr=new TiXmlElement("Board");\r
tid->LinkEndChild(tr);\r
- tr->LinkEndChild(XMLCreateCDATAElement("Name",(*i).m_name));\r
+ tr->LinkEndChild(XMLCreateCDATAElement("Name",boardname));\r
tr->LinkEndChild(XMLCreateCDATAElement("Description",(*i).m_description));\r
}\r
\r
Initialize();\r
}\r
\r
-IdentityRequester::IdentityRequester(FCPv2 *fcp):IFCPConnected(fcp)\r
+IdentityRequester::IdentityRequester(FCPv2 *fcp):IIndexRequester<long>(fcp)\r
{\r
Initialize();\r
}\r
\r
-void IdentityRequester::FCPConnected()\r
-{\r
- m_requesting.clear();\r
- PopulateIDList();\r
-}\r
-\r
-void IdentityRequester::FCPDisconnected()\r
-{\r
- \r
-}\r
-\r
const bool IdentityRequester::HandleAllData(FCPMessage &message)\r
{\r
DateTime now;\r
\r
}\r
\r
-const bool IdentityRequester::HandleMessage(FCPMessage &message)\r
-{\r
-\r
- if(message["Identifier"].find("IdentityRequester")==0)\r
- {\r
- if(message.GetName()=="DataFound")\r
- {\r
- return true;\r
- }\r
-\r
- if(message.GetName()=="AllData")\r
- {\r
- return HandleAllData(message);\r
- }\r
-\r
- if(message.GetName()=="GetFailed")\r
- {\r
- return HandleGetFailed(message);\r
- }\r
-\r
- if(message.GetName()=="IdentifierCollision")\r
- {\r
- // remove one of the ids from the requesting list\r
- long identityid=0;\r
- std::vector<std::string> idparts;\r
- StringFunctions::Split(message["Identifier"],"|",idparts);\r
- StringFunctions::Convert(idparts[1],identityid);\r
- RemoveFromRequestList(identityid);\r
- return true;\r
- }\r
- }\r
-\r
- return false;\r
-}\r
-\r
void IdentityRequester::Initialize()\r
{\r
std::string tempval="";\r
+ m_fcpuniquename="IdentityRequester";\r
Option::Instance()->Get("MaxIdentityRequests",tempval);\r
StringFunctions::Convert(tempval,m_maxrequests);\r
if(m_maxrequests<1)\r
{\r
m_log->WriteLog(LogFile::LOGLEVEL_WARNING,"Option MaxIdentityRequests is currently set at "+tempval+". This value might be incorrectly configured.");\r
}\r
- Option::Instance()->Get("MessageBase",m_messagebase);\r
- m_tempdate.SetToGMTime();\r
}\r
\r
void IdentityRequester::PopulateIDList()\r
}\r
}\r
\r
-void IdentityRequester::Process()\r
-{\r
- // max is the smaller of the config value or the total number of identities we will request from\r
- long max=m_maxrequests>m_ids.size() ? m_ids.size() : m_maxrequests;\r
-\r
- // try to keep up to max requests going\r
- if(m_requesting.size()<max)\r
- {\r
- std::map<long,bool>::iterator i=m_ids.begin();\r
- while(i!=m_ids.end() && (*i).second==true)\r
- {\r
- i++;\r
- }\r
-\r
- if(i!=m_ids.end())\r
- {\r
- StartRequest((*i).first);\r
- }\r
- else\r
- {\r
- // we requested from all ids in the list, repopulate the list\r
- PopulateIDList();\r
- }\r
- }\r
- // special case - if there were 0 identities on the list when we started then we will never get a chance to repopulate the list\r
- // this will recheck for ids every minute\r
- DateTime now;\r
- now.SetToGMTime();\r
- if(m_ids.size()==0 && m_tempdate<(now-(1.0/1440.0)))\r
- {\r
- PopulateIDList();\r
- m_tempdate=now;\r
- }\r
-\r
-}\r
-\r
-void IdentityRequester::RemoveFromRequestList(const long identityid)\r
-{\r
- std::vector<long>::iterator i=m_requesting.begin();\r
- while(i!=m_requesting.end() && (*i)!=identityid)\r
- {\r
- i++;\r
- }\r
- if(i!=m_requesting.end())\r
- {\r
- m_requesting.erase(i);\r
- }\r
-}\r
-\r
-void IdentityRequester::RegisterWithThread(FreenetMasterThread *thread)\r
-{\r
- thread->RegisterFCPConnected(this);\r
- thread->RegisterFCPMessageHandler(this);\r
- thread->RegisterPeriodicProcessor(this);\r
-}\r
-\r
-void IdentityRequester::StartRequest(const long identityid)\r
+void IdentityRequester::StartRequest(const long &identityid)\r
{\r
DateTime now;\r
FCPMessage message;\r
\r
message.SetName("ClientGet");\r
message["URI"]=publickey+m_messagebase+"|"+now.Format("%Y-%m-%d")+"|Identity|"+indexstr+".xml";\r
- message["Identifier"]="IdentityRequester|"+identityidstr+"|"+indexstr+"|"+message["URI"];\r
+ message["Identifier"]=m_fcpuniquename+"|"+identityidstr+"|"+indexstr+"|"+message["URI"];\r
message["ReturnType"]="direct";\r
message["MaxSize"]="10000"; // 10 KB\r
\r
if(boards.size()<=0)\r
{\r
m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Message XML did not contain any boards! "+message["Identifier"]);\r
+ // remove this identityid from request list\r
+ RemoveFromRequestList(idparts[1]); \r
return true;\r
}\r
if(xml.GetReplyBoard()=="")\r
{\r
m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Message XML did not contain a reply board! "+message["Identifier"]);\r
+ // remove this identityid from request list\r
+ RemoveFromRequestList(idparts[1]); \r
return true;\r
}\r
\r
tid->LinkEndChild(brds);\r
for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
{\r
- brds->LinkEndChild(XMLCreateCDATAElement("Board",(*i)));\r
+ std::string boardname=(*i);\r
+ StringFunctions::Convert(boardname,boardname);\r
+ brds->LinkEndChild(XMLCreateCDATAElement("Board",boardname));\r
}\r
\r
if(m_inreplyto.size()>0)\r
void PeriodicDBMaintenance::Do1HourMaintenance()\r
{\r
// recalculate all trust levels - this is CPU instensive\r
- // TODO - will probably have to change this to do 1 identity at a time as this locks that database for the duration\r
- m_db->Execute("UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);");\r
+ // do 1 identity at a time as doing it with 1 UPDATE statement locks that database for the duration\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT TargetIdentityID,PeerMessageTrust,PeerTrustListTrust FROM vwCalculatedPeerTrust;");\r
+ SQLite3DB::Statement upd=m_db->Prepare("UPDATE tblIdentity SET PeerMessageTrust=?, PeerTrustListTrust=? WHERE IdentityID=?");\r
+ st.Step();\r
+ while(st.RowReturned())\r
+ {\r
+ int identityid=0;\r
+ int trust=0;\r
+ \r
+ st.ResultInt(0,identityid);\r
+\r
+ upd.Bind(0,identityid);\r
+ if(st.ResultNull(1)==false)\r
+ {\r
+ trust=0;\r
+ st.ResultInt(1,trust);\r
+ upd.Bind(0,trust);\r
+ }\r
+ else\r
+ {\r
+ upd.Bind(0);\r
+ }\r
+ if(st.ResultNull(2)==false)\r
+ {\r
+ trust=0;\r
+ st.ResultInt(2,trust);\r
+ upd.Bind(1,trust);\r
+ }\r
+ else\r
+ {\r
+ upd.Bind(1);\r
+ }\r
+ upd.Bind(2,identityid);\r
+ upd.Step();\r
+ upd.Reset();\r
+\r
+ st.Step();\r
+ }\r
+\r
+\r
\r
m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"PeriodicDBMaintenance::Do1HourMaintenance");\r
}\r
Initialize();\r
}\r
\r
-TrustListRequester::TrustListRequester(FCPv2 *fcp):IFCPConnected(fcp)\r
+TrustListRequester::TrustListRequester(FCPv2 *fcp):IIndexRequester<long>(fcp)\r
{\r
Initialize();\r
}\r
\r
-void TrustListRequester::FCPConnected()\r
-{\r
- m_requesting.clear();\r
- PopulateIDList();\r
-}\r
-\r
-void TrustListRequester::FCPDisconnected()\r
-{\r
- \r
-}\r
-\r
const bool TrustListRequester::HandleAllData(FCPMessage &message)\r
{\r
DateTime now;\r
\r
}\r
\r
-const bool TrustListRequester::HandleMessage(FCPMessage &message)\r
-{\r
-\r
- if(message["Identifier"].find("TrustListRequester")==0)\r
- {\r
- if(message.GetName()=="DataFound")\r
- {\r
- return true;\r
- }\r
-\r
- if(message.GetName()=="AllData")\r
- {\r
- return HandleAllData(message);\r
- }\r
-\r
- if(message.GetName()=="GetFailed")\r
- {\r
- return HandleGetFailed(message);\r
- }\r
-\r
- if(message.GetName()=="IdentifierCollision")\r
- {\r
- // remove one of the ids from the requesting list\r
- long identityid=0;\r
- std::vector<std::string> idparts;\r
- StringFunctions::Split(message["Identifier"],"|",idparts);\r
- StringFunctions::Convert(idparts[1],identityid);\r
- RemoveFromRequestList(identityid);\r
- return true;\r
- }\r
- }\r
-\r
- return false;\r
-}\r
-\r
void TrustListRequester::Initialize()\r
{\r
std::string tempval="";\r
+ m_fcpuniquename="TrustListRequester";\r
Option::Instance()->Get("MaxIdentityRequests",tempval);\r
StringFunctions::Convert(tempval,m_maxrequests);\r
if(m_maxrequests<1)\r
{\r
m_log->WriteLog(LogFile::LOGLEVEL_WARNING,"Option MaxTrustListRequests is currently set at "+tempval+". This value might be incorrectly configured.");\r
}\r
- Option::Instance()->Get("MessageBase",m_messagebase);\r
m_tempdate.SetToGMTime();\r
}\r
\r
}\r
}\r
\r
-void TrustListRequester::Process()\r
-{\r
- // max is the smaller of the config value or the total number of identities we will request from\r
- long max=m_maxrequests>m_ids.size() ? m_ids.size() : m_maxrequests;\r
-\r
- // try to keep up to max requests going\r
- if(m_requesting.size()<max)\r
- {\r
- std::map<long,bool>::iterator i=m_ids.begin();\r
- while(i!=m_ids.end() && (*i).second==true)\r
- {\r
- i++;\r
- }\r
-\r
- if(i!=m_ids.end())\r
- {\r
- StartRequest((*i).first);\r
- }\r
- else\r
- {\r
- // we requested from all ids in the list, repopulate the list\r
- PopulateIDList();\r
- }\r
- }\r
- // special case - if there were 0 identities on the list when we started then we will never get a chance to repopulate the list\r
- // this will recheck for ids every minute\r
- DateTime now;\r
- now.SetToGMTime();\r
- if(m_ids.size()==0 && m_tempdate<(now-(1.0/1440.0)))\r
- {\r
- PopulateIDList();\r
- m_tempdate=now;\r
- }\r
-\r
-}\r
-\r
-void TrustListRequester::RegisterWithThread(FreenetMasterThread *thread)\r
-{\r
- thread->RegisterFCPConnected(this);\r
- thread->RegisterFCPMessageHandler(this);\r
- thread->RegisterPeriodicProcessor(this);\r
-}\r
-\r
-void TrustListRequester::RemoveFromRequestList(const long identityid)\r
-{\r
- std::vector<long>::iterator i=m_requesting.begin();\r
- while(i!=m_requesting.end() && (*i)!=identityid)\r
- {\r
- i++;\r
- }\r
- if(i!=m_requesting.end())\r
- {\r
- m_requesting.erase(i);\r
- }\r
-}\r
-\r
-void TrustListRequester::StartRequest(const long identityid)\r
+void TrustListRequester::StartRequest(const long &identityid)\r
{\r
DateTime now;\r
FCPMessage message;\r
\r
message.SetName("ClientGet");\r
message["URI"]=publickey+m_messagebase+"|"+now.Format("%Y-%m-%d")+"|TrustList|"+indexstr+".xml";\r
- message["Identifier"]="TrustListRequester|"+identityidstr+"|"+indexstr+"|"+message["URI"];\r
+ message["Identifier"]=m_fcpuniquename+"|"+identityidstr+"|"+indexstr+"|"+message["URI"];\r
message["ReturnType"]="direct";\r
message["MaxSize"]="1000000"; // 1 MB\r
\r
content+="<tr><td colspan=\"4\"><center>Select Identity : ";\r
content+=CreateLocalIdentityDropDown("localidentityid","");\r
content+="</td></tr>";\r
- content+="<tr><td colspan=\"4\"><center>Type the answers of a few puzzles. The puzzles are case sensitive.</td></tr>";\r
+ content+="<tr><td colspan=\"4\"><center>Type the answers of a few puzzles. The puzzles 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.</td></tr>";\r
content+="<tr>";\r
\r
\r
std::string boarddescription="";\r
\r
boardname=(*queryvars.find("boardname")).second;\r
+ StringFunctions::LowerCase(boardname,boardname);\r
boarddescription=(*queryvars.find("boarddescription")).second;\r
\r
SQLite3DB::Statement addst=m_db->Prepare("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES(?,?,?);");\r
content+="</tr>";\r
\r
content+="<tr>";\r
- content+="<td><form name=\"frmaddboard\" method=\"POST\"><input type=\"hidden\" name=\"formaction\" value=\"addboard\"><input type=\"text\" name=\"boardname\"></td><td><input type=\"text\" name=\"boarddescription\" size=\"40\"></td><td><input type=\"submit\" value=\"Add Board\"></form></td>";\r
+ content+="<td><form name=\"frmaddboard\" method=\"POST\"><input type=\"hidden\" name=\"formaction\" value=\"addboard\"><input type=\"text\" name=\"boardname\"></td><td><input type=\"text\" name=\"boarddescription\" size=\"40\" maxlength=\"50\"></td><td><input type=\"submit\" value=\"Add Board\"></form></td>";\r
content+="</tr>";\r
\r
content+="<tr><td colspan=\"3\"><hr><form name=\"frmboards\" method=\"POST\"><input type=\"hidden\" name=\"formaction\" value=\"update\"></td></tr>";\r
content+="<td>"+SanitizeOutput(boardname)+"</td>";\r
content+="<td><input type=\"hidden\" name=\"boardid["+rownumstr+"]\" value=\""+boardidstr+"\">";\r
content+="<input type=\"hidden\" name=\"oldboarddescription["+rownumstr+"]\" value=\""+StringFunctions::Replace(SanitizeOutput(boarddescription)," "," ")+"\">";\r
- content+="<input type=\"text\" name=\"boarddescription["+rownumstr+"]\" value=\""+SanitizeOutput(boarddescription)+"\" size=\"40\"></td>";\r
+ content+="<input type=\"text\" name=\"boarddescription["+rownumstr+"]\" value=\""+SanitizeOutput(boarddescription)+"\" size=\"40\" maxlength=\"50\"></td>";\r
content+="<td>";\r
content+="<input type=\"hidden\" name=\"oldsavereceivedmessages["+rownumstr+"]\" value=\""+savereceivedmessages+"\">";\r
content+="<input type=\"checkbox\" name=\"savereceivedmessages["+rownumstr+"]\" value=\"true\"";\r
SQLite3DB::Recordset rs=m_db->Query((*queryvars.find("query")).second);\r
\r
content+="<table>";\r
+ if(rs.Count()>0)\r
+ {\r
+ content+="<tr>";\r
+ for(int i=0; i<rs.Cols(); i++)\r
+ {\r
+ content+="<th>";\r
+ if(rs.GetColumnName(i))\r
+ {\r
+ content+=rs.GetColumnName(i);\r
+ }\r
+ content+="</th>";\r
+ }\r
+ content+="<tr>";\r
+ }\r
while(!rs.AtEnd())\r
{\r
content+="<tr>";\r
\r
content+="<tr><td colspan=\"5\"><center><input type=\"submit\" value=\"Update Selected\"> <input type=\"submit\" value=\"Delete Selected\" onClick=\"if(confirm('Delete Selected Identities?')){frmlocalidentity.formaction.value='delete';}else{return false;}\"></td></tr>";\r
content+="</table>";\r
- content+="<p class=\"paragraph=\">* An identity is considered successfully announced when you have downloaded a trust list from someone that contains the identity.</p>";\r
+ content+="<p class=\"paragraph\">* An identity is considered successfully announced when you have downloaded a trust list from someone that contains the identity.</p>";\r
+ content+="<p class=\"paragraph\">Single Use Identities will automatically be deleted 7 days after creation.</p>";\r
\r
return "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"+StringFunctions::Replace(m_template,"[CONTENT]",content);\r
}\r
StringFunctions::Convert((*queryvars.find("daysago")).second,tempint);\r
date.SetToGMTime();\r
date.Add(0,0,0,-tempint);\r
- st=m_db->Prepare("DELETE FROM tblIdentity WHERE IdentityID NOT IN (SELECT IdentityID FROM tblMessage GROUP BY IdentityID) AND LastSeen<?;");\r
+ st=m_db->Prepare("DELETE FROM tblIdentity WHERE LastSeen<?;");\r
+ st.Bind(0,date.Format("%Y-%m-%d %H:%M:%S"));\r
+ st.Step();\r
+ }\r
+ else if((*queryvars.find("formaction")).second=="removenulldaysago" && queryvars.find("daysago")!=queryvars.end() && (*queryvars.find("daysago")).second!="")\r
+ {\r
+ int tempint=10000;\r
+ StringFunctions::Convert((*queryvars.find("daysago")).second,tempint);\r
+ date.SetToGMTime();\r
+ date.Add(0,0,0,-tempint);\r
+ st=m_db->Prepare("DELETE FROM tblIdentity WHERE LastSeen<? AND LocalMessageTrust IS NULL AND LocalTrustListTrust IS NULL;");\r
st.Bind(0,date.Format("%Y-%m-%d %H:%M:%S"));\r
st.Step();\r
}\r
content+="<td><input type=\"submit\" value=\"Remove\"></form></td>";\r
content+="</tr>";\r
\r
+ content+="<tr>";\r
+ content+="<td><form name=\"frmdelete\" method=\"POST\"><input type=\"hidden\" name=\"formaction\" value=\"removenulldaysago\"></td>";\r
+ content+="<td>last seen <input type=\"text\" name=\"daysago\" size=\"2\"> days ago, and have null local trust</td>";\r
+ content+="<td><input type=\"submit\" value=\"Remove\"></form></td>";\r
+ content+="</tr>";\r
+\r
content+="</table>";\r
\r
return "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"+StringFunctions::Replace(m_template,"[CONTENT]",content);\r