254 lines
6.9 KiB
C++
254 lines
6.9 KiB
C++
/*
|
|
Copyright© 2021 John Sennesael
|
|
|
|
UsenetSearch is Free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
UsenetSearch is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with UsenetSearch. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "usenetsearch/Configuration.h"
|
|
|
|
#include "usenetsearch/ScopeExit.h"
|
|
#include "usenetsearch/StringUtils.h"
|
|
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <regex>
|
|
#include <string>
|
|
|
|
namespace usenetsearch {
|
|
|
|
std::uint16_t Configuration::BatchSize() const
|
|
{
|
|
return m_batchSize;
|
|
}
|
|
|
|
std::filesystem::path Configuration::DatabasePath() const
|
|
{
|
|
return m_databasePath;
|
|
}
|
|
|
|
std::vector<std::string>& Configuration::FilterEraseSubtoken()
|
|
{
|
|
return m_filterEraseSubtoken;
|
|
}
|
|
|
|
std::vector<std::regex>& Configuration::FilterNewsgroupBlacklist()
|
|
{
|
|
return m_filterNewsgroupBlacklist;
|
|
}
|
|
|
|
std::vector<std::regex>& Configuration::FilterNewsgroupWhitelist()
|
|
{
|
|
return m_filterNewsgroupWhitelist;
|
|
}
|
|
|
|
std::vector<std::string>& Configuration::FilterWordsNoSubtoken()
|
|
{
|
|
return m_filterWordsNoSubtoken;
|
|
}
|
|
|
|
std::uint16_t Configuration::MaxThreads() const
|
|
{
|
|
return m_maxThreads;
|
|
}
|
|
|
|
std::uint8_t Configuration::MaxTreeDepth() const
|
|
{
|
|
return m_maxTreeDepth;
|
|
}
|
|
|
|
std::uint16_t Configuration::MinSubtokenWords() const
|
|
{
|
|
return m_minSubtokenWords;
|
|
}
|
|
|
|
std::string Configuration::NNTPServerHost() const
|
|
{
|
|
return m_nntpServerHost;
|
|
}
|
|
|
|
std::string Configuration::NNTPServerPassword() const
|
|
{
|
|
return m_nntpServerPassword;
|
|
}
|
|
|
|
int Configuration::NNTPServerPort() const
|
|
{
|
|
return m_nntpServerPort;
|
|
}
|
|
|
|
bool Configuration::NNTPServerSSL() const
|
|
{
|
|
return m_nntpServerSSL;
|
|
}
|
|
|
|
std::string Configuration::NNTPServerUser() const
|
|
{
|
|
return m_nntpServerUser;
|
|
}
|
|
|
|
void Configuration::Open(const std::string& filename)
|
|
{
|
|
std::string line;
|
|
std::ifstream fin(filename.c_str());
|
|
if (!fin.is_open())
|
|
{
|
|
throw ConfigurationException(EINVAL,
|
|
"Could not open configuration file: " + filename
|
|
);
|
|
}
|
|
ScopeExit finCloser([&fin](){ fin.close(); });
|
|
int line_nr = 0;
|
|
while(std::getline(fin,line))
|
|
{
|
|
line_nr++;
|
|
line = StringTrim(line);
|
|
// Immediately skip blank lines.
|
|
if (line == "") continue;
|
|
// Skip comments.
|
|
if (StringStartsWith("#",line)==true) continue;
|
|
// Split line in key-value pair.
|
|
const auto kvp = StringSplit(line, std::string{":"}, 2);
|
|
if (kvp.size() != 2)
|
|
{
|
|
throw ConfigurationException(EINVAL,
|
|
std::string("Invalid configuration in ")
|
|
+ filename + std::string(" line ")
|
|
+ std::to_string(line_nr)
|
|
);
|
|
}
|
|
const std::string key = StringToLower(kvp[0]);
|
|
const std::string value = StringTrim(kvp[1]);
|
|
if (key == "batch_size")
|
|
{
|
|
m_batchSize = stoi(value);
|
|
}
|
|
else if (key == "database_path")
|
|
{
|
|
m_databasePath = value;
|
|
}
|
|
else if (key == "filter_erase_subtoken")
|
|
{
|
|
const auto tokens = StringSplit(value, std::string{","});
|
|
for (const auto& token: tokens)
|
|
{
|
|
const auto trimmedToken = StringToLower(StringTrim(token));
|
|
if (trimmedToken != "")
|
|
{
|
|
m_filterEraseSubtoken.emplace_back(trimmedToken);
|
|
}
|
|
}
|
|
}
|
|
else if (key == "filter_newsgroup_blacklist")
|
|
{
|
|
try
|
|
{
|
|
std::regex re(value);
|
|
m_filterNewsgroupBlacklist.emplace_back(re);
|
|
}
|
|
catch (const std::regex_error& e)
|
|
{
|
|
throw ConfigurationException(EINVAL,
|
|
std::string("Invalid configuration in ")
|
|
+ filename + std::string(" line ")
|
|
+ std::to_string(line_nr) + " : Regular expression \""
|
|
+ value + "\" did not parse: " + e.what()
|
|
);
|
|
}
|
|
}
|
|
else if (key == "filter_newsgroup_whitelist")
|
|
{
|
|
try
|
|
{
|
|
std::regex re(value);
|
|
m_filterNewsgroupWhitelist.emplace_back(re);
|
|
}
|
|
catch (const std::regex_error& e)
|
|
{
|
|
throw ConfigurationException(EINVAL,
|
|
std::string("Invalid configuration in ")
|
|
+ filename + std::string(" line ")
|
|
+ std::to_string(line_nr) + " : Regular expression \""
|
|
+ value + "\" did not parse: " + e.what()
|
|
);
|
|
}
|
|
}
|
|
else if (key == "filter_no_subtoken")
|
|
{
|
|
const auto tokens = StringSplit(value, std::string{","});
|
|
for (const auto& token: tokens)
|
|
{
|
|
const auto trimmedToken = StringToLower(StringTrim(token));
|
|
if (trimmedToken != "")
|
|
{
|
|
m_filterWordsNoSubtoken.emplace_back(trimmedToken);
|
|
}
|
|
}
|
|
}
|
|
else if (key == "max_threads")
|
|
{
|
|
m_maxThreads = stoi(value);
|
|
}
|
|
else if (key == "max_tree_depth")
|
|
{
|
|
m_maxTreeDepth = stoi(value);
|
|
}
|
|
else if (key == "minimum_subtoken_words")
|
|
{
|
|
m_minSubtokenWords = stoi(value);
|
|
}
|
|
else if (key == "nntp_server_host")
|
|
{
|
|
m_nntpServerHost = value;
|
|
}
|
|
else if (key == "nntp_server_pass")
|
|
{
|
|
m_nntpServerPassword = value;
|
|
}
|
|
else if (key == "nntp_server_port")
|
|
{
|
|
m_nntpServerPort = stoi(value);
|
|
}
|
|
else if (key == "nntp_server_use_ssl")
|
|
{
|
|
try
|
|
{
|
|
m_nntpServerSSL = StringToBoolean(value);
|
|
}
|
|
catch (const StringException& e)
|
|
{
|
|
fin.close();
|
|
throw ConfigurationException(EINVAL,
|
|
std::string("Invalid configuration in ")
|
|
+ filename + std::string(" line ")
|
|
+ std::to_string(line_nr) + " - " + e.what()
|
|
);
|
|
}
|
|
}
|
|
else if (key == "nntp_server_user")
|
|
{
|
|
m_nntpServerUser = value;
|
|
}
|
|
else
|
|
{
|
|
throw ConfigurationException(EINVAL,
|
|
std::string("Invalid configuration in ")
|
|
+ filename + std::string(" line ")
|
|
+ std::to_string(line_nr)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace usenetsearch
|