Refactored for better readability.
continuous-integration/drone/push Build is passing Details

Ran clang-tidy over the code, took most of the advice.
This commit is contained in:
tastytea 2019-09-25 03:58:29 +02:00
parent 31de8ff620
commit f48b07f323
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
29 changed files with 247 additions and 226 deletions

View File

@ -14,8 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef REMWHAREAD_ADOC_HPP #ifndef REMWHAREAD_EXPORT_ADOC_HPP
#define REMWHAREAD_ADOC_HPP #define REMWHAREAD_EXPORT_ADOC_HPP
#include <map> #include <map>
#include <string> #include <string>
@ -48,27 +48,27 @@ namespace Export
using replacemap = const std::map<const string, const string>; using replacemap = const std::map<const string, const string>;
//! Replace strings in text. //! Replace strings in text.
const string replace(string text, const replacemap &replacements) const; string replace(string text, const replacemap &replacements) const;
//! Replaces characters in tags that asciidoctor doesn't like. //! Replaces characters in tags that asciidoctor doesn't like.
const string replace_in_tag(const string &text) const; string replace_in_tag(const string &text) const;
//! Replaces characters in title that asciidoctor doesn't like. //! Replaces characters in title that asciidoctor doesn't like.
const string replace_in_title(const string &text) const; string replace_in_title(const string &text) const;
//! Replaces characters in URI that asciidoctor doesn't like. //! Replaces characters in URI that asciidoctor doesn't like.
const string replace_in_uri(const string &text) const; string replace_in_uri(const string &text) const;
//! Print things sorted by tag. //! Print things sorted by tag.
void print_tags(const tagmap &tags) const; void print_tags(const tagmap &tags) const;
//! Get ISO-8601 day from Database::entry. //! Get ISO-8601 day from Database::entry.
const string get_day(const Database::entry &entry) const; string get_day(const Database::entry &entry) const;
//! Get ISO-8601 time from Database::entry. //! Get ISO-8601 time from Database::entry.
const string get_time(const Database::entry &entry) const; string get_time(const Database::entry &entry) const;
}; };
} } // namespace Export
} } // namespace remwharead
#endif // REMWHAREAD_ADOC_HPP #endif // REMWHAREAD_EXPORT_ADOC_HPP

View File

@ -14,8 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef REMWHAREAD_BOOKMARKS_HPP #ifndef REMWHAREAD_EXPORT_BOOKMARKS_HPP
#define REMWHAREAD_BOOKMARKS_HPP #define REMWHAREAD_EXPORT_BOOKMARKS_HPP
#include "export.hpp" #include "export.hpp"
@ -34,9 +34,10 @@ namespace Export
{ {
public: public:
using ExportBase::ExportBase; using ExportBase::ExportBase;
virtual void print() const override;
};
}
}
#endif // REMWHAREAD_BOOKMARKS_HPP void print() const override;
};
} // namespace Export
} // namespace remwharead
#endif // REMWHAREAD_EXPORT_BOOKMARKS_HPP

View File

@ -14,8 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef REMWHAREAD_CSV_HPP #ifndef REMWHAREAD_EXPORT_CSV_HPP
#define REMWHAREAD_CSV_HPP #define REMWHAREAD_EXPORT_CSV_HPP
#include <string> #include <string>
#include "export.hpp" #include "export.hpp"
@ -38,13 +38,13 @@ namespace Export
public: public:
using ExportBase::ExportBase; using ExportBase::ExportBase;
virtual void print() const override; void print() const override;
private: private:
//! replaces " with "". //! replaces " with "".
const string quote(string field) const; string quote(string field) const;
}; };
} } // namespace Export
} } // namespace remwharead
#endif // REMWHAREAD_CSV_HPP #endif // REMWHAREAD_EXPORT_CSV_HPP

View File

@ -14,21 +14,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef REMWHAREAD_EXPORT_HPP #ifndef REMWHAREAD_EXPORT_EXPORT_HPP
#define REMWHAREAD_EXPORT_HPP #define REMWHAREAD_EXPORT_EXPORT_HPP
#include <list> #include <list>
#include <iostream> #include <iostream>
#include "sqlite.hpp" #include "sqlite.hpp"
using std::list;
using std::ostream;
using std::cout;
namespace remwharead namespace remwharead
{ {
namespace Export namespace Export
{ {
using std::list;
using std::ostream;
using std::cout;
/*! /*!
* @brief Base class for exports. * @brief Base class for exports.
* *
@ -64,10 +63,9 @@ namespace Export
* *
* @return Sorted list of Database::entry. * @return Sorted list of Database::entry.
*/ */
const list<Database::entry> list<Database::entry> sort_entries(list<Database::entry> entries) const;
sort_entries(list<Database::entry> entries) const;
}; };
} } // namespace Export
} } // namespace remwharead
#endif // REMWHAREAD_EXPORT_HPP #endif // REMWHAREAD_EXPORT_EXPORT_HPP

View File

