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) ||
|
if (!stringicmp("mime", (*it)->m_fieldspec) ||
|
||||||
!stringicmp("format", (*it)->m_fieldspec)) {
|
!stringicmp("format", (*it)->m_fieldspec)) {
|
||||||
if ((*it)->m_op != WasaQuery::OP_LEAF) {
|
if ((*it)->m_op == WasaQuery::OP_LEAF) {
|
||||||
reason = "Negative mime/format clauses not supported yet";
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
sdata->addFiletype((*it)->m_value);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,8 +76,10 @@ static Rcl::SearchData *wasaQueryToRcl(RclConfig *config, WasaQuery *wasa,
|
|||||||
// categories like "audio", "presentation", etc.
|
// categories like "audio", "presentation", etc.
|
||||||
if (!stringicmp("rclcat", (*it)->m_fieldspec) ||
|
if (!stringicmp("rclcat", (*it)->m_fieldspec) ||
|
||||||
!stringicmp("type", (*it)->m_fieldspec)) {
|
!stringicmp("type", (*it)->m_fieldspec)) {
|
||||||
if ((*it)->m_op != WasaQuery::OP_LEAF) {
|
if ((*it)->m_op != WasaQuery::OP_LEAF &&
|
||||||
reason = "Negative rclcat/type clauses not supported yet";
|
(*it)->m_op != WasaQuery::OP_EXCL) {
|
||||||
|
reason = "internal error: rclcat/type clause neither leaf"
|
||||||
|
"nor excl??";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
list<string> mtypes;
|
list<string> mtypes;
|
||||||
@ -82,7 +87,10 @@ static Rcl::SearchData *wasaQueryToRcl(RclConfig *config, WasaQuery *wasa,
|
|||||||
&& !mtypes.empty()) {
|
&& !mtypes.empty()) {
|
||||||
for (list<string>::iterator mit = mtypes.begin();
|
for (list<string>::iterator mit = mtypes.begin();
|
||||||
mit != mtypes.end(); mit++) {
|
mit != mtypes.end(); mit++) {
|
||||||
sdata->addFiletype(*mit);
|
if ((*it)->m_op == WasaQuery::OP_LEAF)
|
||||||
|
sdata->addFiletype(*mit);
|
||||||
|
else
|
||||||
|
sdata->remFiletype(*mit);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reason = "Unknown rclcat/type value: no mime types found";
|
reason = "Unknown rclcat/type value: no mime types found";
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
// Handle translation from rcl's SearchData structures to Xapian Queries
|
// Handle translation from rcl's SearchData structures to Xapian Queries
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#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());
|
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)
|
bool SearchData::toNativeQuery(Rcl::Db &db, void *d)
|
||||||
{
|
{
|
||||||
Xapian::Query xq;
|
Xapian::Query xq;
|
||||||
@ -220,24 +250,11 @@ bool SearchData::toNativeQuery(Rcl::Db &db, void *d)
|
|||||||
|
|
||||||
// Add the file type filtering clause if any
|
// Add the file type filtering clause if any
|
||||||
if (!m_filetypes.empty()) {
|
if (!m_filetypes.empty()) {
|
||||||
vector<string> exptps;
|
expandFileTypes(db.getConf(), m_filetypes);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Xapian::Query tq;
|
Xapian::Query tq;
|
||||||
for (vector<string>::iterator it = exptps.begin();
|
for (vector<string>::iterator it = m_filetypes.begin();
|
||||||
it != exptps.end(); it++) {
|
it != m_filetypes.end(); it++) {
|
||||||
string term = "T" + *it;
|
string term = "T" + *it;
|
||||||
LOGDEB0(("Adding file type term: [%s]\n", term.c_str()));
|
LOGDEB0(("Adding file type term: [%s]\n", term.c_str()));
|
||||||
tq = tq.empty() ? Xapian::Query(term) :
|
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);
|
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
|
// Add the directory filtering clause
|
||||||
if (!m_topdir.empty()) {
|
if (!m_topdir.empty()) {
|
||||||
vector<string> vpath;
|
vector<string> vpath;
|
||||||
|
|||||||
@ -31,6 +31,8 @@
|
|||||||
#include "refcntr.h"
|
#include "refcntr.h"
|
||||||
#include "smallut.h"
|
#include "smallut.h"
|
||||||
|
|
||||||
|
class RclConfig;
|
||||||
|
|
||||||
#ifndef NO_NAMESPACES
|
#ifndef NO_NAMESPACES
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::string;
|
using std::string;
|
||||||
@ -113,6 +115,8 @@ public:
|
|||||||
|
|
||||||
/** Add file type for filtering results */
|
/** Add file type for filtering results */
|
||||||
void addFiletype(const string& ft) {m_filetypes.push_back(ft);}
|
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;}
|
void setStemlang(const string& lang = "english") {m_stemlang = lang;}
|
||||||
|
|
||||||
@ -140,6 +144,7 @@ private:
|
|||||||
SClType m_tp; // Only SCLT_AND or SCLT_OR here
|
SClType m_tp; // Only SCLT_AND or SCLT_OR here
|
||||||
vector<SearchDataClause*> m_query;
|
vector<SearchDataClause*> m_query;
|
||||||
vector<string> m_filetypes; // Restrict to filetypes if set.
|
vector<string> m_filetypes; // Restrict to filetypes if set.
|
||||||
|
vector<string> m_nfiletypes; // Unwanted file types
|
||||||
string m_topdir; // Restrict to subtree.
|
string m_topdir; // Restrict to subtree.
|
||||||
bool m_topdirexcl; // Invert meaning
|
bool m_topdirexcl; // Invert meaning
|
||||||
bool m_haveDates;
|
bool m_haveDates;
|
||||||
@ -150,6 +155,7 @@ private:
|
|||||||
string m_reason;
|
string m_reason;
|
||||||
bool m_haveWildCards;
|
bool m_haveWildCards;
|
||||||
string m_stemlang;
|
string m_stemlang;
|
||||||
|
bool expandFileTypes(RclConfig *cfg, vector<string>& exptps);
|
||||||
/* Copyconst and assignment private and forbidden */
|
/* Copyconst and assignment private and forbidden */
|
||||||
SearchData(const SearchData &) {}
|
SearchData(const SearchData &) {}
|
||||||
SearchData& operator=(const SearchData&) {return *this;};
|
SearchData& operator=(const SearchData&) {return *this;};
|
||||||
|
|||||||
@ -239,6 +239,7 @@ media = \
|
|||||||
image/gif \
|
image/gif \
|
||||||
image/jpeg \
|
image/jpeg \
|
||||||
image/png \
|
image/png \
|
||||||
|
image/svg+xml \
|
||||||
image/tiff \
|
image/tiff \
|
||||||
video/mp2p \
|
video/mp2p \
|
||||||
video/mp2t \
|
video/mp2t \
|
||||||
@ -256,5 +257,4 @@ other = application/vnd.sun.xml.draw \
|
|||||||
application/vnd.sun.xml.draw.template \
|
application/vnd.sun.xml.draw.template \
|
||||||
application/vnd.sun.xml.math \
|
application/vnd.sun.xml.math \
|
||||||
application/x-fsdirectory \
|
application/x-fsdirectory \
|
||||||
application/zip \
|
application/zip
|
||||||
image/svg+xml \
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user