File indexing completed on 2024-12-22 04:40:57

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2010-2016 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "chromeimporter.h"
0019 #include "bookmarkitem.h"
0020 
0021 #include <QDir>
0022 #include <QFileDialog>
0023 #include <QJsonDocument>
0024 #include <QMetaType>
0025 
0026 ChromeImporter::ChromeImporter(QObject* parent)
0027     : BookmarksImporter(parent)
0028 {
0029 }
0030 
0031 QString ChromeImporter::description() const
0032 {
0033     return BookmarksImporter::tr("Google Chrome stores its bookmarks in <b>Bookmarks</b> text file. "
0034                                  "This file is usually located in");
0035 }
0036 
0037 QString ChromeImporter::standardPath() const
0038 {
0039 #if defined(Q_OS_WIN)
0040     return QString("%APPDATA%/Chrome/");
0041 #elif defined(Q_OS_OSX)
0042     return QDir::homePath() + QLatin1String("/Library/Application Support/Google/Chrome/");
0043 #else
0044     return QDir::homePath() + QLatin1String("/.config/chrome/");
0045 #endif
0046 }
0047 
0048 QString ChromeImporter::getPath(QWidget* parent)
0049 {
0050     m_path = QFileDialog::getOpenFileName(parent, BookmarksImporter::tr("Choose file..."), standardPath(), QSL("Bookmarks (Bookmarks)"));
0051     return m_path;
0052 }
0053 
0054 bool ChromeImporter::prepareImport()
0055 {
0056     m_file.setFileName(m_path);
0057 
0058     if (!m_file.open(QFile::ReadOnly)) {
0059         setError(BookmarksImporter::tr("Unable to open file."));
0060         return false;
0061     }
0062 
0063     return true;
0064 }
0065 
0066 BookmarkItem* ChromeImporter::importBookmarks()
0067 {
0068     const QByteArray data = m_file.readAll();
0069     m_file.close();
0070 
0071     QJsonParseError err;
0072     QJsonDocument json = QJsonDocument::fromJson(data, &err);
0073     const QVariant res = json.toVariant();
0074 
0075     if (err.error != QJsonParseError::NoError || res.typeId() != QMetaType::QVariantMap) {
0076         setError(BookmarksImporter::tr("Cannot parse JSON file!"));
0077         return nullptr;
0078     }
0079 
0080     QVariantMap rootMap = res.toMap().value(QSL("roots")).toMap();
0081 
0082     auto* root = new BookmarkItem(BookmarkItem::Folder);
0083     root->setTitle(QSL("Chrome Import"));
0084 
0085     auto* toolbar = new BookmarkItem(BookmarkItem::Folder, root);
0086     toolbar->setTitle(rootMap.value(QSL("bookmark_bar")).toMap().value(QSL("name")).toString());
0087     readBookmarks(rootMap.value(QSL("bookmark_bar")).toMap().value(QSL("children")).toList(), toolbar);
0088 
0089     auto* other = new BookmarkItem(BookmarkItem::Folder, root);
0090     other->setTitle(rootMap.value(QSL("other")).toMap().value(QSL("name")).toString());
0091     readBookmarks(rootMap.value(QSL("other")).toMap().value(QSL("children")).toList(), other);
0092 
0093     auto* synced = new BookmarkItem(BookmarkItem::Folder, root);
0094     synced->setTitle(rootMap.value(QSL("synced")).toMap().value(QSL("name")).toString());
0095     readBookmarks(rootMap.value(QSL("synced")).toMap().value(QSL("synced")).toList(), other);
0096 
0097     return root;
0098 }
0099 
0100 void ChromeImporter::readBookmarks(const QVariantList &list, BookmarkItem* parent)
0101 {
0102     Q_ASSERT(parent);
0103 
0104     for (const QVariant &entry : list) {
0105         const QVariantMap map = entry.toMap();
0106         const QString typeString = map.value(QSL("type")).toString();
0107         BookmarkItem::Type type;
0108 
0109         if (typeString == QLatin1String("url")) {
0110             type = BookmarkItem::Url;
0111         }
0112         else if (typeString == QLatin1String("folder")) {
0113             type = BookmarkItem::Folder;
0114         }
0115         else {
0116             continue;
0117         }
0118 
0119         auto* item = new BookmarkItem(type, parent);
0120         item->setTitle(map.value(QSL("name")).toString());
0121 
0122         if (item->isUrl()) {
0123             item->setUrl(QUrl::fromEncoded(map.value(QSL("url")).toByteArray()));
0124         }
0125 
0126         if (map.contains(QSL("children"))) {
0127             readBookmarks(map.value(QSL("children")).toList(), item);
0128         }
0129     }
0130 }