From 5ebcb0c104f69c83cb17dbf90a283eb784bef70e Mon Sep 17 00:00:00 2001 From: dockes Date: Sat, 5 Nov 2005 14:40:50 +0000 Subject: [PATCH] separate file and document dates (mainly for email folders). Better check configuration at startup --- src/common/rclconfig.cpp | 32 ++++++++++++++++++------------ src/common/rclconfig.h | 5 +++-- src/common/rclinit.cpp | 14 +++++++++---- src/common/rclinit.h | 7 +++++-- src/index/indexer.cpp | 7 +++---- src/index/recollindex.cpp | 11 +++++++++-- src/internfile/mh_mail.cpp | 4 ++-- src/mk/SunOS | 5 ++++- src/qtgui/main.cpp | 9 ++++++--- src/qtgui/preview/preview.ui | 27 +++++++++++++++++++++++-- src/qtgui/preview/preview.ui.h | 7 +++++++ src/qtgui/recollmain.ui.h | 15 +++++++------- src/rcldb/rcldb.cpp | 36 +++++++++++++++++++++++----------- src/rcldb/rcldb.h | 8 +++++--- 14 files changed, 132 insertions(+), 55 deletions(-) diff --git a/src/common/rclconfig.cpp b/src/common/rclconfig.cpp index 478b9d17..6366a1cf 100644 --- a/src/common/rclconfig.cpp +++ b/src/common/rclconfig.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.9 2005-10-19 14:14:17 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.10 2005-11-05 14:40:50 dockes Exp $ (C) 2004 J.F.Dockes"; #endif #include @@ -32,11 +32,13 @@ RclConfig::RclConfig() string cfilename = confdir; path_cat(cfilename, "recoll.conf"); - // Maybe we should try to open readonly here as, else, this will - // casually create a configuration file - conf = new ConfTree(cfilename.c_str(), 0); - if (conf == 0) { - cerr << "No configuration" << endl; + // Open readonly here so as not to casually create a config file + conf = new ConfTree(cfilename.c_str(), true); + if (conf == 0 || + (conf->getStatus() != ConfSimple::STATUS_RO && + conf->getStatus() != ConfSimple::STATUS_RW)) { + reason = string("No main configuration file: ") + cfilename + + " does not exist or cannot be parsed"; return; } @@ -46,9 +48,12 @@ RclConfig::RclConfig() } string mpath = confdir; path_cat(mpath, mimemapfile); - mimemap = new ConfTree(mpath.c_str()); - if (mimemap == 0) { - cerr << "No mime map file" << endl; + mimemap = new ConfTree(mpath.c_str(), true); + if (mimemap == 0 || + (mimemap->getStatus() != ConfSimple::STATUS_RO && + mimemap->getStatus() != ConfSimple::STATUS_RW)) { + reason = string("No mime map configuration file: ") + mpath + + " does not exist or cannot be parsed"; return; } // mimemap->list(); @@ -59,9 +64,12 @@ RclConfig::RclConfig() } mpath = confdir; path_cat(mpath, mimeconffile); - mimeconf = new ConfTree(mpath.c_str()); - if (mimeconf == 0) { - cerr << "No mime conf file" << endl; + mimeconf = new ConfTree(mpath.c_str(), true); + if (mimeconf == 0 || + (mimeconf->getStatus() != ConfSimple::STATUS_RO && + mimeconf->getStatus() != ConfSimple::STATUS_RW)) { + reason = string("No mime configuration file: ") + mpath + + " does not exist or cannot be parsed"; return; } // mimeconf->list(); diff --git a/src/common/rclconfig.h b/src/common/rclconfig.h index 73c72df6..570fa9cb 100644 --- a/src/common/rclconfig.h +++ b/src/common/rclconfig.h @@ -1,6 +1,6 @@ #ifndef _RCLCONFIG_H_INCLUDED_ #define _RCLCONFIG_H_INCLUDED_ -/* @(#$Id: rclconfig.h,v 1.5 2005-10-17 13:36:53 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: rclconfig.h,v 1.6 2005-11-05 14:40:50 dockes Exp $ (C) 2004 J.F.Dockes */ #include @@ -8,6 +8,7 @@ class RclConfig { int m_ok; + string reason; // Explanation for bad state string confdir; // Directory where the files are stored ConfTree *conf; // Parsed main configuration string keydir; // Current directory used for parameter fetches. @@ -26,7 +27,7 @@ class RclConfig { ~RclConfig() {delete conf;delete mimemap;delete mimeconf;} bool ok() {return m_ok;} - + const string &getReason() {return reason;} string getConfDir() {return confdir;} ConfTree *getConfig() {return m_ok ? conf : 0;} diff --git a/src/common/rclinit.cpp b/src/common/rclinit.cpp index 2177afb0..564615cc 100644 --- a/src/common/rclinit.cpp +++ b/src/common/rclinit.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: rclinit.cpp,v 1.1 2005-04-05 09:35:35 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: rclinit.cpp,v 1.2 2005-11-05 14:40:50 dockes Exp $ (C) 2004 J.F.Dockes"; #endif #include @@ -7,8 +7,10 @@ static char rcsid[] = "@(#$Id: rclinit.cpp,v 1.1 2005-04-05 09:35:35 dockes Exp #include "debuglog.h" #include "rclconfig.h" +#include "rclinit.h" -RclConfig *recollinit(void (*cleanup)(void), void (*sigcleanup)(int)) +RclConfig *recollinit(void (*cleanup)(void), void (*sigcleanup)(int), + string &reason) { atexit(cleanup); if (signal(SIGHUP, SIG_IGN) != SIG_IGN) @@ -24,8 +26,12 @@ RclConfig *recollinit(void (*cleanup)(void), void (*sigcleanup)(int)) DebugLog::setfilename("stderr"); RclConfig *config = new RclConfig; if (!config || !config->ok()) { - fprintf(stderr, "Config could not be built\n"); - exit(1); + reason = "Configuration could not be built:\n"; + if (config) + reason += config->getReason(); + else + reason += "Out of memory ?"; + return 0; } string logfilename, loglevel; diff --git a/src/common/rclinit.h b/src/common/rclinit.h index cecfab63..9f4fb13a 100644 --- a/src/common/rclinit.h +++ b/src/common/rclinit.h @@ -1,9 +1,12 @@ #ifndef _RCLINIT_H_INCLUDED_ #define _RCLINIT_H_INCLUDED_ -/* @(#$Id: rclinit.h,v 1.1 2005-04-05 09:35:35 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: rclinit.h,v 1.2 2005-11-05 14:40:50 dockes Exp $ (C) 2004 J.F.Dockes */ + +#include class RclConfig; -extern RclConfig *recollinit(void (*cleanup)(void), void (*sigcleanup)(int)); +extern RclConfig *recollinit(void (*cleanup)(void), void (*sigcleanup)(int), + std::string &reason); #endif /* _RCLINIT_H_INCLUDED_ */ diff --git a/src/index/indexer.cpp b/src/index/indexer.cpp index 55756c01..7be8e43d 100644 --- a/src/index/indexer.cpp +++ b/src/index/indexer.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: indexer.cpp,v 1.12 2005-10-15 12:18:04 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: indexer.cpp,v 1.13 2005-11-05 14:40:50 dockes Exp $ (C) 2004 J.F.Dockes"; #endif #include #include @@ -173,11 +173,10 @@ DbIndexer::processone(const std::string &fn, const struct stat *stp, break; // Set the date if this was not done in the document handler - // (ie: date from Date: mail header). - if (doc.mtime.empty()) { + if (doc.fmtime.empty()) { char ascdate[20]; sprintf(ascdate, "%ld", long(stp->st_ctime)); - doc.mtime = ascdate; + doc.fmtime = ascdate; } // Internal access path for multi-document files doc.ipath = ipath; diff --git a/src/index/recollindex.cpp b/src/index/recollindex.cpp index 0ebcfe18..00587227 100644 --- a/src/index/recollindex.cpp +++ b/src/index/recollindex.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: recollindex.cpp,v 1.10 2005-04-05 09:35:35 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: recollindex.cpp,v 1.11 2005-11-05 14:40:50 dockes Exp $ (C) 2004 J.F.Dockes"; #endif #include @@ -26,8 +26,15 @@ static void sigcleanup(int sig) int main(int argc, const char **argv) { - RclConfig *config = recollinit(cleanup, sigcleanup); + string reason; + RclConfig *config = recollinit(cleanup, sigcleanup, reason); + if (config == 0 || !config->ok()) { + string str = "Configuration problem: "; + str += reason; + fprintf(stderr, "%s\n", str.c_str()); + exit(1); + } indexer = new ConfIndexer(config); exit(!indexer->index()); diff --git a/src/internfile/mh_mail.cpp b/src/internfile/mh_mail.cpp index 4a53c8d8..488214ea 100644 --- a/src/internfile/mh_mail.cpp +++ b/src/internfile/mh_mail.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: mh_mail.cpp,v 1.7 2005-10-31 08:59:05 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: mh_mail.cpp,v 1.8 2005-11-05 14:40:50 dockes Exp $ (C) 2005 J.F.Dockes"; #endif #include @@ -199,7 +199,7 @@ MimeHandlerMail::processone(const string &fn, Binc::MimeDocument& doc, if (strptime(date.c_str(), " %d %b %Y %H:%M:%S %z ", &tm)) { char ascuxtime[100]; sprintf(ascuxtime, "%ld", (long)mktime(&tm)); - docout.mtime = ascuxtime; + docout.dmtime = ascuxtime; } else { LOGDEB(("strptime failed for [%s]\n", date.c_str())); } diff --git a/src/mk/SunOS b/src/mk/SunOS index 742d97b1..4a32240f 100644 --- a/src/mk/SunOS +++ b/src/mk/SunOS @@ -5,6 +5,9 @@ CXXFLAGS = $(COMMONCXXFLAGS) CC=gcc CXX=g++ -LIBICONV = -L/usr/local/lib -liconv +# Note that we use a static libiconv only to ease installation of binary +# packages +#LIBICONV = -L/usr/local/lib -liconv +LIBICONV = /usr/local/lib/libiconv.a LIBSYS = -lpthread -lnsl -lsocket diff --git a/src/qtgui/main.cpp b/src/qtgui/main.cpp index 7734bdff..c6de2178 100644 --- a/src/qtgui/main.cpp +++ b/src/qtgui/main.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: main.cpp,v 1.11 2005-10-22 05:35:16 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: main.cpp,v 1.12 2005-11-05 14:40:50 dockes Exp $ (C) 2005 J.F.Dockes"; #endif #include @@ -101,11 +101,14 @@ int main( int argc, char ** argv ) w.connect(timer, SIGNAL(timeout()), &w, SLOT(checkExit())); timer->start(100); - rclconfig = recollinit(recollCleanup, sigcleanup); + string reason; + rclconfig = recollinit(recollCleanup, sigcleanup, reason); if (!rclconfig || !rclconfig->ok()) { + string msg = "Configuration problem: "; + msg += reason; QMessageBox::critical(0, "Recoll", - QString("Could not find configuration")); + QString(msg.c_str())); exit(1); } diff --git a/src/qtgui/preview/preview.ui b/src/qtgui/preview/preview.ui index 5051468c..99e682c1 100644 --- a/src/qtgui/preview/preview.ui +++ b/src/qtgui/preview/preview.ui @@ -35,7 +35,7 @@ - layout9 + layout4 @@ -75,7 +75,7 @@ - layout7 + layout3 @@ -107,6 +107,9 @@ nextButton + + false + &Next @@ -118,6 +121,9 @@ prevButton + + false + &Previous @@ -125,6 +131,17 @@ Alt+P + + + clearPB + + + false + + + Clear + + matchCheck @@ -161,6 +178,12 @@ Preview prevPressed() + + clearPB + clicked() + searchTextLine + clear() + qapplication.h diff --git a/src/qtgui/preview/preview.ui.h b/src/qtgui/preview/preview.ui.h index 2e0b11a7..40b5b584 100644 --- a/src/qtgui/preview/preview.ui.h +++ b/src/qtgui/preview/preview.ui.h @@ -57,6 +57,7 @@ bool Preview::eventFilter(QObject *target, QEvent *event) e = (QTextEdit *)tw->child("pvEdit"); LOGDEB1(("Widget: %p, edit %p, target %p\n", tw, e, target)); if (e && target == tw && keyEvent->key() == Key_Slash) { + searchTextLine->setFocus(); dynSearchActive = true; return true; } @@ -70,8 +71,14 @@ void Preview::searchTextLine_textChanged(const QString & text) LOGDEB1(("search line text changed. text: '%s'\n", text.ascii())); if (text.isEmpty()) { dynSearchActive = false; + nextButton->setEnabled(false); + prevButton->setEnabled(false); + clearPB->setEnabled(false); } else { dynSearchActive = true; + nextButton->setEnabled(true); + prevButton->setEnabled(true); + clearPB->setEnabled(true); doSearch(false, false); } } diff --git a/src/qtgui/recollmain.ui.h b/src/qtgui/recollmain.ui.h index b5b83c8f..22587de0 100644 --- a/src/qtgui/recollmain.ui.h +++ b/src/qtgui/recollmain.ui.h @@ -407,8 +407,9 @@ void RecollMain::listNextPB_clicked() doc.title = path_getsimple(doc.url); char datebuf[100]; datebuf[0] = 0; - if (!doc.mtime.empty()) { - time_t mtime = atol(doc.mtime.c_str()); + if (!doc.dmtime.empty() || !doc.fmtime.empty()) { + time_t mtime = doc.dmtime.empty() ? + atol(doc.fmtime.c_str()) : atol(doc.dmtime.c_str()); struct tm *tm = localtime(&mtime); strftime(datebuf, 99, "Modified: %F %T", tm); } @@ -417,7 +418,7 @@ void RecollMain::listNextPB_clicked() string result = "

