• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

messageviewer

  • sources
  • kde-4.12
  • kdepim
  • messageviewer
  • adblock
adblockmanager.cpp
Go to the documentation of this file.
1 /* ============================================================
2 * Copyright (c) 2013 Montel Laurent <montel@kde.org>
3 * based on code from rekonq
4 * This file is a part of the rekonq project
5 *
6 * Copyright (C) 2010-2012 by Andrea Diamantini <adjam7 at gmail dot com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License or (at your option) version 3 or any later version
13 * accepted by the membership of KDE e.V. (or its successor approved
14 * by the membership of KDE e.V.), which shall act as a proxy
15 * defined in Section 14 of version 3 of the license.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 *
25 * ============================================================ */
26 
27 
28 // Self Includes
29 #include "adblockmanager.h"
30 
31 #include "settings/globalsettings.h"
32 
33 #include "webpage.h"
34 
35 // KDE Includes
36 #include <KIO/FileCopyJob>
37 #include <KStandardDirs>
38 #include <KNotification>
39 
40 // Qt Includes
41 #include <QUrl>
42 #include <QTimer>
43 #include <QWebElement>
44 #include <QNetworkReply>
45 #include <QNetworkRequest>
46 #include <QtConcurrentRun>
47 #include <QFile>
48 #include <QDateTime>
49 #include <QWebFrame>
50 
51 using namespace MessageViewer;
52 QWeakPointer<AdBlockManager> AdBlockManager::s_adBlockManager;
53 
54 
55 AdBlockManager *AdBlockManager::self()
56 {
57  if (s_adBlockManager.isNull())
58  {
59  s_adBlockManager = new AdBlockManager(qApp);
60  }
61  return s_adBlockManager.data();
62 }
63 
64 
65 // ----------------------------------------------------------------------------------------------
66 
67 
68 AdBlockManager::AdBlockManager(QObject *parent)
69  : QObject(parent)
70 {
71  // NOTE: launch this in a second thread so that it does not delay startup
72  _settingsLoaded = QtConcurrent::run(this, &AdBlockManager::loadSettings);
73 }
74 
75 
76 AdBlockManager::~AdBlockManager()
77 {
78  _whiteList.clear();
79  _blackList.clear();
80 }
81 
82 
83 bool AdBlockManager::isEnabled()
84 {
85  return GlobalSettings::self()->adBlockEnabled();
86 }
87 
88 
89 bool AdBlockManager::isHidingElements()
90 {
91  return GlobalSettings::self()->hideAdsEnabled();
92 }
93 
94 void AdBlockManager::reloadConfig()
95 {
96  loadSettings();
97 }
98 
99 void AdBlockManager::loadSettings()
100 {
101  KConfig config(QLatin1String("messagevieweradblockrc"));
102  // ----------------
103 
104  _hostWhiteList.clear();
105  _hostBlackList.clear();
106 
107  _whiteList.clear();
108  _blackList.clear();
109 
110  _elementHiding.clear();
111 
112  if (!isEnabled())
113  return;
114  // ----------------------------------------------------------
115 
116  QDateTime today = QDateTime::currentDateTime();
117  const int days = GlobalSettings::self()->adBlockUpdateInterval();
118 
119  const QStringList itemList = config.groupList().filter( QRegExp( QLatin1String("FilterList \\d+") ) );
120  Q_FOREACH(const QString &item, itemList) {
121  KConfigGroup filtersGroup(&config, item);
122  const bool isFilterEnabled = filtersGroup.readEntry(QLatin1String("FilterEnabled"), false);
123  if (!isFilterEnabled) {
124  continue;
125  }
126  const QString url = filtersGroup.readEntry(QLatin1String("url"));
127  if (url.isEmpty()) {
128  continue;
129  }
130  const QString path = filtersGroup.readEntry(QLatin1String("path"));
131  if (path.isEmpty())
132  continue;
133 
134  const QDateTime lastDateTime = filtersGroup.readEntry(QLatin1String("lastUpdate"), QDateTime());
135  if (!lastDateTime.isValid() || today > lastDateTime.addDays(days) || !QFile(path).exists()) {
136  updateSubscription(path, url);
137  } else {
138  loadRules(path);
139  }
140  }
141 
142  // load local rules
143  const QString localRulesFilePath = KStandardDirs::locateLocal("appdata" , QLatin1String("adblockrules_local"));
144  loadRules(localRulesFilePath);
145 }
146 
147 
148 void AdBlockManager::loadRules(const QString &rulesFilePath)
149 {
150  QFile ruleFile(rulesFilePath);
151  if (!ruleFile.open(QFile::ReadOnly | QFile::Text)) {
152  kDebug() << "Unable to open rule file" << rulesFilePath;
153  return;
154  }
155 
156  QTextStream in(&ruleFile);
157  while (!in.atEnd())
158  {
159  QString stringRule = in.readLine();
160  loadRuleString(stringRule);
161  }
162 }
163 
164 
165 void AdBlockManager::loadRuleString(const QString &stringRule)
166 {
167  // ! rules are comments
168  if (stringRule.startsWith(QLatin1Char('!')))
169  return;
170 
171  // [ rules are ABP info
172  if (stringRule.startsWith(QLatin1Char('[')))
173  return;
174 
175  // empty rules are just dangerous..
176  // (an empty rule in whitelist allows all, in blacklist blocks all..)
177  if (stringRule.isEmpty())
178  return;
179 
180  // white rules
181  if (stringRule.startsWith(QLatin1String("@@")))
182  {
183  if (_hostWhiteList.tryAddFilter(stringRule))
184  return;
185 
186  const QString filter = stringRule.mid(2);
187  if (filter.isEmpty())
188  return;
189 
190  AdBlockRule rule(filter);
191  _whiteList << rule;
192  return;
193  }
194 
195  // hide (CSS) rules
196  if (stringRule.contains(QLatin1String("##")))
197  {
198  _elementHiding.addRule(stringRule);
199  return;
200  }
201 
202  if (_hostBlackList.tryAddFilter(stringRule))
203  return;
204 
205  AdBlockRule rule(stringRule);
206  _blackList << rule;
207 }
208 
209 
210 bool AdBlockManager::blockRequest(const QNetworkRequest &request)
211 {
212  if (!isEnabled())
213  return false;
214 
215  // we (ad)block just http & https traffic
216  if (request.url().scheme() != QLatin1String("http")
217  && request.url().scheme() != QLatin1String("https"))
218  return false;
219 
220  const QStringList whiteRefererList = GlobalSettings::self()->whiteReferer();
221  const QString referer = QString::fromLatin1(request.rawHeader("referer"));
222  Q_FOREACH(const QString & host, whiteRefererList)
223  {
224  if (referer.contains(host))
225  return false;
226  }
227 
228  QString urlString = request.url().toString();
229  // We compute a lowercase version of the URL so each rule does not
230  // have to do it.
231  const QString urlStringLowerCase = urlString.toLower();
232  const QString host = request.url().host();
233 
234  // check white rules before :)
235  if (_hostWhiteList.match(host))
236  {
237  kDebug() << "ADBLOCK: WHITE RULE (@@) Matched by string: " << urlString;
238  return false;
239  }
240 
241  Q_FOREACH(const AdBlockRule & filter, _whiteList)
242  {
243  if (filter.match(request, urlString, urlStringLowerCase))
244  {
245  kDebug() << "ADBLOCK: WHITE RULE (@@) Matched by string: " << urlString;
246  return false;
247  }
248  }
249 
250  // then check the black ones :(
251  if (_hostBlackList.match(host))
252  {
253  kDebug() << "ADBLOCK: BLACK RULE Matched by string: " << urlString;
254  return true;
255  }
256 
257  Q_FOREACH(const AdBlockRule & filter, _blackList)
258  {
259  if (filter.match(request, urlString, urlStringLowerCase))
260  {
261  kDebug() << "ADBLOCK: BLACK RULE Matched by string: " << urlString;
262  return true;
263  }
264  }
265 
266  // no match
267  return false;
268 }
269 
270 
271 void AdBlockManager::updateSubscription(const QString &path, const QString &url)
272 {
273  KUrl subUrl = KUrl(url);
274 
275  const QString rulesFilePath = path;
276  KUrl destUrl = KUrl(rulesFilePath);
277 
278  KIO::FileCopyJob* job = KIO::file_copy(subUrl , destUrl, -1, KIO::HideProgressInfo | KIO::Overwrite);
279  job->metaData().insert(QLatin1String("ssl_no_client_cert"), QLatin1String("TRUE"));
280  job->metaData().insert(QLatin1String("ssl_no_ui"), QLatin1String("TRUE"));
281  job->metaData().insert(QLatin1String("UseCache"), QLatin1String("false"));
282  job->metaData().insert(QLatin1String("cookies"), QLatin1String("none"));
283  job->metaData().insert(QLatin1String("no-auth"), QLatin1String("true"));
284 
285  connect(job, SIGNAL(finished(KJob*)), this, SLOT(slotFinished(KJob*)));
286 }
287 
288 
289 void AdBlockManager::slotFinished(KJob *job)
290 {
291  if (job->error()) {
292  KNotification *notify = new KNotification( QLatin1String("adblock-list-download-failed") );
293  notify->setComponentData( KComponentData("messageviewer") );
294  notify->setText( i18n("Download new ad-block list was failed." ) );
295  notify->sendEvent();
296  return;
297  }
298 
299  KNotification *notify = new KNotification( QLatin1String("adblock-list-download-done") );
300  notify->setComponentData( KComponentData("messageviewer") );
301  notify->setText( i18n("Download new ad-block list was done." ) );
302  notify->sendEvent();
303 
304  KIO::FileCopyJob *fJob = qobject_cast<KIO::FileCopyJob *>(job);
305  KUrl url = fJob->destUrl();
306  url.setProtocol(QString()); // this is needed to load local url well :(
307  loadRules(url.url());
308 }
309 
310 
311 bool AdBlockManager::subscriptionFileExists(int i)
312 {
313  const QString n = QString::number(i + 1);
314 
315  QString rulesFilePath = KStandardDirs::locateLocal("appdata" , QLatin1String("adblockrules_") + n);
316  return QFile::exists(rulesFilePath);
317 }
318 
319 void AdBlockManager::addCustomRule(const QString &stringRule, bool reloadPage)
320 {
321  // at this point, the settings should be loaded
322  _settingsLoaded.waitForFinished();
323 
324  // save rule in local filters
325  const QString localRulesFilePath = KStandardDirs::locateLocal("appdata" , QLatin1String("adblockrules_local"));
326 
327  QFile ruleFile(localRulesFilePath);
328  if (!ruleFile.open(QFile::ReadOnly)) {
329  kDebug() << "Unable to open rule file" << localRulesFilePath;
330  return;
331  }
332 
333  QTextStream in(&ruleFile);
334  while (!in.atEnd()) {
335  QString readStringRule = in.readLine();
336  if (stringRule == readStringRule) {
337  ruleFile.close();
338  return;
339  }
340  }
341  ruleFile.close();
342  if (!ruleFile.open(QFile::WriteOnly | QFile::Append)) {
343  kDebug() << "Unable to open rule file" << localRulesFilePath;
344  return;
345  }
346 
347  QTextStream out(&ruleFile);
348  out << stringRule << '\n';
349 
350  ruleFile.close();
351 
352  // load it
353  loadRuleString(stringRule);
354 
355  // eventually reload page
356  if (reloadPage)
357  emit reloadCurrentPage();
358 }
359 
360 
361 bool AdBlockManager::isAdblockEnabledForHost(const QString &host)
362 {
363  if (!isEnabled())
364  return false;
365 
366  return ! _hostWhiteList.match(host);
367 }
368 
369 
370 void AdBlockManager::applyHidingRules(QWebFrame *frame)
371 {
372  if (!frame)
373  return;
374 
375  if (!isEnabled())
376  return;
377 
378  connect(frame, SIGNAL(loadFinished(bool)), this, SLOT(applyHidingRules(bool)));
379 }
380 
381 
382 void AdBlockManager::applyHidingRules(bool ok)
383 {
384  if (!ok)
385  return;
386 
387  QWebFrame *frame = qobject_cast<QWebFrame *>(sender());
388  if (!frame)
389  return;
390  MessageViewer::WebPage *page = qobject_cast<MessageViewer::WebPage *>(frame->page());
391  if (!page)
392  return;
393 
394  QString mainPageHost = page->loadingUrl().host();
395  const QStringList hosts = GlobalSettings::self()->whiteReferer();
396  if (hosts.contains(mainPageHost))
397  return;
398 
399  QWebElement document = frame->documentElement();
400 
401  _elementHiding.apply(document, mainPageHost);
402 }
403 
404 #include "adblockmanager.moc"
MessageViewer::AdBlockManager::reloadCurrentPage
void reloadCurrentPage()
MessageViewer::AdBlockRule::match
bool match(const QNetworkRequest &request, const QString &encodedUrl, const QString &encodedUrlLowerCase) const
Definition: adblockrule.cpp:72
MessageViewer::AdBlockManager::~AdBlockManager
~AdBlockManager()
Definition: adblockmanager.cpp:76
globalsettings.h
MessageViewer::WebPage
Definition: webpage.h:25
MessageViewer::AdBlockManager::isAdblockEnabledForHost
bool isAdblockEnabledForHost(const QString &host)
Definition: adblockmanager.cpp:361
MessageViewer::WebPage::loadingUrl
KUrl loadingUrl() const
Definition: webpage.cpp:42
QObject
MessageViewer::AdBlockRule
Definition: adblockrule.h:49
MessageViewer::AdBlockManager::addCustomRule
void addCustomRule(const QString &, bool reloadPage=true)
Definition: adblockmanager.cpp:319
adblockmanager.h
MessageViewer::AdBlockManager::isHidingElements
bool isHidingElements()
Definition: adblockmanager.cpp:89
MessageViewer::GlobalSettings::self
static GlobalSettings * self()
Definition: globalsettings.cpp:34
webpage.h
MessageViewer::AdBlockManager::reloadConfig
void reloadConfig()
Definition: adblockmanager.cpp:94
MessageViewer::AdBlockManager::self
static AdBlockManager * self()
Entry point.
Definition: adblockmanager.cpp:55
MessageViewer::AdBlockManager::blockRequest
bool blockRequest(const QNetworkRequest &request)
Definition: adblockmanager.cpp:210
MessageViewer::AdBlockHostMatcher::tryAddFilter
bool tryAddFilter(const QString &filter)
Definition: adblockhostmatcher.cpp:33
MessageViewer::AdBlockManager::isEnabled
bool isEnabled()
Definition: adblockmanager.cpp:83
MessageViewer::AdBlockManager
Definition: adblockmanager.h:148
MessageViewer::AdBlockElementHiding::apply
void apply(QWebElement &document, const QString &domain) const
Definition: adblockelementhiding.cpp:66
MessageViewer::AdBlockHostMatcher::clear
void clear()
Definition: adblockhostmatcher.cpp:89
MessageViewer::AdBlockHostMatcher::match
bool match(const QString &host) const
Definition: adblockhostmatcher.cpp:84
MessageViewer::AdBlockElementHiding::clear
void clear()
Definition: adblockelementhiding.cpp:92
MessageViewer::AdBlockElementHiding::addRule
bool addRule(const QString &rule)
Definition: adblockelementhiding.cpp:38
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:55:57 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

messageviewer

Skip menu "messageviewer"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal