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

messageviewer

  • sources
  • kde-4.14
  • kdepim
  • messageviewer
  • adblock
adblockmanager.cpp
Go to the documentation of this file.
1 /* ============================================================
2 * Copyright (c) 2013-2015 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 #include "adblock/adblockutil.h"
33 
34 #include "webpage.h"
35 
36 // KDE Includes
37 #include <KIO/FileCopyJob>
38 #include <KStandardDirs>
39 #include <KNotification>
40 
41 // Qt Includes
42 #include <QUrl>
43 #include <QTimer>
44 #include <QWebElement>
45 #include <QNetworkReply>
46 #include <QNetworkRequest>
47 #include <QtConcurrentRun>
48 #include <QFile>
49 #include <QDateTime>
50 #include <QWebFrame>
51 
52 using namespace MessageViewer;
53 QWeakPointer<AdBlockManager> AdBlockManager::s_adBlockManager;
54 
55 
56 AdBlockManager *AdBlockManager::self()
57 {
58  if (s_adBlockManager.isNull())
59  {
60  s_adBlockManager = new AdBlockManager(qApp);
61  }
62  return s_adBlockManager.data();
63 }
64 
65 
66 // ----------------------------------------------------------------------------------------------
67 
68 
69 AdBlockManager::AdBlockManager(QObject *parent)
70  : QObject(parent)
71 {
72  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, item);
137  } else {
138  loadRules(path);
139  }
140  }
141 
142  // load local rules
143  const QString localRulesFilePath = MessageViewer::AdBlockUtil::localFilterPath();
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  qDebug() << "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, const QString &itemName)
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  job->setProperty("itemname", itemName);
285 
286  connect(job, SIGNAL(finished(KJob*)), this, SLOT(slotFinished(KJob*)));
287 }
288 
289 
290 void AdBlockManager::slotFinished(KJob *job)
291 {
292  if (job->error()) {
293  KNotification *notify = new KNotification( QLatin1String("adblock-list-download-failed") );
294  notify->setComponentData( KComponentData("messageviewer") );
295  notify->setText( i18n("Download new ad-block list was failed." ) );
296  notify->sendEvent();
297  return;
298  }
299 
300  KNotification *notify = new KNotification( QLatin1String("adblock-list-download-done") );
301  notify->setComponentData( KComponentData("messageviewer") );
302  notify->setText( i18n("Download new ad-block list was done." ) );
303  notify->sendEvent();
304  const QString itemName = job->property("itemname").toString();
305  if (!itemName.isEmpty()) {
306  KConfig config(QLatin1String("messagevieweradblockrc"));
307  if (config.hasGroup(itemName)) {
308  KConfigGroup grp = config.group(itemName);
309  grp.writeEntry(QLatin1String("lastUpdate"), QDateTime::currentDateTime());
310  }
311  }
312 
313  KIO::FileCopyJob *fJob = qobject_cast<KIO::FileCopyJob *>(job);
314  KUrl url = fJob->destUrl();
315  url.setProtocol(QString()); // this is needed to load local url well :(
316  loadRules(url.url());
317 }
318 
319 
320 bool AdBlockManager::subscriptionFileExists(int i)
321 {
322  const QString n = QString::number(i + 1);
323 
324  const QString rulesFilePath = KStandardDirs::locateLocal("data" , QLatin1String("kmail2/adblockrules_") + n);
325  return QFile::exists(rulesFilePath);
326 }
327 
328 void AdBlockManager::addCustomRule(const QString &stringRule, bool reloadPage)
329 {
330  // save rule in local filters
331  const QString localRulesFilePath = MessageViewer::AdBlockUtil::localFilterPath();
332 
333  QFile ruleFile(localRulesFilePath);
334  if (!ruleFile.open(QFile::ReadOnly)) {
335  kDebug() << "Unable to open rule file" << localRulesFilePath;
336  return;
337  }
338 
339  QTextStream in(&ruleFile);
340  while (!in.atEnd()) {
341  QString readStringRule = in.readLine();
342  if (stringRule == readStringRule) {
343  ruleFile.close();
344  return;
345  }
346  }
347  ruleFile.close();
348  if (!ruleFile.open(QFile::WriteOnly | QFile::Append)) {
349  kDebug() << "Unable to open rule file" << localRulesFilePath;
350  return;
351  }
352 
353  QTextStream out(&ruleFile);
354  out << stringRule << '\n';
355 
356  ruleFile.close();
357 
358  // load it
359  loadRuleString(stringRule);
360 
361  // eventually reload page
362  if (reloadPage)
363  emit reloadCurrentPage();
364 }
365 
366 
367 bool AdBlockManager::isAdblockEnabledForHost(const QString &host)
368 {
369  if (!isEnabled())
370  return false;
371 
372  return ! _hostWhiteList.match(host);
373 }
374 
375 
376 void AdBlockManager::applyHidingRules(QWebFrame *frame)
377 {
378  if (!frame)
379  return;
380 
381  if (!isEnabled())
382  return;
383 
384  connect(frame, SIGNAL(loadFinished(bool)), this, SLOT(applyHidingRules(bool)));
385 }
386 
387 
388 void AdBlockManager::applyHidingRules(bool ok)
389 {
390  if (!ok)
391  return;
392 
393  QWebFrame *frame = qobject_cast<QWebFrame *>(sender());
394  if (!frame)
395  return;
396  MessageViewer::WebPage *page = qobject_cast<MessageViewer::WebPage *>(frame->page());
397  if (!page)
398  return;
399 
400  QString mainPageHost = page->loadingUrl().host();
401  const QStringList hosts = GlobalSettings::self()->whiteReferer();
402  if (hosts.contains(mainPageHost))
403  return;
404 
405  QWebElement document = frame->documentElement();
406 
407  _elementHiding.apply(document, mainPageHost);
408 }
409 
MessageViewer::AdBlockManager::reloadCurrentPage
void reloadCurrentPage()
MessageViewer::AdBlockRule::match
bool match(const QNetworkRequest &request, const QString &encodedUrl, const QString &encodedUrlLowerCase) const
Definition: adblockrule.cpp:72
QList::clear
void clear()
MessageViewer::AdBlockManager::~AdBlockManager
~AdBlockManager()
Definition: adblockmanager.cpp:76
globalsettings.h
MessageViewer::WebPage
Definition: webpage.h:25
QWebFrame
QWebFrame::documentElement
QWebElement documentElement() const
QTextStream::readLine
QString readLine(qint64 maxlen)
MessageViewer::AdBlockManager::isAdblockEnabledForHost
bool isAdblockEnabledForHost(const QString &host)
Definition: adblockmanager.cpp:367
QObject::sender
QObject * sender() const
QNetworkRequest::rawHeader
QByteArray rawHeader(const QByteArray &headerName) const
MessageViewer::WebPage::loadingUrl
KUrl loadingUrl() const
Definition: webpage.cpp:42
MessageViewer::AdBlockUtil::localFilterPath
QString localFilterPath()
Definition: adblockutil.cpp:69
QUrl::host
QString host() const
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QFile::exists
bool exists() const
QUrl::toString
QString toString(QFlags< QUrl::FormattingOption > options) const
QFile
QTextStream
MessageViewer::AdBlockRule
Definition: adblockrule.h:49
MessageViewer::AdBlockManager::addCustomRule
void addCustomRule(const QString &, bool reloadPage=true)
Definition: adblockmanager.cpp:328
adblockmanager.h
MessageViewer::AdBlockManager::isHidingElements
bool isHidingElements()
Definition: adblockmanager.cpp:89
QRegExp
QNetworkRequest
QString::number
QString number(int n, int base)
QTextStream::atEnd
bool atEnd() const
QObject
QWebElement
QString::isEmpty
bool isEmpty() const
MessageViewer::GlobalSettings::self
static GlobalSettings * self()
Definition: globalsettings.cpp:34
webpage.h
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QString
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QUrl::scheme
QString scheme() const
QStringList
QWebFrame::page
QWebPage * page() const
QString::toLower
QString toLower() const
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QLatin1Char
adblockutil.h
QNetworkRequest::url
QUrl url() const
MessageViewer::AdBlockManager::reloadConfig
void reloadConfig()
Definition: adblockmanager.cpp:94
QFile::close
virtual void close()
QDateTime::isValid
bool isValid() const
MessageViewer::AdBlockManager::self
static AdBlockManager * self()
Entry point.
Definition: adblockmanager.cpp:56
MessageViewer::AdBlockManager::blockRequest
bool blockRequest(const QNetworkRequest &request)
Definition: adblockmanager.cpp:210
QDateTime::currentDateTime
QDateTime currentDateTime()
QString::mid
QString mid(int position, int n) const
QLatin1String
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:147
MessageViewer::AdBlockElementHiding::apply
void apply(QWebElement &document, const QString &domain) const
Definition: adblockelementhiding.cpp:66
MessageViewer::AdBlockHostMatcher::clear
void clear()
Definition: adblockhostmatcher.cpp:89
QWeakPointer
QString::fromLatin1
QString fromLatin1(const char *str, int size)
MessageViewer::AdBlockHostMatcher::match
bool match(const QString &host) const
Definition: adblockhostmatcher.cpp:84
MessageViewer::AdBlockElementHiding::clear
void clear()
Definition: adblockelementhiding.cpp:92
QtConcurrent::filter
QFuture< void > filter(Sequence &sequence, FilterFunction filterFunction)
QStringList::filter
QStringList filter(const QString &str, Qt::CaseSensitivity cs) const
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QDateTime::addDays
QDateTime addDays(int ndays) const
KJob
QDateTime
MessageViewer::AdBlockElementHiding::addRule
bool addRule(const QString &rule)
Definition: adblockelementhiding.cpp:38
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:32:45 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
  • pimprint

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