|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2009 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the AdBlock manager. |
|
8 """ |
|
9 |
|
10 import os |
|
11 import contextlib |
|
12 |
|
13 from PyQt5.QtCore import ( |
|
14 pyqtSignal, QObject, QUrl, QUrlQuery, QFile, QByteArray, QMutex |
|
15 ) |
|
16 from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInfo |
|
17 |
|
18 from E5Gui import E5MessageBox |
|
19 |
|
20 from E5Utilities.E5MutexLocker import E5MutexLocker |
|
21 |
|
22 from .AdBlockSubscription import AdBlockSubscription |
|
23 from .AdBlockUrlInterceptor import AdBlockUrlInterceptor |
|
24 from .AdBlockMatcher import AdBlockMatcher |
|
25 |
|
26 from Utilities.AutoSaver import AutoSaver |
|
27 import Utilities |
|
28 import Preferences |
|
29 |
|
30 |
|
31 class AdBlockManager(QObject): |
|
32 """ |
|
33 Class implementing the AdBlock manager. |
|
34 |
|
35 @signal rulesChanged() emitted after some rule has changed |
|
36 @signal requiredSubscriptionLoaded(subscription) emitted to indicate |
|
37 loading of a required subscription is finished (AdBlockSubscription) |
|
38 @signal enabledChanged(enabled) emitted to indicate a change of the |
|
39 enabled state |
|
40 """ |
|
41 rulesChanged = pyqtSignal() |
|
42 requiredSubscriptionLoaded = pyqtSignal(AdBlockSubscription) |
|
43 enabledChanged = pyqtSignal(bool) |
|
44 |
|
45 def __init__(self, parent=None): |
|
46 """ |
|
47 Constructor |
|
48 |
|
49 @param parent reference to the parent object |
|
50 @type QObject |
|
51 """ |
|
52 super().__init__(parent) |
|
53 |
|
54 self.__loaded = False |
|
55 self.__subscriptionsLoaded = False |
|
56 self.__enabled = False |
|
57 self.__adBlockDialog = None |
|
58 self.__adBlockExceptionsDialog = None |
|
59 self.__adBlockNetwork = None |
|
60 self.__adBlockPage = None |
|
61 self.__subscriptions = [] |
|
62 self.__exceptedHosts = Preferences.getWebBrowser("AdBlockExceptions") |
|
63 self.__saveTimer = AutoSaver(self, self.save) |
|
64 self.__limitedEasyList = Preferences.getWebBrowser( |
|
65 "AdBlockUseLimitedEasyList") |
|
66 |
|
67 self.__defaultSubscriptionUrlString = ( |
|
68 "abp:subscribe?location=" |
|
69 "https://easylist-downloads.adblockplus.org/easylist.txt&" |
|
70 "title=EasyList" |
|
71 ) |
|
72 self.__additionalDefaultSubscriptionUrlStrings = ( |
|
73 "abp:subscribe?location=https://raw.githubusercontent.com/" |
|
74 "hoshsadiq/adblock-nocoin-list/master/nocoin.txt&" |
|
75 "title=NoCoin", |
|
76 ) |
|
77 self.__customSubscriptionUrlString = ( |
|
78 bytes(self.__customSubscriptionUrl().toEncoded()).decode() |
|
79 ) |
|
80 |
|
81 self.__mutex = QMutex() |
|
82 self.__matcher = AdBlockMatcher(self) |
|
83 |
|
84 self.rulesChanged.connect(self.__saveTimer.changeOccurred) |
|
85 self.rulesChanged.connect(self.__rulesChanged) |
|
86 |
|
87 self.__interceptor = AdBlockUrlInterceptor(self) |
|
88 |
|
89 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
|
90 WebBrowserWindow.networkManager().installUrlInterceptor( |
|
91 self.__interceptor) |
|
92 |
|
93 def __rulesChanged(self): |
|
94 """ |
|
95 Private slot handling a change of the AdBlock rules. |
|
96 """ |
|
97 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
|
98 WebBrowserWindow.mainWindow().reloadUserStyleSheet() |
|
99 self.__updateMatcher() |
|
100 |
|
101 def close(self): |
|
102 """ |
|
103 Public method to close the open search engines manager. |
|
104 """ |
|
105 self.__adBlockDialog and self.__adBlockDialog.close() |
|
106 (self.__adBlockExceptionsDialog and |
|
107 self.__adBlockExceptionsDialog.close()) |
|
108 |
|
109 self.__saveTimer.saveIfNeccessary() |
|
110 |
|
111 def isEnabled(self): |
|
112 """ |
|
113 Public method to check, if blocking ads is enabled. |
|
114 |
|
115 @return flag indicating the enabled state |
|
116 @rtype bool |
|
117 """ |
|
118 if not self.__loaded: |
|
119 self.load() |
|
120 |
|
121 return self.__enabled |
|
122 |
|
123 def setEnabled(self, enabled): |
|
124 """ |
|
125 Public slot to set the enabled state. |
|
126 |
|
127 @param enabled flag indicating the enabled state |
|
128 @type bool |
|
129 """ |
|
130 if self.isEnabled() == enabled: |
|
131 return |
|
132 |
|
133 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
|
134 self.__enabled = enabled |
|
135 for mainWindow in WebBrowserWindow.mainWindows(): |
|
136 mainWindow.adBlockIcon().setEnabled(enabled) |
|
137 if enabled: |
|
138 self.__loadSubscriptions() |
|
139 |
|
140 self.rulesChanged.emit() |
|
141 self.enabledChanged.emit(enabled) |
|
142 |
|
143 def block(self, info): |
|
144 """ |
|
145 Public method to check, if a request should be blocked. |
|
146 |
|
147 @param info request info object |
|
148 @type QWebEngineUrlRequestInfo |
|
149 @return flag indicating to block the request |
|
150 @rtype bool |
|
151 """ |
|
152 with E5MutexLocker(self.__mutex): |
|
153 if not self.isEnabled(): |
|
154 return False |
|
155 |
|
156 urlString = bytes(info.requestUrl().toEncoded()).decode().lower() |
|
157 urlDomain = info.requestUrl().host().lower() |
|
158 urlScheme = info.requestUrl().scheme().lower() |
|
159 |
|
160 if ( |
|
161 not self.canRunOnScheme(urlScheme) or |
|
162 not self.__canBeBlocked(info.firstPartyUrl()) |
|
163 ): |
|
164 return False |
|
165 |
|
166 res = False |
|
167 blockedRule = self.__matcher.match(info, urlDomain, urlString) |
|
168 |
|
169 if blockedRule: |
|
170 res = True |
|
171 if ( |
|
172 info.resourceType() == |
|
173 QWebEngineUrlRequestInfo.ResourceType |
|
174 .ResourceTypeMainFrame |
|
175 ): |
|
176 url = QUrl("eric:adblock") |
|
177 query = QUrlQuery() |
|
178 query.addQueryItem("rule", blockedRule.filter()) |
|
179 query.addQueryItem( |
|
180 "subscription", blockedRule.subscription().title()) |
|
181 url.setQuery(query) |
|
182 info.redirect(url) |
|
183 else: |
|
184 info.block(True) |
|
185 |
|
186 return res |
|
187 |
|
188 def canRunOnScheme(self, scheme): |
|
189 """ |
|
190 Public method to check, if AdBlock can be performed on the scheme. |
|
191 |
|
192 @param scheme scheme to check |
|
193 @type str |
|
194 @return flag indicating, that AdBlock can be performed |
|
195 @rtype bool |
|
196 """ |
|
197 return scheme not in ["data", "eric", "qthelp", "qrc", "file", "abp"] |
|
198 |
|
199 def page(self): |
|
200 """ |
|
201 Public method to get a reference to the page block object. |
|
202 |
|
203 @return reference to the page block object |
|
204 @rtype AdBlockPage |
|
205 """ |
|
206 if self.__adBlockPage is None: |
|
207 from .AdBlockPage import AdBlockPage |
|
208 self.__adBlockPage = AdBlockPage(self) |
|
209 return self.__adBlockPage |
|
210 |
|
211 def __customSubscriptionLocation(self): |
|
212 """ |
|
213 Private method to generate the path for custom subscriptions. |
|
214 |
|
215 @return URL for custom subscriptions |
|
216 @rtype QUrl |
|
217 """ |
|
218 dataDir = os.path.join(Utilities.getConfigDir(), "web_browser", |
|
219 "subscriptions") |
|
220 if not os.path.exists(dataDir): |
|
221 os.makedirs(dataDir) |
|
222 fileName = os.path.join(dataDir, "adblock_subscription_custom") |
|
223 return QUrl.fromLocalFile(fileName) |
|
224 |
|
225 def __customSubscriptionUrl(self): |
|
226 """ |
|
227 Private method to generate the URL for custom subscriptions. |
|
228 |
|
229 @return URL for custom subscriptions |
|
230 @rtype QUrl |
|
231 """ |
|
232 location = self.__customSubscriptionLocation() |
|
233 encodedUrl = bytes(location.toEncoded()).decode() |
|
234 url = QUrl("abp:subscribe?location={0}&title={1}".format( |
|
235 encodedUrl, self.tr("Custom Rules"))) |
|
236 return url |
|
237 |
|
238 def customRules(self): |
|
239 """ |
|
240 Public method to get a subscription for custom rules. |
|
241 |
|
242 @return subscription object for custom rules |
|
243 @rtype AdBlockSubscription |
|
244 """ |
|
245 location = self.__customSubscriptionLocation() |
|
246 for subscription in self.__subscriptions: |
|
247 if subscription.location() == location: |
|
248 return subscription |
|
249 |
|
250 url = self.__customSubscriptionUrl() |
|
251 customAdBlockSubscription = AdBlockSubscription(url, True, self) |
|
252 self.addSubscription(customAdBlockSubscription) |
|
253 return customAdBlockSubscription |
|
254 |
|
255 def subscriptions(self): |
|
256 """ |
|
257 Public method to get all subscriptions. |
|
258 |
|
259 @return list of subscriptions |
|
260 @rtype list of AdBlockSubscription |
|
261 """ |
|
262 if not self.__loaded: |
|
263 self.load() |
|
264 |
|
265 return self.__subscriptions[:] |
|
266 |
|
267 def subscription(self, location): |
|
268 """ |
|
269 Public method to get a subscription based on its location. |
|
270 |
|
271 @param location location of the subscription to search for |
|
272 @type str |
|
273 @return subscription or None |
|
274 @rtype AdBlockSubscription |
|
275 """ |
|
276 if location != "": |
|
277 for subscription in self.__subscriptions: |
|
278 if subscription.location().toString() == location: |
|
279 return subscription |
|
280 |
|
281 return None |
|
282 |
|
283 def updateAllSubscriptions(self): |
|
284 """ |
|
285 Public method to update all subscriptions. |
|
286 """ |
|
287 for subscription in self.__subscriptions: |
|
288 subscription.updateNow() |
|
289 |
|
290 def removeSubscription(self, subscription, emitSignal=True): |
|
291 """ |
|
292 Public method to remove an AdBlock subscription. |
|
293 |
|
294 @param subscription AdBlock subscription to be removed |
|
295 @type AdBlockSubscription |
|
296 @param emitSignal flag indicating to send a signal |
|
297 @type bool |
|
298 """ |
|
299 if subscription is None: |
|
300 return |
|
301 |
|
302 if subscription.url().toString().startswith( |
|
303 (self.__defaultSubscriptionUrlString, |
|
304 self.__customSubscriptionUrlString)): |
|
305 return |
|
306 |
|
307 with contextlib.suppress(ValueError): |
|
308 self.__subscriptions.remove(subscription) |
|
309 rulesFileName = subscription.rulesFileName() |
|
310 QFile.remove(rulesFileName) |
|
311 requiresSubscriptions = self.getRequiresSubscriptions(subscription) |
|
312 for requiresSubscription in requiresSubscriptions: |
|
313 self.removeSubscription(requiresSubscription, False) |
|
314 if emitSignal: |
|
315 self.rulesChanged.emit() |
|
316 |
|
317 def addSubscriptionFromUrl(self, url): |
|
318 """ |
|
319 Public method to ad an AdBlock subscription given the abp URL. |
|
320 |
|
321 @param url URL to subscribe an AdBlock subscription |
|
322 @type QUrl |
|
323 @return flag indicating success |
|
324 @rtype bool |
|
325 """ |
|
326 if url.path() != "subscribe": |
|
327 return False |
|
328 |
|
329 title = QUrl.fromPercentEncoding( |
|
330 QByteArray(QUrlQuery(url).queryItemValue("title").encode())) |
|
331 if not title: |
|
332 return False |
|
333 |
|
334 res = E5MessageBox.yesNo( |
|
335 None, |
|
336 self.tr("Subscribe?"), |
|
337 self.tr( |
|
338 """<p>Subscribe to this AdBlock subscription?</p>""" |
|
339 """<p>{0}</p>""").format(title)) |
|
340 if res: |
|
341 from .AdBlockSubscription import AdBlockSubscription |
|
342 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
|
343 |
|
344 dlg = WebBrowserWindow.adBlockManager().showDialog() |
|
345 subscription = AdBlockSubscription( |
|
346 url, False, |
|
347 WebBrowserWindow.adBlockManager()) |
|
348 WebBrowserWindow.adBlockManager().addSubscription(subscription) |
|
349 dlg.addSubscription(subscription, False) |
|
350 dlg.setFocus() |
|
351 dlg.raise_() |
|
352 |
|
353 return res |
|
354 |
|
355 def addSubscription(self, subscription): |
|
356 """ |
|
357 Public method to add an AdBlock subscription. |
|
358 |
|
359 @param subscription AdBlock subscription to be added |
|
360 @type AdBlockSubscription |
|
361 """ |
|
362 if subscription is None: |
|
363 return |
|
364 |
|
365 self.__subscriptions.insert(-1, subscription) |
|
366 |
|
367 subscription.rulesChanged.connect(self.rulesChanged) |
|
368 subscription.changed.connect(self.rulesChanged) |
|
369 subscription.enabledChanged.connect(self.rulesChanged) |
|
370 |
|
371 self.rulesChanged.emit() |
|
372 |
|
373 def save(self): |
|
374 """ |
|
375 Public method to save the AdBlock subscriptions. |
|
376 """ |
|
377 if not self.__loaded: |
|
378 return |
|
379 |
|
380 Preferences.setWebBrowser("AdBlockEnabled", self.__enabled) |
|
381 if self.__subscriptionsLoaded: |
|
382 subscriptions = [] |
|
383 requiresSubscriptions = [] |
|
384 # intermediate store for subscription requiring others |
|
385 for subscription in self.__subscriptions: |
|
386 if subscription is None: |
|
387 continue |
|
388 urlString = bytes(subscription.url().toEncoded()).decode() |
|
389 if "requiresLocation" in urlString: |
|
390 requiresSubscriptions.append(urlString) |
|
391 else: |
|
392 subscriptions.append(urlString) |
|
393 subscription.saveRules() |
|
394 for subscription in requiresSubscriptions: |
|
395 subscriptions.insert(-1, subscription) # custom should be last |
|
396 Preferences.setWebBrowser("AdBlockSubscriptions", subscriptions) |
|
397 |
|
398 def load(self): |
|
399 """ |
|
400 Public method to load the AdBlock subscriptions. |
|
401 """ |
|
402 if self.__loaded: |
|
403 return |
|
404 |
|
405 self.__loaded = True |
|
406 |
|
407 self.__enabled = Preferences.getWebBrowser("AdBlockEnabled") |
|
408 if self.__enabled: |
|
409 self.__loadSubscriptions() |
|
410 |
|
411 def __loadSubscriptions(self): |
|
412 """ |
|
413 Private method to load the set of subscriptions. |
|
414 """ |
|
415 if self.__subscriptionsLoaded: |
|
416 return |
|
417 |
|
418 subscriptions = Preferences.getWebBrowser("AdBlockSubscriptions") |
|
419 if subscriptions: |
|
420 for subscription in subscriptions: |
|
421 if subscription.startswith(self.__customSubscriptionUrlString): |
|
422 break |
|
423 else: |
|
424 subscriptions.append(self.__customSubscriptionUrlString) |
|
425 else: |
|
426 subscriptions = ( |
|
427 [self.__defaultSubscriptionUrlString] + |
|
428 self.__additionalDefaultSubscriptionUrlStrings + |
|
429 [self.__customSubscriptionUrlString] |
|
430 ) |
|
431 for subscription in subscriptions: |
|
432 url = QUrl.fromEncoded(subscription.encode("utf-8")) |
|
433 adBlockSubscription = AdBlockSubscription( |
|
434 url, |
|
435 subscription.startswith(self.__customSubscriptionUrlString), |
|
436 self, |
|
437 subscription.startswith(self.__defaultSubscriptionUrlString)) |
|
438 adBlockSubscription.rulesChanged.connect(self.rulesChanged) |
|
439 adBlockSubscription.changed.connect(self.rulesChanged) |
|
440 adBlockSubscription.enabledChanged.connect(self.rulesChanged) |
|
441 adBlockSubscription.rulesEnabledChanged.connect( |
|
442 self.__updateMatcher) |
|
443 adBlockSubscription.rulesEnabledChanged.connect( |
|
444 self.__saveTimer.changeOccurred) |
|
445 self.__subscriptions.append(adBlockSubscription) |
|
446 |
|
447 self.__subscriptionsLoaded = True |
|
448 |
|
449 self.__updateMatcher() |
|
450 |
|
451 def loadRequiredSubscription(self, location, title): |
|
452 """ |
|
453 Public method to load a subscription required by another one. |
|
454 |
|
455 @param location location of the required subscription |
|
456 @type str |
|
457 @param title title of the required subscription |
|
458 @type str |
|
459 """ |
|
460 # Step 1: check, if the subscription is in the list of subscriptions |
|
461 urlString = "abp:subscribe?location={0}&title={1}".format( |
|
462 location, title) |
|
463 for subscription in self.__subscriptions: |
|
464 if subscription.url().toString().startswith(urlString): |
|
465 # We found it! |
|
466 return |
|
467 |
|
468 # Step 2: if it is not, get it |
|
469 url = QUrl.fromEncoded(urlString.encode("utf-8")) |
|
470 adBlockSubscription = AdBlockSubscription(url, False, self) |
|
471 self.addSubscription(adBlockSubscription) |
|
472 self.requiredSubscriptionLoaded.emit(adBlockSubscription) |
|
473 |
|
474 def getRequiresSubscriptions(self, subscription): |
|
475 """ |
|
476 Public method to get a list of subscriptions, that require the given |
|
477 one. |
|
478 |
|
479 @param subscription subscription to check for |
|
480 @type AdBlockSubscription |
|
481 @return list of subscription requiring the given one |
|
482 @rtype list of AdBlockSubscription |
|
483 """ |
|
484 subscriptions = [] |
|
485 location = subscription.location().toString() |
|
486 for subscription in self.__subscriptions: |
|
487 if subscription.requiresLocation() == location: |
|
488 subscriptions.append(subscription) |
|
489 |
|
490 return subscriptions |
|
491 |
|
492 def showDialog(self): |
|
493 """ |
|
494 Public slot to show the AdBlock subscription management dialog. |
|
495 |
|
496 @return reference to the dialog |
|
497 @rtype AdBlockDialog |
|
498 """ |
|
499 if self.__adBlockDialog is None: |
|
500 from .AdBlockDialog import AdBlockDialog |
|
501 self.__adBlockDialog = AdBlockDialog(self) |
|
502 |
|
503 self.__adBlockDialog.show() |
|
504 return self.__adBlockDialog |
|
505 |
|
506 def elementHidingRules(self, url): |
|
507 """ |
|
508 Public method to get the element hiding rules. |
|
509 |
|
510 |
|
511 @param url URL to get hiding rules for |
|
512 @type QUrl |
|
513 @return element hiding rules |
|
514 @rtype str |
|
515 """ |
|
516 if ( |
|
517 not self.isEnabled() or |
|
518 not self.canRunOnScheme(url.scheme()) or |
|
519 not self.__canBeBlocked(url) |
|
520 ): |
|
521 return "" |
|
522 |
|
523 return self.__matcher.elementHidingRules() |
|
524 |
|
525 def elementHidingRulesForDomain(self, url): |
|
526 """ |
|
527 Public method to get the element hiding rules for a domain. |
|
528 |
|
529 @param url URL to get hiding rules for |
|
530 @type QUrl |
|
531 @return element hiding rules |
|
532 @rtype str |
|
533 """ |
|
534 if ( |
|
535 not self.isEnabled() or |
|
536 not self.canRunOnScheme(url.scheme()) or |
|
537 not self.__canBeBlocked(url) |
|
538 ): |
|
539 return "" |
|
540 |
|
541 return self.__matcher.elementHidingRulesForDomain(url.host()) |
|
542 |
|
543 def exceptions(self): |
|
544 """ |
|
545 Public method to get a list of excepted hosts. |
|
546 |
|
547 @return list of excepted hosts |
|
548 @rtype list of str |
|
549 """ |
|
550 return self.__exceptedHosts |
|
551 |
|
552 def setExceptions(self, hosts): |
|
553 """ |
|
554 Public method to set the list of excepted hosts. |
|
555 |
|
556 @param hosts list of excepted hosts |
|
557 @type list of str |
|
558 """ |
|
559 self.__exceptedHosts = [host.lower() for host in hosts] |
|
560 Preferences.setWebBrowser("AdBlockExceptions", self.__exceptedHosts) |
|
561 |
|
562 def addException(self, host): |
|
563 """ |
|
564 Public method to add an exception. |
|
565 |
|
566 @param host to be excepted |
|
567 @type str |
|
568 """ |
|
569 host = host.lower() |
|
570 if host and host not in self.__exceptedHosts: |
|
571 self.__exceptedHosts.append(host) |
|
572 Preferences.setWebBrowser( |
|
573 "AdBlockExceptions", self.__exceptedHosts) |
|
574 |
|
575 def removeException(self, host): |
|
576 """ |
|
577 Public method to remove an exception. |
|
578 |
|
579 @param host to be removed from the list of exceptions |
|
580 @type str |
|
581 """ |
|
582 host = host.lower() |
|
583 if host in self.__exceptedHosts: |
|
584 self.__exceptedHosts.remove(host) |
|
585 Preferences.setWebBrowser( |
|
586 "AdBlockExceptions", self.__exceptedHosts) |
|
587 |
|
588 def isHostExcepted(self, host): |
|
589 """ |
|
590 Public slot to check, if a host is excepted. |
|
591 |
|
592 @param host host to check |
|
593 @type str |
|
594 @return flag indicating an exception |
|
595 @rtype bool |
|
596 """ |
|
597 host = host.lower() |
|
598 return host in self.__exceptedHosts |
|
599 |
|
600 def showExceptionsDialog(self): |
|
601 """ |
|
602 Public method to show the AdBlock Exceptions dialog. |
|
603 |
|
604 @return reference to the exceptions dialog |
|
605 @rtype AdBlockExceptionsDialog |
|
606 """ |
|
607 if self.__adBlockExceptionsDialog is None: |
|
608 from .AdBlockExceptionsDialog import AdBlockExceptionsDialog |
|
609 self.__adBlockExceptionsDialog = AdBlockExceptionsDialog() |
|
610 |
|
611 self.__adBlockExceptionsDialog.load(self.__exceptedHosts) |
|
612 self.__adBlockExceptionsDialog.show() |
|
613 return self.__adBlockExceptionsDialog |
|
614 |
|
615 def useLimitedEasyList(self): |
|
616 """ |
|
617 Public method to test, if limited EasyList rules shall be used. |
|
618 |
|
619 @return flag indicating limited EasyList rules |
|
620 @rtype bool |
|
621 """ |
|
622 return self.__limitedEasyList |
|
623 |
|
624 def setUseLimitedEasyList(self, limited): |
|
625 """ |
|
626 Public method to set the limited EasyList flag. |
|
627 |
|
628 @param limited flag indicating to use limited EasyList |
|
629 @type bool |
|
630 """ |
|
631 self.__limitedEasyList = limited |
|
632 |
|
633 for subscription in self.__subscriptions: |
|
634 if subscription.url().toString().startswith( |
|
635 self.__defaultSubscriptionUrlString): |
|
636 subscription.updateNow() |
|
637 |
|
638 Preferences.setWebBrowser("AdBlockUseLimitedEasyList", limited) |
|
639 |
|
640 def getDefaultSubscriptionUrl(self): |
|
641 """ |
|
642 Public method to get the default subscription URL. |
|
643 |
|
644 @return default subscription URL |
|
645 @rtype str |
|
646 """ |
|
647 return self.__defaultSubscriptionUrlString |
|
648 |
|
649 def __updateMatcher(self): |
|
650 """ |
|
651 Private slot to update the adblock matcher. |
|
652 """ |
|
653 from WebBrowser.WebBrowserWindow import WebBrowserWindow |
|
654 WebBrowserWindow.networkManager().removeUrlInterceptor( |
|
655 self.__interceptor) |
|
656 |
|
657 if self.__enabled: |
|
658 self.__matcher.update() |
|
659 else: |
|
660 self.__matcher.clear() |
|
661 |
|
662 WebBrowserWindow.networkManager().installUrlInterceptor( |
|
663 self.__interceptor) |
|
664 |
|
665 def __canBeBlocked(self, url): |
|
666 """ |
|
667 Private method to check, if the given URL could be blocked (i.e. is |
|
668 not whitelisted). |
|
669 |
|
670 @param url URL to be checked |
|
671 @type QUrl |
|
672 @return flag indicating that the given URL can be blocked |
|
673 @rtype bool |
|
674 """ |
|
675 return not self.__matcher.adBlockDisabledForUrl(url) |