File indexing completed on 2024-05-26 05:00:26
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2010-2014 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 "operaimporter.h" 0019 #include "bookmarkitem.h" 0020 0021 #include <QUrl> 0022 #include <QDir> 0023 #include <QFileDialog> 0024 0025 OperaImporter::OperaImporter(QObject* parent) 0026 : BookmarksImporter(parent) 0027 { 0028 m_stream.setEncoding(QStringConverter::Utf8); 0029 } 0030 0031 QString OperaImporter::description() const 0032 { 0033 return BookmarksImporter::tr("Opera stores its bookmarks in <b>bookmarks.adr</b> text file. " 0034 "This file is usually located in"); 0035 } 0036 0037 QString OperaImporter::standardPath() const 0038 { 0039 #ifdef Q_OS_WIN 0040 return QString("%APPDATA%/Opera/"); 0041 #else 0042 return QDir::homePath() + QLatin1String("/.opera/"); 0043 #endif 0044 } 0045 0046 QString OperaImporter::getPath(QWidget* parent) 0047 { 0048 m_path = QFileDialog::getOpenFileName(parent, BookmarksImporter::tr("Choose file..."), standardPath(), QStringLiteral("Bookmarks (*.adr)")); 0049 return m_path; 0050 } 0051 0052 bool OperaImporter::prepareImport() 0053 { 0054 m_file.setFileName(m_path); 0055 0056 if (!m_file.open(QFile::ReadOnly)) { 0057 setError(BookmarksImporter::tr("Unable to open file.")); 0058 return false; 0059 } 0060 0061 m_stream.setDevice(&m_file); 0062 0063 if (m_stream.readLine() != QLatin1String("Opera Hotlist version 2.0")) { 0064 setError(BookmarksImporter::tr("File is not valid Opera bookmarks file!")); 0065 return false; 0066 } 0067 0068 if (!m_stream.readLine().startsWith(QLatin1String("Options: encoding = utf8"))) { 0069 setError(BookmarksImporter::tr("Only UTF-8 encoded Opera bookmarks file is supported!")); 0070 return false; 0071 } 0072 0073 return true; 0074 } 0075 0076 BookmarkItem* OperaImporter::importBookmarks() 0077 { 0078 auto* root = new BookmarkItem(BookmarkItem::Folder); 0079 root->setTitle(QSL("Opera Import")); 0080 0081 QList<BookmarkItem*> folders; 0082 folders.append(root); 0083 0084 BookmarkItem* item = nullptr; 0085 0086 #define PARENT folders.isEmpty() ? root : folders.last() 0087 0088 while (!m_stream.atEnd()) { 0089 switch (parseLine(m_stream.readLine())) { 0090 case StartFolder: 0091 item = new BookmarkItem(BookmarkItem::Folder, PARENT); 0092 while (!m_stream.atEnd()) { 0093 Token tok = parseLine(m_stream.readLine()); 0094 if (tok == EmptyLine) 0095 break; 0096 else if (tok == KeyValuePair && m_key == QLatin1String("NAME")) 0097 item->setTitle(m_value); 0098 } 0099 folders.append(item); 0100 break; 0101 0102 case EndFolder: 0103 if (folders.count() > 0) { 0104 folders.removeLast(); 0105 } 0106 break; 0107 0108 case StartUrl: 0109 item = new BookmarkItem(BookmarkItem::Url, PARENT); 0110 while (!m_stream.atEnd()) { 0111 Token tok = parseLine(m_stream.readLine()); 0112 if (tok == EmptyLine) { 0113 break; 0114 } 0115 else if (tok == KeyValuePair) { 0116 if (m_key == QL1S("NAME")) 0117 item->setTitle(m_value); 0118 else if (m_key == QL1S("URL")) 0119 item->setUrl(QUrl(m_value)); 0120 else if (m_key == QL1S("DESCRIPTION")) 0121 item->setDescription(m_value); 0122 else if (m_key == QL1S("SHORT NAME")) 0123 item->setKeyword(m_value); 0124 } 0125 } 0126 break; 0127 0128 case StartSeparator: 0129 item = new BookmarkItem(BookmarkItem::Separator, PARENT); 0130 while (!m_stream.atEnd()) { 0131 if (parseLine(m_stream.readLine()) == EmptyLine) { 0132 break; 0133 } 0134 } 0135 break; 0136 0137 case StartDeleted: 0138 while (!m_stream.atEnd()) { 0139 if (parseLine(m_stream.readLine()) == EmptyLine) { 0140 break; 0141 } 0142 } 0143 break; 0144 0145 default: // EmptyLine 0146 break; 0147 } 0148 } 0149 0150 #undef PARENT 0151 0152 return root; 0153 } 0154 0155 OperaImporter::Token OperaImporter::parseLine(const QString &line) 0156 { 0157 const QString str = line.trimmed(); 0158 0159 if (str.isEmpty()) { 0160 return EmptyLine; 0161 } 0162 0163 if (str == QLatin1String("#FOLDER")) { 0164 return StartFolder; 0165 } 0166 0167 if (str == QLatin1String("-")) { 0168 return EndFolder; 0169 } 0170 0171 if (str == QLatin1String("#URL")) { 0172 return StartUrl; 0173 } 0174 0175 if (str == QLatin1String("#SEPERATOR")) { 0176 return StartSeparator; 0177 } 0178 0179 if (str == QLatin1String("#DELETED")) { 0180 return StartDeleted; 0181 } 0182 0183 int index = str.indexOf(QLatin1Char('=')); 0184 0185 // Let's assume "key=" is valid line with empty value (but not "=value") 0186 if (index > 0) { 0187 m_key = str.mid(0, index); 0188 m_value = str.mid(index + 1); 0189 return KeyValuePair; 0190 } 0191 0192 return Invalid; 0193 }