@ -14,8 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef REMWHAREAD_JSON_HPP #ifndef REMWHAREAD_EXPORT_JSON_HPP
#define REMWHAREAD_JSON_HPP #define REMWHAREAD_EXPORT_JSON_HPP
#include <string> #include <string>
#include "export.hpp" #include "export.hpp"
@ -38,9 +38,9 @@ namespace Export
public: public:
using ExportBase::ExportBase; using ExportBase::ExportBase;
virtual void print() const override; void print() const override;
}; };
} } // namespace Export
} } // namespace remwharead
#endif // REMWHAREAD_JSON_HPP #endif // REMWHAREAD_EXPORT_JSON_HPP

View File

@ -14,8 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef REMWHAREAD_RSS_HPP #ifndef REMWHAREAD_EXPORT_RSS_HPP
#define REMWHAREAD_RSS_HPP #define REMWHAREAD_EXPORT_RSS_HPP
#include <string> #include <string>
#include "export.hpp" #include "export.hpp"
@ -38,9 +38,9 @@ namespace Export
public: public:
using ExportBase::ExportBase; using ExportBase::ExportBase;
virtual void print() const override; void print() const override;
}; };
} } // namespace Export
} } // namespace remwharead
#endif // REMWHAREAD_RSS_HPP #endif // REMWHAREAD_EXPORT_RSS_HPP

View File

@ -14,8 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef REMWHAREAD_SIMPLE_HPP #ifndef REMWHAREAD_EXPORT_SIMPLE_HPP
#define REMWHAREAD_SIMPLE_HPP #define REMWHAREAD_EXPORT_SIMPLE_HPP
#include "export.hpp" #include "export.hpp"
@ -34,9 +34,9 @@ namespace Export
{ {
public: public:
using ExportBase::ExportBase; using ExportBase::ExportBase;
virtual void print() const override; void print() const override;
}; };
} } // namespace Export
} } // namespace remwharead
#endif // REMWHAREAD_SIMPLE_HPP #endif // REMWHAREAD_EXPORT_SIMPLE_HPP

View File

@ -43,7 +43,7 @@ namespace remwharead
* *
* @since 0.7.0 * @since 0.7.0
*/ */
explicit Search(const list<Database::entry> &entries); explicit Search(list<Database::entry> entries);
/*! /*!
* @brief %Search in tags of database entries. * @brief %Search in tags of database entries.
@ -57,8 +57,8 @@ namespace remwharead
* *
* @since 0.7.0 * @since 0.7.0
*/ */
const list<Database::entry> search_tags(string expression, list<Database::entry> search_tags(const string &expression, bool is_re)
const bool is_re) const; const;
/*! /*!
* @brief %Search in full text of database entries. * @brief %Search in full text of database entries.
@ -72,8 +72,8 @@ namespace remwharead
* *
* @since 0.7.0 * @since 0.7.0
*/ */
const list<Database::entry> search_all(string expression, list<Database::entry> search_all(const string &expression, bool is_re)
const bool is_re) const; const;
/*! /*!
* @brief Spawn threads of search_all(), if it seems sensible. * @brief Spawn threads of search_all(), if it seems sensible.
@ -88,9 +88,9 @@ namespace remwharead
* *
* @since 0.7.2 * @since 0.7.2
*/ */
// TODO: Think of something more elegant. // TODO(tastytea): Think of something more elegant.
const list<Database::entry> search_all_threaded(string expression, list<Database::entry> search_all_threaded(const string &expression,
const bool is_re) const; bool is_re) const;
private: private:
const list<Database::entry> _entries; const list<Database::entry> _entries;
@ -106,15 +106,15 @@ namespace remwharead
* *
* @since 0.7.0 * @since 0.7.0
*/ */
const vector<vector<string>> parse_expression(string expression) const; vector<vector<string>> parse_expression(const string &expression) const;
/*! /*!
* @brief Convert str to lowercase. Works with unicode. * @brief Convert str to lowercase. Works with unicode.
* *
* @since 0.7.0 * @since 0.7.0
*/ */
inline const string to_lowercase(const string &str) const; inline string to_lowercase(const string &str) const;
}; };
} } // namespace remwharead
#endif // REMWHAREAD_SEARCH_HPP #endif // REMWHAREAD_SEARCH_HPP

View File

