Merge branch 'develop' into main
continuous-integration/drone/push Build is failing Details

Add JSON export.
This commit is contained in:
tastytea 2019-09-03 17:51:03 +02:00
commit 059ea2dc01
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
9 changed files with 142 additions and 10 deletions

View File

@ -2,7 +2,7 @@ include(CMakeFindDependencyMacro)
include(GNUInstallDirs) include(GNUInstallDirs)
find_depencency(Poco find_depencency(Poco
COMPONENTS Foundation Net NetSSL Data DataSQLite COMPONENTS Foundation Net NetSSL Data DataSQLite JSON
CONFIG REQUIRED) CONFIG REQUIRED)
find_dependency(PkgConfig REQUIRED) find_dependency(PkgConfig REQUIRED)
pkg_check_modules(libxdg-basedir REQUIRED IMPORTED_TARGET libxdg-basedir) pkg_check_modules(libxdg-basedir REQUIRED IMPORTED_TARGET libxdg-basedir)

46
include/export/json.hpp Normal file
View File

@ -0,0 +1,46 @@
/* This file is part of remwharead.
* Copyright © 2019 tastytea <tastytea@tastytea.de>
*
* This program 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, version 3.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REMWHAREAD_JSON_HPP
#define REMWHAREAD_JSON_HPP
#include <string>
#include "export.hpp"
namespace remwharead
{
namespace Export
{
using std::string;
/*!
* @brief Export as JSON array.
*
* @since 0.8.0
*
* @headerfile json.hpp remwharead/export/json.hpp
*/
class JSON : protected ExportBase
{
public:
using ExportBase::ExportBase;
virtual void print() const override;
};
}
}
#endif // REMWHAREAD_JSON_HPP

View File

@ -34,7 +34,8 @@ namespace remwharead
csv, csv,
asciidoc, asciidoc,
bookmarks, bookmarks,
simple simple,
json
}; };
} }

View File

@ -2,7 +2,7 @@
:doctype: manpage :doctype: manpage
:Author: tastytea :Author: tastytea
:Email: tastytea@tastytea.de :Email: tastytea@tastytea.de
:Date: 2019-08-09 :Date: 2019-09-03
:Revision: 0.0.0 :Revision: 0.0.0
:man source: remwharead :man source: remwharead
:man manual: General Commands Manual :man manual: General Commands Manual
@ -24,7 +24,7 @@ remwharead - Saves URIs of things you want to remember in a database
the full text of the page and optional tags. the full text of the page and optional tags.
The database can be filtered by time, tags and full text and exported to CSV, The database can be filtered by time, tags and full text and exported to CSV,
AsciiDoc or a bookmarks file. AsciiDoc, a bookmarks file or JSON.
Archiving is done using the Wayback machine from the Archiving is done using the Wayback machine from the
https://archive.org/[Internet Archive]. https://archive.org/[Internet Archive].
@ -35,8 +35,8 @@ https://archive.org/[Internet Archive].
Add tags to _URI_, delimited by commas. Add tags to _URI_, delimited by commas.
*-e* _format_, *--export* _format_:: *-e* _format_, *--export* _format_::
Export to _format_. Possible values are _csv_, _asciidoc_, _bookmarks_ or Export to _format_. Possible values are _csv_, _asciidoc_, _bookmarks_,
_simple_. See _FORMATS_. _simple_ or _json_. See _FORMATS_.
*-f* _file_, *--file* _file_:: *-f* _file_, *--file* _file_::
Save output to _file_. Default is stdout. Save output to _file_. Default is stdout.
@ -133,6 +133,12 @@ understood by most browsers.
Simple, human readable, list. Outputs date, title and URI. Simple, human readable, list. Outputs date, title and URI.
=== json
Export as JSON array. See https://tools.ietf.org/html/rfc8259[RFC 8259]. Each
object contains the members _uri_, _archive_uri_, _datetime_, _tags_ (array),
_title_, _description_ and _fulltext_.
== SEARCH EXPRESSIONS == SEARCH EXPRESSIONS
A search expression is either a single term, or several terms separated by _AND_ A search expression is either a single term, or several terms separated by _AND_

View File

@ -10,4 +10,4 @@ Version: @PROJECT_VERSION@
Cflags: -I${includedir} Cflags: -I${includedir}
Libs: -L${libdir} -l${name} -lPocoData -lstdc++fs Libs: -L${libdir} -l${name} -lPocoData -lstdc++fs
Requires.private: libxdg-basedir, icu-uc, icu-i18n Requires.private: libxdg-basedir, icu-uc, icu-i18n
Libs.private: -lPocoFoundation -lPocoNet -lPocoNetSSL -lPocoDataSQLite Libs.private: -lPocoFoundation -lPocoNet -lPocoNetSSL -lPocoDataSQLite -lPocoJSON

