query: support negative mime and catg clauses: -mime:text/plain
This commit is contained in:
parent
b9be9e58d5
commit
ce9e9e4d00
@ -61,11 +61,14 @@ static Rcl::SearchData *wasaQueryToRcl(RclConfig *config, WasaQuery *wasa,
|
||||
|
||||
if (!stringicmp("mime", (*it)->m_fieldspec) ||
|
||||
!stringicmp("format", (*it)->m_fieldspec)) {
|
||||
if ((*it)->m_op != WasaQuery::OP_LEAF) {
|
||||
reason = "Negative mime/format clauses not supported yet";
|
||||
if ((*it)->m_op == WasaQuery::OP_LEAF) {
|
||||
sdata->addFiletype((*it)->m_value);
|
||||
} else if ((*it)->m_op == WasaQuery::OP_EXCL) {
|
||||
sdata->remFiletype((*it)->m_value);
|
||||
} else {
|
||||
reason = "internal error: mime clause neither leaf not excl??";
|
||||
return 0;
|
||||
}
|
||||
sdata->addFiletype((*it)->m_value);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -73,8 +76,10 @@ static Rcl::SearchData *wasaQueryToRcl(RclConfig *config, WasaQuery *wasa,
|
||||
// categories like "audio", "presentation", etc.
|
||||
if (!stringicmp("rclcat", (*it)->m_fieldspec) ||
|
||||
!stringicmp("type", (*it)->m_fieldspec)) {
|
||||
if ((*it)->m_op != WasaQuery::OP_LEAF) {
|
||||
reason = "Negative rclcat/type clauses not supported yet";
|
||||
if ((*it)->m_op != WasaQuery::OP_LEAF &&
|
||||
(*it)->m_op != WasaQuery::OP_EXCL) {
|
||||
reason = "internal error: rclcat/type clause neither leaf"
|
||||
"nor excl??";
|
||||
return 0;
|
||||
}
|
||||
list<string> mtypes;
|
||||
@ -82,7 +87,10 @@ static Rcl::SearchData *wasaQueryToRcl(RclConfig *config, WasaQuery *wasa,
|
||||
&& !mtypes.empty()) {
|
||||
for (list<string>::iterator mit = mtypes.begin();
|
||||
mit != mtypes.end(); mit++) {
|
||||
sdata->addFiletype(*mit);
|
||||
if ((*it)->m_op == WasaQuery::OP_LEAF)
|
||||
sdata->addFiletype(*mit);
|
||||
else
|
||||
sdata->remFiletype(*mit);
|
||||
}
|
||||
} else {
|
||||
reason = "Unknown rclcat/type value: no mime types found";
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
// Handle translation from rcl's SearchData structures to Xapian Queries
|
||||
#include <stdio.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -135,6 +136,35 @@ date_range_filter(int y1, int m1, int d1, int y2, int m2, int d2)
|
||||
return Xapian::Query(Xapian::Query::OP_OR, v.begin(), v.end());
|
||||
}
|
||||
|
||||
// Expand categories and mime type wild card exps
|
||||
bool SearchData::expandFileTypes(RclConfig *cfg, vector<string>& tps)
|
||||
{
|
||||
if (!cfg) {
|
||||
LOGFATAL(("Db::expandFileTypes: null configuration!!\n"));
|
||||
return false;
|
||||
}
|
||||
vector<string> exptps;
|
||||
list<string> alltypes = cfg->getAllMimeTypes();
|
||||
|
||||
for (vector<string>::iterator it = tps.begin(); it != tps.end(); it++) {
|
||||
if (cfg->isMimeCategory(*it)) {
|
||||
list<string>tps;
|
||||
cfg->getMimeCatTypes(*it, tps);
|
||||
exptps.insert(exptps.end(), tps.begin(), tps.end());
|
||||
} else {
|
||||
for (list<string>::const_iterator ait = alltypes.begin();
|
||||
ait != alltypes.end(); ait++) {
|
||||
if (fnmatch(it->c_str(), ait->c_str(), FNM_CASEFOLD)
|
||||
!= FNM_NOMATCH) {
|
||||
exptps.push_back(*ait);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tps = exptps;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SearchData::toNativeQuery(Rcl::Db &db, void *d)
|
||||
{
|
||||
Xapian::Query xq;
|
||||
@ -220,24 +250,11 @@ bool SearchData::toNativeQuery(Rcl::Db &db, void *d)
|
||||
|
||||
// Add the file type filtering clause if any
|
||||
if (!m_filetypes.empty()) {
|
||||
vector<string> exptps;
|
||||
exptps.reserve(m_filetypes.size());
|
||||
// Expand categories
|
||||
RclConfig *cfg = db.getConf();
|
||||
for (vector<string>::iterator it = m_filetypes.begin();
|
||||
it != m_filetypes.end(); it++) {
|
||||
if (cfg && cfg->isMimeCategory(*it)) {
|
||||
list<string>tps;
|
||||
cfg->getMimeCatTypes(*it, tps);
|
||||
exptps.insert(exptps.end(), tps.begin(), tps.end());
|
||||
} else {
|
||||
exptps.push_back(*it);
|
||||
}
|
||||
}
|
||||
expandFileTypes(db.getConf(), m_filetypes);
|
||||
|
||||
Xapian::Query tq;
|
||||
for (vector<string>::iterator it = exptps.begin();
|
||||
it != exptps.end(); it++) {
|
||||
for (vector<string>::iterator it = m_filetypes.begin();
|
||||
it != m_filetypes.end(); it++) {
|
||||
string term = "T" + *it;
|
||||
LOGDEB0(("Adding file type term: [%s]\n", term.c_str()));
|
||||
tq = tq.empty() ? Xapian::Query(term) :
|
||||
@ -246,6 +263,21 @@ bool SearchData::toNativeQuery(Rcl::Db &db, void *d)
|
||||
xq = xq.empty() ? tq : Xapian::Query(Xapian::Query::OP_FILTER, xq, tq);
|
||||
}
|
||||
|
||||
// Add the neg file type filtering clause if any
|
||||
if (!m_nfiletypes.empty()) {
|
||||
expandFileTypes(db.getConf(), m_nfiletypes);
|
||||
|
||||
Xapian::Query tq;
|
||||
for (vector<string>::iterator it = m_nfiletypes.begin();
|
||||
it != m_nfiletypes.end(); it++) {
|
||||
string term = "T" + *it;
|
||||
LOGDEB0(("Adding negative file type term: [%s]\n", term.c_str()));
|
||||
tq = tq.empty() ? Xapian::Query(term) :
|
||||
Xapian::Query(Xapian::Query::OP_OR, tq, Xapian::Query(term));
|
||||
}
|
||||
xq = xq.empty() ? tq : Xapian::Query(Xapian::Query::OP_AND_NOT, xq, tq);
|
||||
}
|
||||
|
||||
// Add the directory filtering clause
|
||||
if (!m_topdir.empty()) {
|
||||
vector<string> vpath;
|
||||
|
||||
@ -31,6 +31,8 @@
|
||||
#include "refcntr.h"
|
||||
#include "smallut.h"
|
||||
|
||||
class RclConfig;
|
||||
|
||||
#ifndef NO_NAMESPACES
|
||||
using std::vector;
|
||||
using std::string;
|
||||
@ -113,6 +115,8 @@ public:
|
||||
|
||||
/** Add file type for filtering results */
|
||||
void addFiletype(const string& ft) {m_filetypes.push_back(ft);}
|
||||
/** Add file type to not wanted list */
|
||||
void remFiletype(const string& ft) {m_nfiletypes.push_back(ft);}
|
||||
|
||||
void setStemlang(const string& lang = "english") {m_stemlang = lang;}
|
||||
|
||||
@ -140,6 +144,7 @@ private:
|
||||
SClType m_tp; // Only SCLT_AND or SCLT_OR here
|
||||
vector<SearchDataClause*> m_query;
|
||||
vector<string> m_filetypes; // Restrict to filetypes if set.
|
||||
vector<string> m_nfiletypes; // Unwanted file types
|
||||
string m_topdir; // Restrict to subtree.
|
||||
bool m_topdirexcl; // Invert meaning
|
||||
bool m_haveDates;
|
||||
@ -150,6 +155,7 @@ private:
|
||||
string m_reason;
|
||||
bool m_haveWildCards;
|
||||
string m_stemlang;
|
||||
bool expandFileTypes(RclConfig *cfg, vector<string>& exptps);
|
||||
/* Copyconst and assignment private and forbidden */
|
||||
SearchData(const SearchData &) {}
|
||||
SearchData& operator=(const SearchData&) {return *this;};
|
||||
|
||||
@ -239,6 +239,7 @@ media = \
|
||||
image/gif \
|
||||
image/jpeg \
|
||||
image/png \
|
||||
image/svg+xml \
|
||||
image/tiff \
|
||||
video/mp2p \
|
||||
video/mp2t \
|
||||
@ -256,5 +257,4 @@ other = application/vnd.sun.xml.draw \
|
||||
application/vnd.sun.xml.draw.template \
|
||||
application/vnd.sun.xml.math \
|
||||
application/x-fsdirectory \
|
||||
application/zip \
|
||||
image/svg+xml \
|
||||
application/zip
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user