@ -52,7 +52,7 @@ namespace remwharead
* *
* @headerfile sqlite.hpp remwharead/sqlite.hpp * @headerfile sqlite.hpp remwharead/sqlite.hpp
*/ */
typedef struct entry using entry = struct entry
{ {
string uri; string uri;
string archive_uri; string archive_uri;
@ -75,8 +75,8 @@ namespace remwharead
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const string fulltext_oneline() const; string fulltext_oneline() const;
} entry; };
/*! /*!
* @brief Connects to the database and creates it if necessary. * @brief Connects to the database and creates it if necessary.
@ -90,7 +90,7 @@ namespace remwharead
* *
* @since 0.6.0 * @since 0.6.0
*/ */
operator bool() const; explicit operator bool() const;
/*! /*!
* @brief Store a Database::entry in the database. * @brief Store a Database::entry in the database.
@ -104,9 +104,8 @@ namespace remwharead
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const list<entry> retrieve( list<entry> retrieve(const time_point &start = time_point(),
const time_point &start = time_point(), const time_point &end = system_clock::now()) const;
const time_point &end = system_clock::now()) const;
private: private:
fs::path _dbpath; fs::path _dbpath;
@ -115,6 +114,6 @@ namespace remwharead
}; };
using DB = Database; using DB = Database;
} } // namespace remwharead
#endif // REMWHAREAD_SQLITE_HPP #endif // REMWHAREAD_SQLITE_HPP

View File

@ -36,8 +36,7 @@ namespace remwharead
* @param strtime Time string in ISO 8601 or SQLite format. * @param strtime Time string in ISO 8601 or SQLite format.
* @param sqlite Is the string in SQLite format? * @param sqlite Is the string in SQLite format?
*/ */
const time_point string_to_timepoint(const string &strtime, time_point string_to_timepoint(const string &strtime, bool sqlite = false);
bool sqlite = false);
/*! /*!
* @brief Convert time_point to ISO 8601 or SQLite time-string. * @brief Convert time_point to ISO 8601 or SQLite time-string.
@ -47,7 +46,7 @@ namespace remwharead
* @param time_point The std::chrono::system_clock::time_point. * @param time_point The std::chrono::system_clock::time_point.
* @param sqlite Is the string in SQLite format? * @param sqlite Is the string in SQLite format?
*/ */
const string timepoint_to_string(const time_point &tp, bool sqlite = false); string timepoint_to_string(const time_point &tp, bool sqlite = false);
} } // namespace remwharead
#endif // REMWHAREAD_TIME_HPP #endif // REMWHAREAD_TIME_HPP

View File

@ -38,6 +38,6 @@ namespace remwharead
json, json,
rss rss
}; };
} } // namespace remwharead
#endif // REMWHAREAD_TYPES_HPP #endif // REMWHAREAD_TYPES_HPP

View File

@ -32,7 +32,7 @@ namespace remwharead
* *
* @headerfile uri.hpp remwharead/uri.hpp * @headerfile uri.hpp remwharead/uri.hpp
*/ */
typedef struct html_extract using html_extract = struct html_extract
{ {
bool successful = false; bool successful = false;
string error; string error;
@ -40,8 +40,8 @@ namespace remwharead
string description; string description;
string fulltext; string fulltext;
operator bool(); explicit operator bool();
} html_extract; };
/*! /*!
* @brief The result of the call to the archive service. * @brief The result of the call to the archive service.
@ -52,14 +52,14 @@ namespace remwharead
* *
* @headerfile uri.hpp remwharead/uri.hpp * @headerfile uri.hpp remwharead/uri.hpp
*/ */
typedef struct archive_answer using archive_answer = struct archive_answer
{ {
bool successful = false; bool successful = false;
string error; string error;
string uri; string uri;
operator bool(); explicit operator bool();
} archive_answer; };
/*! /*!
* @brief Download, archive and process an %URI. * @brief Download, archive and process an %URI.
@ -79,22 +79,27 @@ namespace remwharead
* *
* @since 0.6.0 * @since 0.6.0
*/ */
explicit URI(const string &uri); explicit URI(string uri);
virtual ~URI(); virtual ~URI();
URI(const URI &other) = default;
URI &operator=(const URI &other) = default;
URI(URI &&other) = default;
URI &operator=(URI &&other) = default;
/*! /*!
* @brief Download %URI and extract title, description and full text. * @brief Download %URI and extract title, description and full text.
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const html_extract get(); html_extract get();
/*! /*!
* @brief Save %URI in archive and return archive-URI. * @brief Save %URI in archive and return archive-URI.
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const archive_answer archive(); archive_answer archive();
protected: protected:
string _uri; string _uri;
@ -104,29 +109,28 @@ namespace remwharead
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const string make_request(const string &uri, string make_request(const string &uri, bool archive = false) const;
bool archive = false) const;
/*! /*!
* @brief Extract the title from an HTML page. * @brief Extract the title from an HTML page.
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const string extract_title(const string &html); string extract_title(const string &html);
/*! /*!
* @brief Extract the description from an HTML page. * @brief Extract the description from an HTML page.
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const string extract_description(const string &html); string extract_description(const string &html);
/*! /*!
* @brief Removes HTML tags and superflous spaces from an HTML page. * @brief Removes HTML tags and superflous spaces from an HTML page.
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const string strip_html(const string &html); string strip_html(const string &html);
/*! /*!
* @brief Remove HTML tags. * @brief Remove HTML tags.
@ -136,23 +140,29 @@ namespace remwharead
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const string remove_html_tags(const string &html, string remove_html_tags(const string &html, const string &tag = "");
const string &tag = "");
/*! /*!
* @brief Convert HTML entities to UTF-8. * @brief Convert HTML entities to UTF-8.
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const string unescape_html(string html); string unescape_html(string html);
/*! /*!
* @brief Replace newlines with spaces. * @brief Replace newlines with spaces.
* *
* @since 0.6.0 * @since 0.6.0
*/ */
const string remove_newlines(string text); string remove_newlines(string text);
/*!
* @brief Set proxy server.
*
* @since 0.8.5
*/
void set_proxy();
}; };
} } // namespace remwharead
#endif // REMWHAREAD_URI_HPP #endif // REMWHAREAD_URI_HPP