" + string(perbuf) + " " + doc.title + "
" + doc.mimetype + " " + - (!doc.mtime.empty() ? string(datebuf) + "
" : string("
")) + + (datebuf[0] ? string(datebuf) + "
" : string("
")) + (!abst.empty() ? abst + "
" : string("")) + (!doc.keywords.empty() ? doc.keywords + "
" : string("")) + "" + doc.url + +"
" + @@ -620,14 +621,14 @@ void RecollMain::startPreview(int docnum) doc.title = path_getsimple(doc.url); char datebuf[100]; datebuf[0] = 0; - if (!doc.mtime.empty()) { - time_t mtime = atol(doc.mtime.c_str()); + if (!doc.fmtime.empty() || !doc.dmtime.empty()) { + time_t mtime = doc.dmtime.empty() ? + atol(doc.fmtime.c_str()) : atol(doc.dmtime.c_str()); struct tm *tm = localtime(&mtime); strftime(datebuf, 99, "%F %T", tm); } string tiptxt = doc.url + string("\n"); - tiptxt += doc.mimetype + " " - + (doc.mtime.empty() ? "\n" : string(datebuf) + "\n"); + tiptxt += doc.mimetype + " " + string(datebuf) + "\n"; if (!doc.title.empty()) tiptxt += doc.title + "\n"; curPreview->pvTab->setTabToolTip(curPreview->pvTab->currentPage(), diff --git a/src/rcldb/rcldb.cpp b/src/rcldb/rcldb.cpp index 1e4d256b..642a4d91 100644 --- a/src/rcldb/rcldb.cpp +++ b/src/rcldb/rcldb.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.31 2005-10-20 11:33:49 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.32 2005-11-05 14:40:50 dockes Exp $ (C) 2004 J.F.Dockes"; #endif #include #include @@ -338,7 +338,9 @@ bool Rcl::Db::add(const string &fn, const Rcl::Doc &idoc) // - mime type string record = "url=file://" + fn; record += "\nmtype=" + doc.mimetype; - record += "\nmtime=" + doc.mtime; + record += "\nfmtime=" + doc.fmtime; + if (!doc.dmtime.empty()) + record += "\ndmtime=" + doc.dmtime; record += "\norigcharset=" + doc.origcharset; record += "\ncaption=" + doc.title; record += "\nkeywords=" + doc.keywords; @@ -351,7 +353,8 @@ bool Rcl::Db::add(const string &fn, const Rcl::Doc &idoc) LOGDEB1(("Newdocument data: %s\n", record.c_str())); newdocument.set_data(record); - time_t mtime = atol(doc.mtime.c_str()); + time_t mtime = atol(doc.dmtime.empty() ? doc.fmtime.c_str() : + doc.dmtime.c_str()); struct tm *tm = localtime(&mtime); char buf[9]; sprintf(buf, "%04d%02d%02d",tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday); @@ -399,8 +402,9 @@ bool Rcl::Db::needUpdate(const string &filename, const struct stat *stp) return true; } - // Look for all documents with this path. Check the update time (once). - // If the db is up to date, set the update flags for all documents + // Look for all documents with this path. We need to look at all + // to set their existence flag. + // We check the update time on the spe Xapian::PostingIterator doc; try { Xapian::PostingIterator docid0 = ndb->wdb.postlist_begin(pathterm); @@ -409,14 +413,23 @@ bool Rcl::Db::needUpdate(const string &filename, const struct stat *stp) Xapian::Document doc = ndb->wdb.get_document(*docid); - // Check the date once. no need to look at the others if the - // db needs updating. + // Check the date once. no need to look at the others if + // the db needs updating. Note that the fmtime used to be + // called mtime, and we're keeping compat if (docid == docid0) { string data = doc.get_data(); - const char *cp = strstr(data.c_str(), "mtime="); - cp += 6; - long mtime = atol(cp); + const char *cp = strstr(data.c_str(), "fmtime="); + if (cp) { + cp += 7; + } else { + cp = strstr(data.c_str(), "mtime="); + if (cp) + cp+= 6; + } + long mtime = cp ? atol(cp) : 0; if (mtime < stp->st_mtime) { + LOGDEB2(("Need update: Db Doc mtime %ld file mtime %ld\n", + (long)mtime, (long)stp->st_mtime)); // Db is not up to date. Let's index the file return true; } @@ -1027,7 +1040,8 @@ bool Rcl::Db::getDoc(int exti, Doc &doc, int *percent) ConfSimple parms(&data); parms.get(string("url"), doc.url); parms.get(string("mtype"), doc.mimetype); - parms.get(string("mtime"), doc.mtime); + parms.get(string("fmtime"), doc.fmtime); + parms.get(string("dmtime"), doc.dmtime); parms.get(string("origcharset"), doc.origcharset); parms.get(string("caption"), doc.title); parms.get(string("keywords"), doc.keywords); diff --git a/src/rcldb/rcldb.h b/src/rcldb/rcldb.h index 5f4508e6..bc1ba9bc 100644 --- a/src/rcldb/rcldb.h +++ b/src/rcldb/rcldb.h @@ -1,6 +1,6 @@ #ifndef _DB_H_INCLUDED_ #define _DB_H_INCLUDED_ -/* @(#$Id: rcldb.h,v 1.15 2005-10-19 14:14:17 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: rcldb.h,v 1.16 2005-11-05 14:40:50 dockes Exp $ (C) 2004 J.F.Dockes */ #include #include @@ -39,7 +39,8 @@ class Doc { string url; string ipath; string mimetype; - string mtime; // Modification time as decimal ascii + string fmtime; // File modification time as decimal ascii unix time + string dmtime; // Data reference date (same format). Ie: mail date string origcharset; string title; string keywords; @@ -51,7 +52,8 @@ class Doc { url.erase(); ipath.erase(); mimetype.erase(); - mtime.erase(); + fmtime.erase(); + dmtime.erase(); origcharset.erase(); title.erase(); keywords.erase();