1 /**************************************************************************
2 * Otter Browser: Web browser controlled by the user, not vice-versa.
3 * Copyright (C) 2015 - 2018 Michal Dutkiewicz aka Emdek <michal@emdek.pl>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 **************************************************************************/
19
20 #include "HandlersManager.h"
21 #include "AdblockContentFiltersProfile.h"
22 #include "ContentFiltersManager.h"
23 #include "IniSettings.h"
24 #include "SessionsManager.h"
25 #include "SettingsManager.h"
26 #include "Utils.h"
27
28 #include <QtCore/QFile>
29 #include <QtCore/QFileInfo>
30 #include <QtCore/QMimeDatabase>
31 #include <QtCore/QUrlQuery>
32 #include <QtGui/QDesktopServices>
33 #include <QtWidgets/QMessageBox>
34
35 namespace Otter
36 {
37
38 HandlersManager* HandlersManager::m_instance(nullptr);
39
HandlersManager(QObject * parent)40 HandlersManager::HandlersManager(QObject *parent) : QObject(parent)
41 {
42 }
43
createInstance()44 void HandlersManager::createInstance()
45 {
46 if (!m_instance)
47 {
48 m_instance = new HandlersManager(QCoreApplication::instance());
49 }
50 }
51
setHandler(const QMimeType & mimeType,const HandlerDefinition & definition)52 void HandlersManager::setHandler(const QMimeType &mimeType, const HandlerDefinition &definition)
53 {
54 if (SessionsManager::isReadOnly())
55 {
56 return;
57 }
58
59 const QString path(SessionsManager::getWritableDataPath(QLatin1String("handlers.ini")));
60 IniSettings settings(QFile::exists(path) ? path : SessionsManager::getReadableDataPath(QLatin1String("handlers.ini")));
61 QString transferMode;
62
63 switch (definition.transferMode)
64 {
65 case HandlerDefinition::IgnoreTransfer:
66 transferMode = QLatin1String("ignore");
67
68 break;
69 case HandlerDefinition::OpenTransfer:
70 transferMode = QLatin1String("open");
71
72 break;
73 case HandlerDefinition::SaveTransfer:
74 transferMode = QLatin1String("save");
75
76 break;
77 case HandlerDefinition::SaveAsTransfer:
78 transferMode = QLatin1String("saveAs");
79
80 break;
81 default:
82 transferMode = QLatin1String("ask");
83
84 break;
85 }
86
87 settings.beginGroup(mimeType.isValid() ? mimeType.name() : QLatin1String("*"));
88 settings.setValue(QLatin1String("openCommand"), definition.openCommand);
89 settings.setValue(QLatin1String("downloadsPath"), definition.downloadsPath);
90 settings.setValue(QLatin1String("transferMode"), transferMode);
91 settings.save(path);
92 }
93
getInstance()94 HandlersManager* HandlersManager::getInstance()
95 {
96 return m_instance;
97 }
98
getHandler(const QMimeType & mimeType)99 HandlersManager::HandlerDefinition HandlersManager::getHandler(const QMimeType &mimeType)
100 {
101 IniSettings settings(SessionsManager::getReadableDataPath(QLatin1String("handlers.ini")));
102 const QString name(mimeType.isValid() ? mimeType.name() : QLatin1String("*"));
103 HandlerDefinition definition;
104 definition.mimeType = mimeType;
105 definition.isExplicit = settings.getGroups().contains(name);
106
107 if (definition.isExplicit)
108 {
109 settings.beginGroup(name);
110 }
111 else
112 {
113 settings.beginGroup(QLatin1String("*"));
114 }
115
116 const QString downloadsPath(settings.getValue(QLatin1String("downloadsPath"), {}).toString());
117 const QString transferMode(settings.getValue(QLatin1String("transferMode"), {}).toString());
118
119 definition.openCommand = settings.getValue(QLatin1String("openCommand"), {}).toString();
120 definition.downloadsPath = (downloadsPath.isEmpty() ? SettingsManager::getOption(SettingsManager::Paths_DownloadsOption).toString() : downloadsPath);
121
122 if (transferMode == QLatin1String("ignore"))
123 {
124 definition.transferMode = HandlerDefinition::IgnoreTransfer;
125 }
126 else if (transferMode == QLatin1String("open"))
127 {
128 definition.transferMode = HandlerDefinition::OpenTransfer;
129 }
130 else if (transferMode == QLatin1String("save"))
131 {
132 definition.transferMode = HandlerDefinition::SaveTransfer;
133 }
134 else if (transferMode == QLatin1String("saveAs"))
135 {
136 definition.transferMode = HandlerDefinition::SaveAsTransfer;
137 }
138 else
139 {
140 definition.transferMode = HandlerDefinition::AskTransfer;
141 }
142
143 return definition;
144 }
145
getHandlers()146 QVector<HandlersManager::HandlerDefinition> HandlersManager::getHandlers()
147 {
148 const QMimeDatabase mimeDatabase;
149 const QStringList mimeTypes(IniSettings(SessionsManager::getReadableDataPath(QLatin1String("handlers.ini"))).getGroups());
150 QVector<HandlersManager::HandlerDefinition> handlers;
151 handlers.reserve(mimeTypes.count());
152
153 for (int i = 0; i < mimeTypes.count(); ++i)
154 {
155 handlers.append(getHandler(mimeDatabase.mimeTypeForName(mimeTypes.at(i))));
156 }
157
158 return handlers;
159 }
160
handleUrl(const QUrl & url)161 bool HandlersManager::handleUrl(const QUrl &url)
162 {
163 if (url.scheme() == QLatin1String("abp"))
164 {
165 const QUrlQuery query(url.query());
166 const QUrl location(QUrl::fromPercentEncoding(query.queryItemValue(QLatin1String("location")).toUtf8()));
167
168 if (location.isValid())
169 {
170 if (ContentFiltersManager::getProfile(location))
171 {
172 QMessageBox::critical(nullptr, tr("Error"), tr("Profile with this address already exists."), QMessageBox::Close);
173 }
174 else if (QMessageBox::question(nullptr, tr("Question"), tr("Do you want to add this content blocking profile?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
175 {
176 ContentFiltersProfile *profile(new AdblockContentFiltersProfile(Utils::createIdentifier(QFileInfo(location.path()).baseName(), ContentFiltersManager::getProfileNames()), QByteArray::fromPercentEncoding(query.queryItemValue(QLatin1String("title")).toUtf8()), location, {}, {}, 0, ContentFiltersProfile::OtherCategory, ContentFiltersProfile::NoFlags));
177
178 ContentFiltersManager::addProfile(profile);
179
180 profile->update();
181 ///TODO Some sort of passive confirmation that profile was added
182 }
183 }
184
185 return true;
186 }
187
188 if (url.scheme() == QLatin1String("mailto"))
189 {
190 QDesktopServices::openUrl(url);
191
192 return true;
193 }
194
195 return false;
196 }
197
canHandleUrl(const QUrl & url)198 bool HandlersManager::canHandleUrl(const QUrl &url)
199 {
200 return (url.scheme() == QLatin1String("abp") || url.scheme() == QLatin1String("mailto"));
201 }
202
203 }
204