View File

@ -1,3 +1,3 @@
# Write version in header # Write version in header
configure_file("version.hpp.in" configure_file("version.hpp.in"
"${PROJECT_BINARY_DIR}/version.hpp") "${CMAKE_CURRENT_BINARY_DIR}/version.hpp")

View File

@ -10,7 +10,7 @@ set_target_properties(${PROJECT_NAME}-cli
PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
target_include_directories(${PROJECT_NAME}-cli target_include_directories(${PROJECT_NAME}-cli
PRIVATE "${PROJECT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") PRIVATE "${PROJECT_BINARY_DIR}/src" "${CMAKE_CURRENT_SOURCE_DIR}")
target_link_libraries(${PROJECT_NAME}-cli target_link_libraries(${PROJECT_NAME}-cli
PRIVATE ${PROJECT_NAME}) PRIVATE ${PROJECT_NAME})

View File

@ -33,6 +33,7 @@
#include "search.hpp" #include "search.hpp"
using namespace remwharead; using namespace remwharead;
using namespace remwharead_cli;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::string; using std::string;
@ -58,7 +59,7 @@ int App::main(const std::vector<std::string> &args)
{ {
return 1; return 1;
} }
if (args.size() > 0) if (!args.empty())
{ {
_uri = args[0]; _uri = args[0];
} }

View File

@ -20,6 +20,7 @@
#include "version.hpp" #include "version.hpp"
#include "remwharead_cli.hpp" #include "remwharead_cli.hpp"
using namespace remwharead_cli;
using std::cout; using std::cout;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
@ -31,8 +32,6 @@ App::App()
: _help_requested(false) : _help_requested(false)
, _version_requested(false) , _version_requested(false)
, _argument_error(false) , _argument_error(false)
, _uri()
, _tags()
, _format(export_format::undefined) , _format(export_format::undefined)
, _timespan({ time_point(), system_clock::now() }) , _timespan({ time_point(), system_clock::now() })
, _archive(true) , _archive(true)

View File

@ -26,40 +26,43 @@
#include "types.hpp" #include "types.hpp"
#include "time.hpp" #include "time.hpp"
using namespace remwharead; namespace remwharead_cli
using std::string;
using std::vector;
using std::array;
using std::chrono::system_clock;
using time_point = system_clock::time_point;
using Poco::Util::OptionSet;
class App : public Poco::Util::Application
{ {
public: using namespace remwharead;
App(); using std::string;
using std::vector;
using std::array;
using std::chrono::system_clock;
using time_point = system_clock::time_point;
using Poco::Util::OptionSet;
protected: class App : public Poco::Util::Application
void defineOptions(OptionSet& options); {
void handle_info(const std::string &name, const std::string &); public:
void handle_options(const std::string &name, const std::string &value); App();
void print_help();
void print_version();
int main(const std::vector<std::string> &args);
private: protected:
bool _help_requested; void defineOptions(OptionSet& options) override;
bool _version_requested; void handle_info(const std::string &name, const std::string &);
bool _argument_error; void handle_options(const std::string &name, const std::string &value);
string _uri; void print_help();
vector<string> _tags; void print_version();
export_format _format; int main(const std::vector<std::string> &args) override;
string _file;
array<time_point, 2> _timespan; private:
string _search_tags; bool _help_requested;
string _search_all; bool _version_requested;
bool _archive; bool _argument_error;
bool _regex; string _uri;
}; vector<string> _tags;
export_format _format;
string _file;
array<time_point, 2> _timespan;
string _search_tags;
string _search_all;
bool _archive;
bool _regex;
};
} // namespace remwharead_cli
#endif // REMWHAREAD_PARSE_OPTIONS_HPP #endif // REMWHAREAD_PARSE_OPTIONS_HPP

View File

@ -18,7 +18,7 @@ set_target_properties(${PROJECT_NAME} PROPERTIES
target_include_directories(${PROJECT_NAME} target_include_directories(${PROJECT_NAME}
PRIVATE PRIVATE
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>" # version.hpp "$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/src>" # version.hpp
PUBLIC PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>" "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>") "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
@ -54,4 +54,3 @@ install(TARGETS ${PROJECT_NAME}
EXPORT "${PROJECT_NAME}Targets" EXPORT "${PROJECT_NAME}Targets"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}") ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")

View File

@ -35,9 +35,9 @@ namespace remwharead
try try
{ {
_out << "= Visited things\n" _out << "= Visited things\n"
<< ":Author: remwharead " << global::version << endl << ":Author: remwharead " << global::version << "\n"
<< ":Date: " << ":Date: "
<< timepoint_to_string(system_clock::now()) << endl << timepoint_to_string(system_clock::now()) << "\n"
<< ":TOC: right\n" << ":TOC: right\n"
<< ":TOCLevels: 2\n" << ":TOCLevels: 2\n"
<< ":!webfonts:\n\n"; << ":!webfonts:\n\n";
@ -122,8 +122,8 @@ namespace remwharead
} }
} }
const string Export::AsciiDoc::replace(string text, string Export::AsciiDoc::replace(string text,
const replacemap &replacements) const const replacemap &replacements) const
{ {
for (const std::pair<const string, const string> &sr : replacements) for (const std::pair<const string, const string> &sr : replacements)
{ {
@ -136,9 +136,9 @@ namespace remwharead
} }
return text; return text;
} }
const string Export::AsciiDoc::replace_in_tag(const string &text) const string Export::AsciiDoc::replace_in_tag(const string &text) const
{ {
// TODO: Find a better solution. // TODO(tastytea): Find a better solution.
const replacemap replacements = const replacemap replacements =
{ {
{ " ", "-" }, { "§", "-" }, { " ", "-" }, { "§", "-" },
@ -164,13 +164,13 @@ namespace remwharead
return replace(text, replacements); return replace(text, replacements);
} }
const string Export::AsciiDoc::replace_in_title(const string &text) const string Export::AsciiDoc::replace_in_title(const string &text) const
{ {
// [ is implicitly escaped if the corresponding ] is. // [ is implicitly escaped if the corresponding ] is.
return replace(text, {{ "]", "\\]" }}); return replace(text, {{ "]", "\\]" }});
} }
const string Export::AsciiDoc::replace_in_uri(const string &text) const string Export::AsciiDoc::replace_in_uri(const string &text) const
{ {
return replace(text, return replace(text,
{ {
@ -191,17 +191,14 @@ namespace remwharead
{ // Sort by number of occurrences if they are different. { // Sort by number of occurrences if they are different.
return a.second.size() > b.second.size(); return a.second.size() > b.second.size();
} }
else
{ // Sort by tag names otherwise. // Sort by tag names otherwise.
const std::locale loc; const std::locale loc;
const std::collate<char> &coll = const auto &coll = std::use_facet<std::collate<char>>(loc);
std::use_facet<std::collate<char>>(loc); return (
return ( coll.compare(
coll.compare( &a.first[0], &a.first[0] + a.first.size(),
a.first.data(), a.first.data() + a.first.length(), &b.first[0], &b.first[0] + b.first.size()) == -1);
b.first.data(), b.first.data() + b.first.length())
== -1);
}
}; };
std::sort(sortedtags.begin(), sortedtags.end(), compare_tags); std::sort(sortedtags.begin(), sortedtags.end(), compare_tags);
@ -239,15 +236,15 @@ namespace remwharead
_out << endl; _out << endl;
} }
const string Export::AsciiDoc::get_day(const Database::entry &entry) const string Export::AsciiDoc::get_day(const Database::entry &entry) const
{ {
const string datetime = timepoint_to_string(entry.datetime); const string datetime = timepoint_to_string(entry.datetime);
return datetime.substr(0, datetime.find('T')); return datetime.substr(0, datetime.find('T'));
} }
const string Export::AsciiDoc::get_time(const Database::entry &entry) const string Export::AsciiDoc::get_time(const Database::entry &entry) const
{ {
const string datetime = timepoint_to_string(entry.datetime); const string datetime = timepoint_to_string(entry.datetime);
return datetime.substr(datetime.find('T') + 1); return datetime.substr(datetime.find('T') + 1);
} }
} } // namespace remwharead

View File

@ -56,4 +56,4 @@ namespace remwharead
_out << "</DL><p>\n" _out << "</DL><p>\n"
<< "</DL><p>\n"; << "</DL><p>\n";
} }
} } // namespace remwharead

