privacore-open-source-searc.../FxExplicitKeywords.cpp
2018-01-19 14:30:43 +01:00

107 lines
2.3 KiB
C++

//This file is developed by Privacore ApS and covered by the GNU Affero General Public License. See LICENSE for details.
#include "FxExplicitKeywords.h"
#include "GbMutex.h"
#include "ScopedLock.h"
#include "Log.h"
#include <map>
#include <time.h>
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
static const char filename[] = "explicit_keywords.txt";
static GbMutex mtx;
static std::map<std::string,std::string> m;
static const time_t check_interval = 10;
static time_t next_check_time = 0;
static time_t last_mtime = 0;
static void reload_if_needed(bool detailed_log) {
time_t now=time(0);
if(now<next_check_time)
return;
next_check_time = now + check_interval;
FILE *fp = fopen(filename,"r");
if(!fp) {
if(errno!=ENOENT) //normal
log(LOG_ERROR,"fopen(%s) failed with errno=%d (%s)", filename, errno, strerror(errno));
else if(detailed_log)
log(LOG_DEBUG,"%s doesn't exist", filename);
return;
}
struct stat st;
if(fstat(fileno(fp),&st)!=0) {
log(LOG_ERROR, "fstat(%s) failed with errno=%d", filename, errno);
fclose(fp);
return;
}
if(st.st_mtime==last_mtime) {
//hasn't changed
fclose(fp);
if(detailed_log)
log(LOG_DEBUG,"%s hasn't changed since last time", filename);
return;
}
if(last_mtime==0)
log(LOG_INFO, "Loading %s", filename);
else
log(LOG_INFO, "%s has changed. Reloading it", filename);
last_mtime = st.st_mtime;
//The file has changed
int entry_count = 0;
std::map<std::string,std::string> new_m;
char line[4096];
while(fgets(line,sizeof(line),fp)) {
if(line[0]=='#')
continue;
char *p;
p = strchr(line,'\n');
if(p) *p='\0';
p = strchr(line,'\r'); //why are you using a dos editor?
if(p) *p='\0';
p = strchr(line,'\t');
if(!p)
continue;
*p = '\0';
const char *url = p+1;
new_m[url] = line;
entry_count++;
}
fclose(fp);
ScopedLock sl(mtx);
m.swap(new_m);
sl.unlock();
log(LOG_INFO, "%s reloaded. Entries: %d", filename, entry_count);
}
bool ExplicitKeywords::initialize() {
reload_if_needed(true);
return true;
}
void ExplicitKeywords::finalize() {
m.clear();
}
std::string ExplicitKeywords::lookupExplicitKeywords(const std::string &url) {
reload_if_needed(false);
ScopedLock sl(mtx);
auto iter = m.find(url);
if(iter!=m.end())
return iter->second;
else
return "";
}