View File

@ -28,6 +28,7 @@
#include "export/adoc.hpp" #include "export/adoc.hpp"
#include "export/bookmarks.hpp" #include "export/bookmarks.hpp"
#include "export/simple.hpp" #include "export/simple.hpp"
#include "export/json.hpp"
#include "search.hpp" #include "search.hpp"
using namespace remwharead; using namespace remwharead;
@ -177,6 +178,19 @@ int App::main(const std::vector<std::string> &args)
} }
break; break;
} }
case export_format::json:
{
if (file.is_open())
{
Export::JSON(entries, file).print();
file.close();
}
else
{
Export::JSON(entries).print();
}
break;
}
default: default:
{ {
break; break;

View File

@ -139,6 +139,10 @@ void App::handle_options(const std::string &name, const std::string &value)
{ {
_format = export_format::simple; _format = export_format::simple;
} }
else if (value == "json")
{
_format = export_format::json;
}
else else
{ {
cerr << "Error: Unknown format.\n"; cerr << "Error: Unknown format.\n";

View File

@ -3,7 +3,7 @@ include(GNUInstallDirs)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(libxdg-basedir REQUIRED IMPORTED_TARGET libxdg-basedir) pkg_check_modules(libxdg-basedir REQUIRED IMPORTED_TARGET libxdg-basedir)
# Some distributions do not contain Poco*Config.cmake recipes. # Some distributions do not contain Poco*Config.cmake recipes.
find_package(Poco COMPONENTS Foundation Net NetSSL Data DataSQLite CONFIG) find_package(Poco COMPONENTS Foundation Net NetSSL Data DataSQLite JSON CONFIG)
file(GLOB_RECURSE sources_lib *.cpp) file(GLOB_RECURSE sources_lib *.cpp)
file(GLOB_RECURSE headers_lib ../../include/*.hpp) file(GLOB_RECURSE headers_lib ../../include/*.hpp)
@ -28,7 +28,7 @@ target_link_libraries(${PROJECT_NAME}
# If no Poco*Config.cmake recipes are found, look for headers in standard dirs. # If no Poco*Config.cmake recipes are found, look for headers in standard dirs.
if(PocoNetSSL_FOUND) if(PocoNetSSL_FOUND)
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
PRIVATE Poco::Foundation Poco::Net Poco::NetSSL Poco::DataSQLite PRIVATE Poco::Foundation Poco::Net Poco::NetSSL Poco::DataSQLite Poco::JSON
PUBLIC Poco::Data) PUBLIC Poco::Data)
else() else()
find_file(Poco_h NAMES "Poco/Poco.h" find_file(Poco_h NAMES "Poco/Poco.h"
@ -42,7 +42,7 @@ else()
"but the files seem to be in the standard directories. " "but the files seem to be in the standard directories. "
"Let's hope this works.") "Let's hope this works.")
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
PRIVATE PocoFoundation PocoNet PocoNetSSL PocoDataSQLite PRIVATE PocoFoundation PocoNet PocoNetSSL PocoDataSQLite PocoJSON
PUBLIC PocoData) PUBLIC PocoData)
endif() endif()
endif() endif()

61
src/lib/export/json.cpp Normal file
View File

@ -0,0 +1,61 @@
/* This file is part of remwharead.
* Copyright © 2019 tastytea <tastytea@tastytea.de>
*
* This program 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, version 3.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Poco/JSON/Object.h>
#include <Poco/JSON/Stringifier.h>
#include "time.hpp"
#include "export/json.hpp"
namespace remwharead
{
using std::cerr;
using std::endl;
void Export::JSON::print() const
{
try
{
Poco::JSON::Array root = Poco::JSON::Array();
for (const Database::entry &entry : _entries)
{
Poco::JSON::Object json_entry = Poco::JSON::Object();
json_entry.set("uri", entry.uri);
json_entry.set("archive_uri", entry.archive_uri);
json_entry.set("datetime", timepoint_to_string(entry.datetime));
Poco::JSON::Array tags = Poco::JSON::Array();
for (const string &tag : entry.tags)
{
tags.add(tag);
}
json_entry.set("tags", tags);
json_entry.set("title", entry.title);
json_entry.set("description", entry.description);
json_entry.set("fulltext", entry.fulltext);
root.add(json_entry);
}
root.stringify(_out);
_out << endl;
}
catch (std::exception &e)
{
cerr << "Error in " << __func__ << ": " << e.what() << endl;
}
}
}