View File

@ -26,8 +26,8 @@ namespace remwharead
{ {
try try
{ {
_out << "\"URI\",\"Archived URI\",\"Date & time\",\"Tags\"," _out << R"("URI","Archived URI","Date & time","Tags",)"
<< "\"Title\",\"Description\",\"Full text\"\r\n"; << R"("Title","Description","Full text")" << "\r\n";
for (const Database::entry &entry : _entries) for (const Database::entry &entry : _entries)
{ {
string strtags; string strtags;
@ -54,7 +54,7 @@ namespace remwharead
} }
} }
const string Export::CSV::quote(string field) const string Export::CSV::quote(string field) const
{ {
size_t pos = 0; size_t pos = 0;
while ((pos = field.find('"', pos)) != std::string::npos) while ((pos = field.find('"', pos)) != std::string::npos)
@ -63,4 +63,4 @@ namespace remwharead
} }
return field; return field;
} }
} } // namespace remwharead

View File

@ -26,7 +26,7 @@ namespace Export
, _out(out) , _out(out)
{} {}
const list<Database::entry> list<Database::entry>
ExportBase::sort_entries(list<Database::entry> entries) const ExportBase::sort_entries(list<Database::entry> entries) const
{ {
entries.sort([](const auto &a, const auto &b) entries.sort([](const auto &a, const auto &b)
@ -37,5 +37,5 @@ namespace Export
return entries; return entries;
} }
} } // namespace Export
} } // namespace remwharead

