1 /**************************************************************************
2 * Otter Browser: Web browser controlled by the user, not vice-versa.
3 * Copyright (C) 2014 Piotr Wójcik <chocimier@tlen.pl>
4 * Copyright (C) 2014 - 2018 Michal Dutkiewicz aka Emdek <michal@emdek.pl>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 **************************************************************************/
20
21 #include "OperaBookmarksImporter.h"
22 #include "../../../core/BookmarksManager.h"
23 #include "../../../ui/BookmarksImporterWidget.h"
24
25 #include <QtCore/QDateTime>
26 #include <QtCore/QDir>
27 #include <QtCore/QFile>
28 #include <QtCore/QStandardPaths>
29 #include <QtCore/QTextStream>
30
31 namespace Otter
32 {
33
OperaBookmarksImporter(QObject * parent)34 OperaBookmarksImporter::OperaBookmarksImporter(QObject *parent) : BookmarksImporter(parent),
35 m_optionsWidget(nullptr)
36 {
37 }
38
createOptionsWidget(QWidget * parent)39 QWidget* OperaBookmarksImporter::createOptionsWidget(QWidget *parent)
40 {
41 if (!m_optionsWidget)
42 {
43 m_optionsWidget = new BookmarksImporterWidget(parent);
44 }
45
46 return m_optionsWidget;
47 }
48
getTitle() const49 QString OperaBookmarksImporter::getTitle() const
50 {
51 return tr("Opera Bookmarks");
52 }
53
getDescription() const54 QString OperaBookmarksImporter::getDescription() const
55 {
56 return tr("Imports bookmarks from Opera Browser version 12 or earlier");
57 }
58
getVersion() const59 QString OperaBookmarksImporter::getVersion() const
60 {
61 return QLatin1String("0.8");
62 }
63
getSuggestedPath(const QString & path) const64 QString OperaBookmarksImporter::getSuggestedPath(const QString &path) const
65 {
66 if (!path.isEmpty())
67 {
68 if (QFileInfo(path).isDir())
69 {
70 return QDir(path).filePath(QLatin1String("bookmarks.adr"));
71 }
72
73 return path;
74 }
75 #if !defined(Q_OS_MAC) && defined(Q_OS_UNIX)
76 const QString homePath(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).value(0));
77
78 if (!homePath.isEmpty())
79 {
80 return QDir(homePath).filePath(QLatin1String(".opera/bookmarks.adr"));
81 }
82 #endif
83
84 return path;
85 }
86
getBrowser() const87 QString OperaBookmarksImporter::getBrowser() const
88 {
89 return QLatin1String("opera");
90 }
91
getHomePage() const92 QUrl OperaBookmarksImporter::getHomePage() const
93 {
94 return QUrl(QLatin1String("https://otter-browser.org/"));
95 }
96
getFileFilters() const97 QStringList OperaBookmarksImporter::getFileFilters() const
98 {
99 return {tr("Opera bookmarks files (bookmarks.adr)")};
100 }
101
import(const QString & path)102 bool OperaBookmarksImporter::import(const QString &path)
103 {
104 QFile file(getSuggestedPath(path));
105
106 if (!file.open(QIODevice::ReadOnly))
107 {
108 emit importFinished(BookmarksImport, FailedImport, 0);
109
110 return false;
111 }
112
113 QTextStream stream(&file);
114 stream.setCodec("UTF-8");
115
116 QString line(stream.readLine());
117
118 if (line != QLatin1String("Opera Hotlist version 2.0"))
119 {
120 emit importFinished(BookmarksImport, FailedImport, 0);
121
122 return false;
123 }
124
125 emit importStarted(BookmarksImport, -1);
126
127 if (m_optionsWidget)
128 {
129 if (m_optionsWidget->hasToRemoveExisting())
130 {
131 removeAllBookmarks();
132
133 if (m_optionsWidget->isImportingIntoSubfolder())
134 {
135 setImportFolder(BookmarksManager::addBookmark(BookmarksModel::FolderBookmark, {{BookmarksModel::TitleRole, m_optionsWidget->getSubfolderName()}}, BookmarksManager::getModel()->getRootItem()));
136 }
137 else
138 {
139 setImportFolder(BookmarksManager::getModel()->getRootItem());
140 }
141 }
142 else
143 {
144 setAllowDuplicates(m_optionsWidget->areDuplicatesAllowed());
145 setImportFolder(m_optionsWidget->getTargetFolder());
146 }
147 }
148
149 const int estimatedAmount((file.size() > 0) ? static_cast<int>(file.size() / 250) : 0);
150 int totalAmount(0);
151
152 BookmarksManager::getModel()->beginImport(getImportFolder(), estimatedAmount, qMin(estimatedAmount, 100));
153
154 BookmarksModel::Bookmark *bookmark(nullptr);
155 OperaBookmarkEntry type(NoEntry);
156 bool isHeader(true);
157
158 while (!stream.atEnd())
159 {
160 line = stream.readLine();
161
162 if (isHeader && (line.isEmpty() || line.at(0) != QLatin1Char('#')))
163 {
164 continue;
165 }
166
167 isHeader = false;
168
169 if (line.isEmpty())
170 {
171 if (bookmark)
172 {
173 if (type == FolderStartEntry)
174 {
175 setCurrentFolder(bookmark);
176 }
177
178 bookmark = nullptr;
179 }
180 else if (type == FolderEndEntry)
181 {
182 goToParent();
183 }
184
185 type = NoEntry;
186 }
187 else if (line.startsWith(QLatin1String("#URL")))
188 {
189 bookmark = BookmarksManager::addBookmark(BookmarksModel::UrlBookmark, {}, getCurrentFolder());
190 type = UrlEntry;
191
192 ++totalAmount;
193 }
194 else if (line.startsWith(QLatin1String("#FOLDER")))
195 {
196 bookmark = BookmarksManager::addBookmark(BookmarksModel::FolderBookmark, {}, getCurrentFolder());
197 type = FolderStartEntry;
198
199 ++totalAmount;
200 }
201 else if (line.startsWith(QLatin1String("#SEPERATOR")))
202 {
203 bookmark = BookmarksManager::addBookmark(BookmarksModel::SeparatorBookmark, {}, getCurrentFolder());
204 type = SeparatorEntry;
205
206 ++totalAmount;
207 }
208 else if (line == QLatin1String("-"))
209 {
210 type = FolderEndEntry;
211 }
212 else if (bookmark)
213 {
214 if (line.startsWith(QLatin1String("\tURL=")))
215 {
216 const QUrl url(line.section(QLatin1Char('='), 1, -1));
217
218 if (!areDuplicatesAllowed() && BookmarksManager::hasBookmark(url))
219 {
220 bookmark->remove();
221 bookmark = nullptr;
222 }
223 else
224 {
225 bookmark->setData(url, BookmarksModel::UrlRole);
226 }
227 }
228 else if (line.startsWith(QLatin1String("\tNAME=")))
229 {
230 bookmark->setData(line.section(QLatin1Char('='), 1, -1), BookmarksModel::TitleRole);
231 }
232 else if (line.startsWith(QLatin1String("\tDESCRIPTION=")))
233 {
234 bookmark->setData(line.section(QLatin1Char('='), 1, -1).replace(QLatin1String("\x02\x02"), QLatin1String("\n")), BookmarksModel::DescriptionRole);
235 }
236 else if (line.startsWith(QLatin1String("\tSHORT NAME=")))
237 {
238 const QString keyword(line.section(QLatin1Char('='), 1, -1));
239
240 if (!BookmarksManager::hasKeyword(keyword))
241 {
242 bookmark->setData(keyword, BookmarksModel::KeywordRole);
243 }
244 }
245 else if (line.startsWith(QLatin1String("\tCREATED=")))
246 {
247 bookmark->setData(QDateTime::fromTime_t(line.section(QLatin1Char('='), 1, -1).toUInt()), BookmarksModel::TimeAddedRole);
248 }
249 else if (line.startsWith(QLatin1String("\tVISITED=")))
250 {
251 bookmark->setData(QDateTime::fromTime_t(line.section(QLatin1Char('='), 1, -1).toUInt()), BookmarksModel::TimeVisitedRole);
252 }
253 }
254 }
255
256 BookmarksManager::getModel()->endImport();
257
258 emit importFinished(BookmarksImport, SuccessfullImport, totalAmount);
259
260 file.close();
261
262 return true;
263 }
264
265 }
266