From 198be208d49990c3535ac765735768ad1ae79c1b Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Thu, 16 Jan 2020 21:40:15 +0200 Subject: Add Firefox bookmarks.json format to libbookmarks - can only read folders and bookmarks, their title and uri fields Not supported by Bookmark Model: - Separator items - Date added and Date modified fields --- lib/bookmarks/bookmarkformat.cpp | 9 ++++-- lib/bookmarks/bookmarkformat.h | 4 ++- lib/bookmarks/formats/ffjson.cpp | 45 ++++++++++++++++++++++++++ lib/bookmarks/formats/ffjson.h | 19 +++++++++++ lib/bookmarks/meson.build | 2 +- meson.build | 1 + test/firefox-bookmarks-json-parser/main.cpp | 28 ++++++++++++++++ test/firefox-bookmarks-json-parser/meson.build | 13 ++++++++ 8 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 lib/bookmarks/formats/ffjson.cpp create mode 100644 lib/bookmarks/formats/ffjson.h create mode 100644 test/firefox-bookmarks-json-parser/main.cpp create mode 100644 test/firefox-bookmarks-json-parser/meson.build diff --git a/lib/bookmarks/bookmarkformat.cpp b/lib/bookmarks/bookmarkformat.cpp index e6149cd..87b816c 100644 --- a/lib/bookmarks/bookmarkformat.cpp +++ b/lib/bookmarks/bookmarkformat.cpp @@ -8,19 +8,24 @@ #include "bookmarkformat.h" #include "formats/xbel.h" +#include "formats/ffjson.h" #include template<> void BookmarkFormat::read(BookmarkItem *root) const { - Q_CHECK_PTR(m_device); Xbel::read(m_device, root); } template<> void BookmarkFormat::write(BookmarkItem *root) { - Q_CHECK_PTR(m_device); Xbel::write(m_device, root); } +template<> +void BookmarkFormat::read(BookmarkItem *root) const +{ + FFJson::read(m_device, root); +} + diff --git a/lib/bookmarks/bookmarkformat.h b/lib/bookmarks/bookmarkformat.h index 673acbd..5cd1860 100644 --- a/lib/bookmarks/bookmarkformat.h +++ b/lib/bookmarks/bookmarkformat.h @@ -14,7 +14,8 @@ class QIODevice; enum BookmarkFormats { - XbelFormat + XbelFormat, + FirefoxJsonFormat }; template @@ -23,6 +24,7 @@ class BookmarkFormat public: explicit BookmarkFormat(QIODevice *device) { + Q_CHECK_PTR(m_device); m_device = device; } ~BookmarkFormat() diff --git a/lib/bookmarks/formats/ffjson.cpp b/lib/bookmarks/formats/ffjson.cpp new file mode 100644 index 0000000..f173904 --- /dev/null +++ b/lib/bookmarks/formats/ffjson.cpp @@ -0,0 +1,45 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "ffjson.h" +#include "bookmarkitem.h" +#include +#include +#include +#include + +void readChildElements(const QJsonObject &object, BookmarkItem *item) +{ + for(const auto c : object["children"].toArray()) { + const auto child = c.toObject(); + const auto type = child["type"].toString(); + + if(type == "text/x-moz-place-container") { + auto *childItem = new BookmarkItem({}, BookmarkItem::Folder, item); + childItem->setExpanded(true); + childItem->setData(BookmarkItem::Title, child["title"].toString()); + item->appendChild(childItem); + readChildElements(child, childItem); + + } else if(type == "text/x-moz-place") { + auto *childItem = new BookmarkItem({}, BookmarkItem::Bookmark, item); + childItem->setData(BookmarkItem::Title, child["title"].toString()); + childItem->setData(BookmarkItem::Href, child["uri"].toString()); + item->appendChild(childItem); + + } else { + qDebug() << "!!! unknown type " << qUtf8Printable(type); + } + } +} + +void FFJson::read(QIODevice *device, BookmarkItem *item) +{ + const auto doc = QJsonDocument::fromJson(device->readAll()); + readChildElements(doc.object(), item); +} diff --git a/lib/bookmarks/formats/ffjson.h b/lib/bookmarks/formats/ffjson.h new file mode 100644 index 0000000..cc6ac24 --- /dev/null +++ b/lib/bookmarks/formats/ffjson.h @@ -0,0 +1,19 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef FFJSON_H +#define FFJSON_H + +class QIODevice; +class BookmarkItem; +namespace FFJson +{ +void read(QIODevice *device, BookmarkItem *item); +} + +#endif // FFJSON_H diff --git a/lib/bookmarks/meson.build b/lib/bookmarks/meson.build index a7f603b..81c1ece 100644 --- a/lib/bookmarks/meson.build +++ b/lib/bookmarks/meson.build @@ -5,7 +5,7 @@ bookmarks_moc = mod_qt5.preprocess( bookmarks_lib = static_library('bookmarks', [ bookmarks_moc, - 'bookmarkformat.cpp', 'formats/xbel.cpp', + 'bookmarkformat.cpp', 'formats/xbel.cpp', 'formats/ffjson.cpp', 'bookmarkitem.cpp', 'bookmarkmodel.cpp' ], dependencies: dep_qt5 ) diff --git a/meson.build b/meson.build index 32984ea..5e50801 100644 --- a/meson.build +++ b/meson.build @@ -88,6 +88,7 @@ subdir('tools') #subdir('plugins/ProfileEditor') subdir('test/conf') +subdir('test/firefox-bookmarks-json-parser') ssconfig = poi_sourceset.apply(cdata) diff --git a/test/firefox-bookmarks-json-parser/main.cpp b/test/firefox-bookmarks-json-parser/main.cpp new file mode 100644 index 0000000..48093ec --- /dev/null +++ b/test/firefox-bookmarks-json-parser/main.cpp @@ -0,0 +1,28 @@ +#include +#include "bookmarkformat.h" +#include +#include + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + + QFile f(qgetenv("FILE")); + + auto *model = new BookmarkModel; + + if(f.open(QIODevice::ReadOnly)) { + BookmarkFormat(&f) >> model; + f.close(); + } else + return -1; + + auto *view = new QTreeView; + view->setModel(model); + + if(qgetenv("NOGUI") == "1") + return 0; + + view->show(); + return app.exec(); +} diff --git a/test/firefox-bookmarks-json-parser/meson.build b/test/firefox-bookmarks-json-parser/meson.build new file mode 100644 index 0000000..1432e68 --- /dev/null +++ b/test/firefox-bookmarks-json-parser/meson.build @@ -0,0 +1,13 @@ +e = executable('bookmarks-json-parser', + sources: [ 'main.cpp' ], + dependencies: [ dep_qt5, dep_bookmarks ] +) + +env = environment({ + 'NOGUI' : '1', + 'FILE' : 'bookmarks.json' +}) +test('Firefox bookmarks.json parser', e, + env: env, + workdir: meson.build_root() +) -- cgit v1.2.1