View File

@ -58,4 +58,4 @@ namespace remwharead
cerr << "Error in " << __func__ << ": " << e.what() << endl; cerr << "Error in " << __func__ << ": " << e.what() << endl;
} }
} }
} } // namespace remwharead

View File

@ -41,7 +41,8 @@ namespace remwharead
try try
{ {
XMLWriter writer(_out, XMLWriter::CANONICAL); XMLWriter writer(_out, XMLWriter::CANONICAL);
AttributesImpl attrs_rss, attrs_guid; AttributesImpl attrs_rss;
AttributesImpl attrs_guid;
constexpr char timefmt_rfc822[] = "%w, %d %b %Y %H:%M:%S %Z"; constexpr char timefmt_rfc822[] = "%w, %d %b %Y %H:%M:%S %Z";
attrs_rss.addAttribute("", "", "version", "", "2.0"); attrs_rss.addAttribute("", "", "version", "", "2.0");
@ -114,7 +115,7 @@ namespace remwharead
string description = entry.description; string description = entry.description;
if (!description.empty()) if (!description.empty())
{ {
description = "<p>" + description + "</p>"; description = "<p>" + description.append("</p>");
} }
if (!entry.tags.empty()) if (!entry.tags.empty())
{ {
@ -133,7 +134,7 @@ namespace remwharead
{ {
description += "<p><strong>Archived version:</strong> " description += "<p><strong>Archived version:</strong> "
"<a href=\"" + entry.archive_uri + "\">" "<a href=\"" + entry.archive_uri + "\">"
+ entry.archive_uri + "</a>"; + entry.archive_uri + "</a></p>";
} }
writer.startElement("", "", "description"); writer.startElement("", "", "description");
writer.characters(description); writer.characters(description);
@ -152,4 +153,4 @@ namespace remwharead
cerr << "Error in " << __func__ << ": " << e.what() << endl; cerr << "Error in " << __func__ << ": " << e.what() << endl;
} }
} }
} } // namespace remwharead

View File

@ -38,4 +38,4 @@ namespace remwharead
_out << "<" << entry.uri << ">\n"; _out << "<" << entry.uri << ">\n";
} }
} }
} } // namespace remwharead

View File

@ -33,11 +33,11 @@ namespace remwharead
using std::move; using std::move;
using RegEx = Poco::RegularExpression; using RegEx = Poco::RegularExpression;
Search::Search(const list<Database::entry> &entries) Search::Search(list<Database::entry> entries)
:_entries(entries) :_entries(move(entries))
{} {}
const vector<vector<string>> Search::parse_expression(string expression) vector<vector<string>> Search::parse_expression(const string &expression)
const const
{ {
vector<vector<string>> searchlist; vector<vector<string>> searchlist;
@ -59,7 +59,7 @@ namespace remwharead
} }
{ {
for (string sub : subexpressions) for (const string &sub : subexpressions)
{ // Split each OR-slice at AND. { // Split each OR-slice at AND.
vector<string> terms; vector<string> terms;
pos = 0; pos = 0;
@ -79,13 +79,13 @@ namespace remwharead
return searchlist; return searchlist;
} }
const string Search::to_lowercase(const string &str) const string Search::to_lowercase(const string &str) const
{ {
return Poco::UTF8::toLower(str); return Poco::UTF8::toLower(str);
} }
const list<DB::entry> Search::search_tags(string expression, list<DB::entry> Search::search_tags(const string &expression,
const bool is_re) const const bool is_re) const
{ {
vector<vector<string>> searchlist = parse_expression(expression); vector<vector<string>> searchlist = parse_expression(expression);
list<DB::entry> result; list<DB::entry> result;
@ -108,17 +108,15 @@ namespace remwharead
const RegEx re("^" + tag + "$"); const RegEx re("^" + tag + "$");
return (re == s); return (re == s);
} }
else
{ return (s == tag);
return (s == tag);
}
}); });
if (it == entry.tags.end()) if (it == entry.tags.end())
{ {
matched = false; matched = false;
} }
} }
if (matched == true) if (matched)
{ {
result.push_back(entry); result.push_back(entry);
} }
@ -128,8 +126,8 @@ namespace remwharead
return result; return result;
} }
const list<DB::entry> Search::search_all(string expression, list<DB::entry> Search::search_all(const string &expression,
const bool is_re) const const bool is_re) const
{ {
vector<vector<string>> searchlist = parse_expression(expression); vector<vector<string>> searchlist = parse_expression(expression);
list<DB::entry> result = search_tags(expression, is_re); list<DB::entry> result = search_tags(expression, is_re);
@ -194,9 +192,7 @@ namespace remwharead
} }
} }
} }
if (matched_title == true if (matched_title || matched_description || matched_fulltext)
|| matched_description == true
|| matched_fulltext == true)
{ {
result.push_back(entry); result.push_back(entry);
} }
@ -206,8 +202,8 @@ namespace remwharead
return result; return result;
} }
const list<Database::entry> Search::search_all_threaded( list<Database::entry> Search::search_all_threaded(const string &expression,
string expression, const bool is_re) const const bool is_re) const
{ {
list<Database::entry> entries = _entries; list<Database::entry> entries = _entries;
@ -242,7 +238,9 @@ namespace remwharead
segments.push_back(move(segment)); segments.push_back(move(segment));
} }
// Move rest of `entries` into `segments`. // Move rest of `entries` into `segments`.
segments.push_back(move(entries)); list<Database::entry> segment;
segment.splice(segment.begin(), entries);
segments.push_back(move(segment));
list<thread> threads; list<thread> threads;
for (auto &segment : segments) for (auto &segment : segments)
@ -266,5 +264,6 @@ namespace remwharead
} }
return entries; return entries;
} }
} } // namespace remwharead

