store and display dates in history. Needs more work

This commit is contained in:
dockes 2005-11-28 15:31:01 +00:00
parent 30bf4052f8
commit 80ae403a15
7 changed files with 99 additions and 61 deletions

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: main.cpp,v 1.19 2005-11-25 10:26:35 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: main.cpp,v 1.20 2005-11-28 15:31:01 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
#include <unistd.h> #include <unistd.h>
@ -36,7 +36,7 @@ int recollNeedsExit;
string tmpdir; string tmpdir;
bool showicons; bool showicons;
string iconsdir; string iconsdir;
RclQHistory *history; RclDHistory *history;
void getQueryStemming(bool &dostem, std::string &stemlang) void getQueryStemming(bool &dostem, std::string &stemlang)
{ {
@ -172,7 +172,7 @@ int main( int argc, char ** argv )
string historyfile = rclconfig->getConfDir(); string historyfile = rclconfig->getConfDir();
path_cat(historyfile, "history"); path_cat(historyfile, "history");
history = new RclQHistory(historyfile); history = new RclDHistory(historyfile);
dbdir = path_tildexpand(dbdir); dbdir = path_tildexpand(dbdir);

View File

@ -1,6 +1,6 @@
#ifndef _RECOLL_H_INCLUDED_ #ifndef _RECOLL_H_INCLUDED_
#define _RECOLL_H_INCLUDED_ #define _RECOLL_H_INCLUDED_
/* @(#$Id: recoll.h,v 1.6 2005-11-25 10:02:36 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: recoll.h,v 1.7 2005-11-28 15:31:01 dockes Exp $ (C) 2004 J.F.Dockes */
#include <string> #include <string>
#include <list> #include <list>
@ -20,7 +20,7 @@ extern Rcl::Db *rcldb;
extern std::string tmpdir; extern std::string tmpdir;
extern bool showicons; extern bool showicons;
extern string iconsdir; extern string iconsdir;
extern RclQHistory *history; extern RclDHistory *history;
extern int recollNeedsExit; extern int recollNeedsExit;

View File

@ -260,7 +260,7 @@ void RecollMain::reslistTE_doubleClicked(int par, int)
Rcl::Doc doc; Rcl::Doc doc;
int reldocnum = reldocnumfromparnum(par); int reldocnum = reldocnumfromparnum(par);
if (!docsource->getDoc(reslist_winfirst + reldocnum, doc, 0)) if (!docsource->getDoc(reslist_winfirst + reldocnum, doc, 0, 0))
return; return;
// Look for appropriate viewer // Look for appropriate viewer
@ -439,9 +439,10 @@ void RecollMain::listNextPB_clicked()
// Insert results if any in result list window // Insert results if any in result list window
for (int i = 0; i < last; i++) { for (int i = 0; i < last; i++) {
string sh;
doc.erase(); doc.erase();
if (!docsource->getDoc(reslist_winfirst + i, doc, &percent)) { if (!docsource->getDoc(reslist_winfirst + i, doc, &percent, &sh)) {
if (i == 0) if (i == 0)
reslist_winfirst = -1; reslist_winfirst = -1;
break; break;
@ -498,7 +499,10 @@ void RecollMain::listNextPB_clicked()
} }
string abst = stripMarkup(doc.abstract); string abst = stripMarkup(doc.abstract);
LOGDEB1(("Abstract: {%s}\n", abst.c_str())); LOGDEB1(("Abstract: {%s}\n", abst.c_str()));
string result = string("<p>"); string result;
if (!sh.empty())
result += string("<br><b>") + sh + "</b><br><br>\n";
result += string("<p>");
if (!img_name.empty()) { if (!img_name.empty()) {
result += "<img source=\"" + img_name + "\" align=\"left\">"; result += "<img source=\"" + img_name + "\" align=\"left\">";
} }

View File

@ -1,10 +1,13 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: docseq.cpp,v 1.1 2005-11-25 10:02:36 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: docseq.cpp,v 1.2 2005-11-28 15:31:01 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
#include <math.h>
#include "docseq.h" #include "docseq.h"
bool DocSequenceDb::getDoc(int num, Rcl::Doc &doc, int *percent) bool DocSequenceDb::getDoc(int num, Rcl::Doc &doc, int *percent, string *sh)
{ {
if (sh) sh->erase();
return db ? db->getDoc(num, doc, percent) : false; return db ? db->getDoc(num, doc, percent) : false;
} }
@ -20,7 +23,8 @@ int DocSequenceDb::getResCnt()
} }
bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, int *percent) { bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, int *percent,
string *sh) {
// Retrieve history list // Retrieve history list
if (!hist) if (!hist)
return false; return false;
@ -41,7 +45,15 @@ bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, int *percent) {
it++; it++;
if (percent) if (percent)
*percent = 100; *percent = 100;
return db->getDoc((*it).first, (*it).second, doc); if (sh) {
if (prevtime < 0 || abs(prevtime - (*it).unixtime) > 86400) {
prevtime = it->unixtime;
time_t t = (time_t)(it->unixtime);
*sh = string(ctime(&t));
} else
sh->erase();
}
return db->getDoc((*it).fn, (*it).ipath, doc);
} }
int DocSequenceHistory::getResCnt() int DocSequenceHistory::getResCnt()

