Export as CSV to stdout.
This commit is contained in:
parent
df69efbbb7
commit
2c27a352a2
38
src/main.cpp
38
src/main.cpp
|
@ -47,8 +47,42 @@ int main(const int argc, const char *argv[])
|
|||
{
|
||||
URL url(opts.url);
|
||||
html_extract page = url.get();
|
||||
db.store(opts.url, url.archive(), system_clock::now(), opts.tags,
|
||||
page.title, page.description, page.fulltext);
|
||||
db.store({opts.url, url.archive(), system_clock::now(), opts.tags,
|
||||
page.title, page.description, page.fulltext});
|
||||
}
|
||||
|
||||
switch (opts.format)
|
||||
{
|
||||
case export_format::csv:
|
||||
{
|
||||
for (const Database::entry &entry : db.retrieve())
|
||||
{
|
||||
string strtags;
|
||||
for (const string &tag : entry.tags)
|
||||
{
|
||||
strtags += tag;
|
||||
if (tag != *(entry.tags.rbegin()))
|
||||
{
|
||||
strtags += ",";
|
||||
}
|
||||
}
|
||||
cout << entry.uri << ';' << entry.archive_uri << ';'
|
||||
<< timepoint_to_string(entry.datetime) << ';'
|
||||
<< strtags << ';' << entry.title << ';'
|
||||
<< entry.description << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case export_format::asciidoc:
|
||||
{
|
||||
cerr << "AsciiDoc is not yet supported.\n";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -60,19 +60,16 @@ Database::operator bool() const
|
|||
return _connected;
|
||||
}
|
||||
|
||||
void Database::store(const string &uri, const string &archive_uri,
|
||||
const time_point &datetime, const vector<string> &tags,
|
||||
const string &title, const string &description,
|
||||
const string &fulltext)
|
||||
void Database::store(const Database::entry &data) const
|
||||
{
|
||||
try
|
||||
{
|
||||
const string strdatetime = timepoint_to_string(datetime);
|
||||
const string strdatetime = timepoint_to_string(data.datetime, true);
|
||||
string strtags;
|
||||
for (const string &tag : tags)
|
||||
for (const string &tag : data.tags)
|
||||
{
|
||||
strtags += tag;
|
||||
if (tag != *(tags.rbegin()))
|
||||
if (tag != *(data.tags.rbegin()))
|
||||
{
|
||||
strtags += ",";
|
||||
}
|
||||
|
@ -80,8 +77,8 @@ void Database::store(const string &uri, const string &archive_uri,
|
|||
|
||||
sqlite::execute ins(*_con, "INSERT INTO remwharead "
|
||||
"VALUES(?, ?, ?, ?, ?, ?, ?);");
|
||||
ins % uri % archive_uri % strdatetime % strtags
|
||||
% title % description % fulltext;
|
||||
ins % data.uri % data.archive_uri % strdatetime % strtags
|
||||
% data.title % data.description % data.fulltext;
|
||||
ins();
|
||||
}
|
||||
catch (std::exception &e)
|
||||
|
@ -89,3 +86,54 @@ void Database::store(const string &uri, const string &archive_uri,
|
|||
cerr << "Error in " << __func__ << ": " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
const vector<Database::entry> Database::retrieve(const time_point &start,
|
||||
const time_point &end) const
|
||||
{
|
||||
try
|
||||
{
|
||||
const string query = "SELECT * FROM remwharead WHERE datetime "
|
||||
"BETWEEN '" + timepoint_to_string(start, true)
|
||||
+ "' AND '" + timepoint_to_string(end, true)
|
||||
+ "' ORDER BY datetime;";
|
||||
|
||||
sqlite::query q(*_con, query);
|
||||
sqlite::result_type res = q.get_result();
|
||||
vector<entry> entries;
|
||||
|
||||
while(res->next_row())
|
||||
{
|
||||
vector<string> tags;
|
||||
const string strtags = res->get_string(3);
|
||||
size_t pos = 0;
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
const size_t newpos = strtags.find(',', pos);
|
||||
tags.push_back(strtags.substr(pos, newpos - pos));
|
||||
pos = newpos;
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
entries.push_back
|
||||
({
|
||||
res->get_string(0),
|
||||
res->get_string(1),
|
||||
string_to_timepoint(res->get_string(2), true),
|
||||
tags,
|
||||
res->get_string(4),
|
||||
res->get_string(5),
|
||||
res->get_string(6)
|
||||
});
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
cerr << "Error in " << __func__ << ": " << e.what() << endl;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <vector>
|
||||
#include <chrono>
|
||||
#include <sqlite/connection.hpp>
|
||||
#include "types.hpp"
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
using std::string;
|
||||
|
@ -33,14 +34,27 @@ using time_point = system_clock::time_point;
|
|||
class Database
|
||||
{
|
||||
public:
|
||||
typedef struct entry
|
||||
{
|
||||
string uri;
|
||||
string archive_uri;
|
||||
time_point datetime;
|
||||
vector<string> tags;
|
||||
string title;
|
||||
string description;
|
||||
string fulltext;
|
||||
} entry;
|
||||
|
||||
Database();
|
||||
operator bool() const;
|
||||
|
||||
//! Store in database.
|
||||
void store(const string &uri, const string &archive_uri,
|
||||
const time_point &datetime, const vector<string> &tags,
|
||||
const string &title, const string &description,
|
||||
const string &fulltext);
|
||||
void store(const entry &data) const;
|
||||
|
||||
//! retrieve from database.
|
||||
const vector<entry> retrieve(const time_point &start = time_point(),
|
||||
const time_point &end = system_clock::now())
|
||||
const;
|
||||
|
||||
private:
|
||||
fs::path _dbpath;
|
||||
|
|
Loading…
Reference in New Issue