View File

@ -70,7 +70,7 @@ namespace remwharead
return (a.datetime == b.datetime); return (a.datetime == b.datetime);
} }
const string Database::entry::fulltext_oneline() const string Database::entry::fulltext_oneline() const
{ {
string oneline = fulltext; string oneline = fulltext;
size_t pos = 0; size_t pos = 0;
@ -112,13 +112,14 @@ namespace remwharead
} }
} }
const list<Database::entry> Database::retrieve( list<Database::entry> Database::retrieve(const time_point &start,
const time_point &start, const time_point &end) const const time_point &end) const
{ {
try try
{ {
Database::entry entrybuf; Database::entry entrybuf;
string datetime, strtags; string datetime;
string strtags;
Statement select(*_session); Statement select(*_session);
// bind() copies the value. // bind() copies the value.
@ -166,4 +167,4 @@ namespace remwharead
return {}; return {};
} }
} } // namespace remwharead

View File

@ -25,7 +25,7 @@ namespace remwharead
{ {
using std::array; using std::array;
const time_point string_to_timepoint(const string &strtime, bool sqlite) time_point string_to_timepoint(const string &strtime, bool sqlite)
{ {
std::stringstream sstime(strtime); std::stringstream sstime(strtime);
struct std::tm tm = {}; struct std::tm tm = {};
@ -42,7 +42,7 @@ namespace remwharead
return system_clock::from_time_t(time); return system_clock::from_time_t(time);
} }
const string timepoint_to_string(const time_point &tp, bool sqlite) string timepoint_to_string(const time_point &tp, bool sqlite)
{ {
constexpr std::uint16_t bufsize = 32; constexpr std::uint16_t bufsize = 32;
std::time_t time = system_clock::to_time_t(tp); std::time_t time = system_clock::to_time_t(tp);

View File

@ -21,6 +21,7 @@
#include <codecvt> #include <codecvt>
#include <exception> #include <exception>
#include <vector> #include <vector>
#include <utility>
#include <Poco/Net/HTTPClientSession.h> #include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPSClientSession.h> #include <Poco/Net/HTTPSClientSession.h>
#include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPRequest.h>
@ -42,6 +43,7 @@ namespace remwharead
using std::vector; using std::vector;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::move;
using Poco::Net::HTTPClientSession; using Poco::Net::HTTPClientSession;
using Poco::Net::HTTPSClientSession; using Poco::Net::HTTPSClientSession;
using Poco::Net::HTTPRequest; using Poco::Net::HTTPRequest;
@ -61,11 +63,16 @@ namespace remwharead
return successful; return successful;
} }
URI::URI(const string &uri) URI::URI(string uri)
:_uri(uri) :_uri(move(uri))
{ {
Poco::Net::initializeSSL(); Poco::Net::initializeSSL();
set_proxy();
}
void URI::set_proxy()
{
try try
{ {
HTTPClientSession::ProxyConfig proxy; HTTPClientSession::ProxyConfig proxy;
@ -74,20 +81,23 @@ namespace remwharead
"([^:/]+)(?::([\\d]{1,5}))?/?$"); "([^:/]+)(?::([\\d]{1,5}))?/?$");
vector<string> matches; vector<string> matches;
if (re_proxy.split(env_proxy, matches) >= 4) if (re_proxy.split(env_proxy, matches) < 4)
{ {
proxy.username = matches[1]; return;
proxy.password = matches[2]; }
proxy.host = matches[3];
if (!matches[4].empty()) proxy.username = matches[1];
proxy.password = matches[2];
proxy.host = matches[3];
if (!matches[4].empty())
{
const std::uint32_t &port = std::stoul(matches[4]);
if (port > 65535)
{ {
const std::uint32_t &port = std::stoul(matches[4]); throw std::invalid_argument(
if (port > 65535) "Proxy port number out of range");
{
throw std::invalid_argument("Port number out of range");
}
proxy.port = port;
} }
proxy.port = port;
} }
HTTPClientSession::setGlobalProxyConfig(proxy); HTTPClientSession::setGlobalProxyConfig(proxy);
} }
@ -100,10 +110,14 @@ namespace remwharead
{ {
cerr << "Error: " << e.what() << endl; cerr << "Error: " << e.what() << endl;
} }
catch (const std::exception &) catch (const Poco::NotFoundException &)
{ {
// No proxy found, no problem. // No proxy found, no problem.
} }
catch (const std::exception &e)
{
cerr << "Unexpected exception: " << e.what() << endl;
}
} }
URI::~URI() URI::~URI()
@ -111,7 +125,7 @@ namespace remwharead
Poco::Net::uninitializeSSL(); Poco::Net::uninitializeSSL();
} }
const html_extract URI::get() html_extract URI::get()
{ {
try try
{ {
@ -136,7 +150,7 @@ namespace remwharead
return { false, "Unknown error.", "", "", "" }; return { false, "Unknown error.", "", "", "" };
} }
const string URI::make_request(const string &uri, bool archive) const string URI::make_request(const string &uri, bool archive) const
{ {
Poco::URI poco_uri(uri); Poco::URI poco_uri(uri);
string method = string method =
@ -209,7 +223,7 @@ namespace remwharead
} }
} }
const string URI::extract_title(const string &html) string URI::extract_title(const string &html)
{ {
const RegEx re_htmlfile(".*\\.(.?html?|xml|rss)$", RegEx::RE_CASELESS); const RegEx re_htmlfile(".*\\.(.?html?|xml|rss)$", RegEx::RE_CASELESS);
if (_uri.substr(0, 4) == "http" || re_htmlfile.match(_uri)) if (_uri.substr(0, 4) == "http" || re_htmlfile.match(_uri))
@ -226,12 +240,12 @@ namespace remwharead
return ""; return "";
} }
const string URI::extract_description(const string &html) string URI::extract_description(const string &html)
{ {
const RegEx re_htmlfile(".*\\.(.?html?|xml|rss)$", RegEx::RE_CASELESS); const RegEx re_htmlfile(".*\\.(.?html?|xml|rss)$", RegEx::RE_CASELESS);
if (_uri.substr(0, 4) == "http" || re_htmlfile.match(_uri)) if (_uri.substr(0, 4) == "http" || re_htmlfile.match(_uri))
{ {
const RegEx re_desc("description\"[^>]+content=\"([^\"]+)", const RegEx re_desc(R"(description"[^>]+content="([^"]+))",
RegEx::RE_CASELESS); RegEx::RE_CASELESS);
vector<string> matches; vector<string> matches;
re_desc.split(html, matches); re_desc.split(html, matches);
@ -244,7 +258,7 @@ namespace remwharead
return ""; return "";
} }
const string URI::strip_html(const string &html) string URI::strip_html(const string &html)
{ {
string out; string out;
@ -253,7 +267,7 @@ namespace remwharead
out = remove_html_tags(out); // Remove tags. out = remove_html_tags(out); // Remove tags.
size_t pos = 0; size_t pos = 0;
while ((pos = out.find("\r", pos)) != std::string::npos) // Remove CR. while ((pos = out.find('\r', pos)) != std::string::npos) // Remove CR.
{ {
out.replace(pos, 1, ""); out.replace(pos, 1, "");
} }
@ -265,7 +279,7 @@ namespace remwharead
return unescape_html(out); return unescape_html(out);
} }
const string URI::remove_html_tags(const string &html, const string &tag) string URI::remove_html_tags(const string &html, const string &tag)
{ {
// NOTE: I did this with regex_replace before, but libstdc++ segfaulted. // NOTE: I did this with regex_replace before, but libstdc++ segfaulted.
string out; string out;
@ -303,7 +317,7 @@ namespace remwharead
return out; return out;
} }
const string URI::unescape_html(string html) string URI::unescape_html(string html)
{ {
// Used to convert int to utf-8 char. // Used to convert int to utf-8 char.
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> u8c; std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> u8c;
@ -603,7 +617,7 @@ namespace remwharead
return html; return html;
} }
const archive_answer URI::archive() archive_answer URI::archive()
{ {
if (_uri.substr(0, 4) != "http") if (_uri.substr(0, 4) != "http")
{ {
@ -628,7 +642,7 @@ namespace remwharead
return { false, "Unknown error.", "" }; return { false, "Unknown error.", "" };
} }
const string URI::remove_newlines(string text) string URI::remove_newlines(string text)
{ {
size_t posn = 0; size_t posn = 0;
while ((posn = text.find('\n', posn)) != std::string::npos) while ((posn = text.find('\n', posn)) != std::string::npos)
@ -645,4 +659,4 @@ namespace remwharead
return text; return text;
} }
} } // namespace remwharead