View File

@ -1,6 +1,6 @@
#ifndef _DOCSEQ_H_INCLUDED_ #ifndef _DOCSEQ_H_INCLUDED_
#define _DOCSEQ_H_INCLUDED_ #define _DOCSEQ_H_INCLUDED_
/* @(#$Id: docseq.h,v 1.1 2005-11-25 10:02:36 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: docseq.h,v 1.2 2005-11-28 15:31:01 dockes Exp $ (C) 2004 J.F.Dockes */
#include "rcldb.h" #include "rcldb.h"
#include "history.h" #include "history.h"
@ -12,7 +12,8 @@
*/ */
class DocSequence { class DocSequence {
public: public:
virtual bool getDoc(int num, Rcl::Doc &doc, int *percent) = 0; virtual bool getDoc(int num, Rcl::Doc &doc, int *percent, string *sh = 0)
= 0;
virtual int getResCnt() = 0; virtual int getResCnt() = 0;
virtual std::string title() = 0; virtual std::string title() = 0;
}; };
@ -24,7 +25,7 @@ class DocSequenceDb : public DocSequence {
public: public:
DocSequenceDb(Rcl::Db *d) : db(d) {} DocSequenceDb(Rcl::Db *d) : db(d) {}
virtual ~DocSequenceDb() {} virtual ~DocSequenceDb() {}
virtual bool getDoc(int num, Rcl::Doc &doc, int *percent); virtual bool getDoc(int num, Rcl::Doc &doc, int *percent, string * = 0);
virtual int getResCnt(); virtual int getResCnt();
virtual std::string title() {return string("Query results");} virtual std::string title() {return string("Query results");}
private: private:
@ -34,20 +35,21 @@ class DocSequenceDb : public DocSequence {
/** A DocSequence coming from the history file */ /** A DocSequence coming from the history file */
class DocSequenceHistory : public DocSequence { class DocSequenceHistory : public DocSequence {
public: public:
DocSequenceHistory(Rcl::Db *d, RclQHistory *h) DocSequenceHistory(Rcl::Db *d, RclDHistory *h)
: db(d), hist(h), prevnum(-1) {} : db(d), hist(h), prevnum(-1), prevtime(-1) {}
virtual ~DocSequenceHistory() {} virtual ~DocSequenceHistory() {}
virtual bool getDoc(int num, Rcl::Doc &doc, int *percent); virtual bool getDoc(int num, Rcl::Doc &doc, int *percent, string *sh = 0);
virtual int getResCnt(); virtual int getResCnt();
virtual std::string title() {return string("Document history");} virtual std::string title() {return string("Document history");}
private: private:
Rcl::Db *db; Rcl::Db *db;
RclQHistory *hist; RclDHistory *hist;
int prevnum; int prevnum;
long prevtime;
std::list< std::pair<std::string, std::string> > hlist; std::list<RclDHistoryEntry> hlist;
std::list< std::pair<std::string, std::string> >::const_iterator it; std::list<RclDHistoryEntry>::const_iterator it;
}; };
#endif /* _DOCSEQ_H_INCLUDED_ */ #endif /* _DOCSEQ_H_INCLUDED_ */

View File

@ -1,9 +1,10 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: history.cpp,v 1.2 2005-11-25 14:36:45 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: history.cpp,v 1.3 2005-11-28 15:31:01 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
#ifndef TEST_HISTORY #ifndef TEST_HISTORY
#include <time.h> #include <time.h>
#include "history.h" #include "history.h"
#include "base64.h" #include "base64.h"
#include "smallut.h" #include "smallut.h"
@ -13,48 +14,65 @@ static char rcsid[] = "@(#$Id: history.cpp,v 1.2 2005-11-25 14:36:45 dockes Exp
using namespace std; using namespace std;
#endif #endif
RclQHistory::RclQHistory(const string &fn, unsigned int mxs) static const char *docSubkey = "docs";
RclDHistory::RclDHistory(const string &fn, unsigned int mxs)
: m_mlen(mxs), m_data(fn.c_str()) : m_mlen(mxs), m_data(fn.c_str())
{ {
} }
const char *docSubkey = "docs";
bool RclQHistory::enterDocument(const string fn, const string ipath) bool RclDHistory::decodeValue(const string &value, RclDHistoryEntry *e)
{ {
LOGDEB(("RclQHistory::enterDocument: [%s] [%s] into %s\n", list<string> vall;
stringToStrings(value, vall);
list<string>::const_iterator it1 = vall.begin();
if (vall.size() < 2)
return false;
e->unixtime = atol((*it1++).c_str());
base64_decode(*it1++, e->fn);
if (vall.size() == 3)
base64_decode(*it1, e->ipath);
else
e->ipath.erase();
return true;
}
bool RclDHistory::enterDocument(const string fn, const string ipath)
{
LOGDEB(("RclDHistory::enterDocument: [%s] [%s] into %s\n",
fn.c_str(), ipath.c_str(), m_data.getFilename().c_str())); fn.c_str(), ipath.c_str(), m_data.getFilename().c_str()));
//Encode value part: 2 base64 of fn and ipath separated by a space // Encode value part: Unix time + base64 of fn + base64 of ipath
// separated by a space. If ipath is not set, there are only 2 parts
char chartime[20];
time_t now = time(0);
sprintf(chartime, "%ld", (long)now);
string bfn, bipath; string bfn, bipath;
base64_encode(fn, bfn); base64_encode(fn, bfn);
base64_encode(ipath, bipath); base64_encode(ipath, bipath);
string value = bfn + " " + bipath; string value = string(chartime) + " " + bfn + " " + bipath;
// We trim whitespace from the value (if there is no ipath it now
// ends with a space), else the value later returned by conftree
// will be different because conftree does trim white space, and
// this breaks the comparisons below
trimstring(value);
LOGDEB1(("Encoded value [%s] (%d)\n", value.c_str(), value.size())); LOGDEB1(("Encoded value [%s] (%d)\n", value.c_str(), value.size()));
// Is this doc already in history ? If it is we remove the old entry // Is this doc already in history ? If it is we remove the old entry
list<string> names = m_data.getNames(docSubkey); list<string> names = m_data.getNames(docSubkey);
list<string>::const_iterator it; list<string>::const_iterator it;
bool changed = false; bool changed = false;
for (it = names.begin();it != names.end(); it++) { for (it = names.begin(); it != names.end(); it++) {
string oval; string oval;
if (!m_data.get(*it, oval, docSubkey)) { if (!m_data.get(*it, oval, docSubkey)) {
LOGDEB(("No data for %s\n", (*it).c_str())); LOGDEB(("No data for %s\n", (*it).c_str()));
continue; continue;
} }
LOGDEB1(("Look at %s [%s] (%d)\n", RclDHistoryEntry entry;
(*it).c_str(), oval.c_str(), oval.length())); decodeValue(oval, &entry);
if (oval == value) {
LOGDEB1(("Erasing old entry\n")); if (entry.fn == fn && entry.ipath == ipath) {
LOGDEB(("Erasing old entry\n"));
m_data.erase(*it, docSubkey); m_data.erase(*it, docSubkey);
changed = true; changed = true;
} }
} }
// Maybe reget list // Maybe reget list
if (changed) if (changed)
names = m_data.getNames(docSubkey); names = m_data.getNames(docSubkey);
@ -78,32 +96,24 @@ bool RclQHistory::enterDocument(const string fn, const string ipath)
sprintf(nname, "%010u", hi); sprintf(nname, "%010u", hi);
if (!m_data.set(string(nname), value, docSubkey)) { if (!m_data.set(string(nname), value, docSubkey)) {
LOGERR(("RclQHistory::enterDocument: set failed\n")); LOGERR(("RclDHistory::enterDocument: set failed\n"));
return false; return false;
} }
return true; return true;
} }
list< pair<string, string> > RclQHistory::getDocHistory() list<RclDHistoryEntry> RclDHistory::getDocHistory()
{ {
list< pair<string, string> > mlist; list<RclDHistoryEntry> mlist;
RclDHistoryEntry entry;
list<string> names = m_data.getNames(docSubkey); list<string> names = m_data.getNames(docSubkey);
for (list<string>::const_iterator it = names.begin(); it != names.end(); for (list<string>::const_iterator it = names.begin();
it++) { it != names.end(); it++) {
string value; string value;
if (m_data.get(*it, value, docSubkey)) { if (m_data.get(*it, value, docSubkey)) {
list<string> vall; if (!decodeValue(value, &entry))
stringToStrings(value, vall);
list<string>::const_iterator it1 = vall.begin();
if (vall.size() < 1)
continue; continue;
string fn, ipath; mlist.push_front(entry);
LOGDEB(("RclQHistory::getDocHistory:b64: %s\n", (*it1).c_str()));
base64_decode(*it1++, fn);
LOGDEB(("RclQHistory::getDocHistory:fn: %s\n", fn.c_str()));
if (vall.size() == 2)
base64_decode(*it1, ipath);
mlist.push_front(pair<string, string>(fn, ipath));
} }
} }
return mlist; return mlist;
@ -122,7 +132,7 @@ using namespace std;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
RclQHistory hist("toto", 5); RclDHistory hist("toto", 5);
DebugLog::getdbl()->setloglevel(DEBDEB1); DebugLog::getdbl()->setloglevel(DEBDEB1);
DebugLog::setfilename("stderr"); DebugLog::setfilename("stderr");

View File

@ -1,6 +1,6 @@
#ifndef _HISTORY_H_INCLUDED_ #ifndef _HISTORY_H_INCLUDED_
#define _HISTORY_H_INCLUDED_ #define _HISTORY_H_INCLUDED_
/* @(#$Id: history.h,v 1.1 2005-11-24 18:21:55 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: history.h,v 1.2 2005-11-28 15:31:01 dockes Exp $ (C) 2004 J.F.Dockes */
#include <string> #include <string>
#include <list> #include <list>
@ -8,19 +8,29 @@
#include "conftree.h" #include "conftree.h"
/** Holder for data returned when querying history */
class RclDHistoryEntry {
public:
RclDHistoryEntry() : unixtime(0) {}
long unixtime;
string fn;
string ipath;
};
/** /**
* The query and documents history class. This is based on a ConfTree for no * The documents history class. This is based on a ConfTree for no
* imperative reason * imperative reason
*/ */
class RclQHistory { class RclDHistory {
public: public:
RclQHistory(const std::string &fn, unsigned int maxsize=1000); RclDHistory(const std::string &fn, unsigned int maxsize=1000);
bool ok() {return m_data.getStatus() == ConfSimple::STATUS_RW;} bool ok() {return m_data.getStatus() == ConfSimple::STATUS_RW;}
bool enterDocument(const std::string fn, const std::string ipath); bool enterDocument(const std::string fn, const std::string ipath);
std::list< std::pair<std::string, std::string> > getDocHistory(); std::list<RclDHistoryEntry> getDocHistory();
private: private:
bool decodeValue(const string &value, RclDHistoryEntry *e);
unsigned int m_mlen; unsigned int m_mlen;
ConfSimple m_data; ConfSimple m_data;
}; };