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
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
#include <unistd.h>
@ -36,7 +36,7 @@ int recollNeedsExit;
string tmpdir;
bool showicons;
string iconsdir;
RclQHistory *history;
RclDHistory *history;
void getQueryStemming(bool &dostem, std::string &stemlang)
{
@ -172,7 +172,7 @@ int main( int argc, char ** argv )
string historyfile = rclconfig->getConfDir();
path_cat(historyfile, "history");
history = new RclQHistory(historyfile);
history = new RclDHistory(historyfile);
dbdir = path_tildexpand(dbdir);

View File

@ -1,6 +1,6 @@
#ifndef _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 <list>
@ -20,7 +20,7 @@ extern Rcl::Db *rcldb;
extern std::string tmpdir;
extern bool showicons;
extern string iconsdir;
extern RclQHistory *history;
extern RclDHistory *history;
extern int recollNeedsExit;

View File

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

View File

@ -1,10 +1,13 @@
#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
#include <math.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;
}
@ -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
if (!hist)
return false;
@ -41,7 +45,15 @@ bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, int *percent) {
it++;
if (percent)
*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()

View File

@ -1,6 +1,6 @@
#ifndef _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 "history.h"
@ -12,7 +12,8 @@
*/
class DocSequence {
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 std::string title() = 0;
};
@ -24,7 +25,7 @@ class DocSequenceDb : public DocSequence {
public:
DocSequenceDb(Rcl::Db *d) : db(d) {}
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 std::string title() {return string("Query results");}
private:
@ -34,20 +35,21 @@ class DocSequenceDb : public DocSequence {
/** A DocSequence coming from the history file */
class DocSequenceHistory : public DocSequence {
public:
DocSequenceHistory(Rcl::Db *d, RclQHistory *h)
: db(d), hist(h), prevnum(-1) {}
DocSequenceHistory(Rcl::Db *d, RclDHistory *h)
: db(d), hist(h), prevnum(-1), prevtime(-1) {}
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 std::string title() {return string("Document history");}
private:
Rcl::Db *db;
RclQHistory *hist;
RclDHistory *hist;
int prevnum;
long prevtime;
std::list< std::pair<std::string, std::string> > hlist;
std::list< std::pair<std::string, std::string> >::const_iterator it;
std::list<RclDHistoryEntry> hlist;
std::list<RclDHistoryEntry>::const_iterator it;
};
#endif /* _DOCSEQ_H_INCLUDED_ */

View File

@ -1,9 +1,10 @@
#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
#ifndef TEST_HISTORY
#include <time.h>
#include "history.h"
#include "base64.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;
#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())
{
}
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()));
//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;
base64_encode(fn, bfn);
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()));
// Is this doc already in history ? If it is we remove the old entry
list<string> names = m_data.getNames(docSubkey);
list<string>::const_iterator it;
bool changed = false;
for (it = names.begin();it != names.end(); it++) {
for (it = names.begin(); it != names.end(); it++) {
string oval;
if (!m_data.get(*it, oval, docSubkey)) {
LOGDEB(("No data for %s\n", (*it).c_str()));
continue;
}
LOGDEB1(("Look at %s [%s] (%d)\n",
(*it).c_str(), oval.c_str(), oval.length()));
if (oval == value) {
LOGDEB1(("Erasing old entry\n"));
RclDHistoryEntry entry;
decodeValue(oval, &entry);
if (entry.fn == fn && entry.ipath == ipath) {
LOGDEB(("Erasing old entry\n"));
m_data.erase(*it, docSubkey);
changed = true;
}
}
// Maybe reget list
if (changed)
names = m_data.getNames(docSubkey);
@ -78,32 +96,24 @@ bool RclQHistory::enterDocument(const string fn, const string ipath)
sprintf(nname, "%010u", hi);
if (!m_data.set(string(nname), value, docSubkey)) {
LOGERR(("RclQHistory::enterDocument: set failed\n"));
LOGERR(("RclDHistory::enterDocument: set failed\n"));
return false;
}
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);
for (list<string>::const_iterator it = names.begin(); it != names.end();
it++) {
for (list<string>::const_iterator it = names.begin();
it != names.end(); it++) {
string value;
if (m_data.get(*it, value, docSubkey)) {
list<string> vall;
stringToStrings(value, vall);
list<string>::const_iterator it1 = vall.begin();
if (vall.size() < 1)
if (!decodeValue(value, &entry))
continue;
string fn, ipath;
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));
mlist.push_front(entry);
}
}
return mlist;
@ -122,7 +132,7 @@ using namespace std;
int main(int argc, char **argv)
{
RclQHistory hist("toto", 5);
RclDHistory hist("toto", 5);
DebugLog::getdbl()->setloglevel(DEBDEB1);
DebugLog::setfilename("stderr");

View File

@ -1,6 +1,6 @@
#ifndef _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 <list>
@ -8,19 +8,29 @@
#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
*/
class RclQHistory {
class RclDHistory {
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 enterDocument(const std::string fn, const std::string ipath);
std::list< std::pair<std::string, std::string> > getDocHistory();
std::list<RclDHistoryEntry> getDocHistory();
private:
bool decodeValue(const string &value, RclDHistoryEntry *e);
unsigned int m_mlen;
ConfSimple m_data;
};