1# Copyright (c) 2017-2021 Cedric Bellegarde <cedric.bellegarde@adishatz.org> 2# This program is free software: you can redistribute it and/or modify 3# it under the terms of the GNU General Public License as published by 4# the Free Software Foundation, either version 3 of the License, or 5# (at your option) any later version. 6# This program is distributed in the hope that it will be useful, 7# but WITHOUT ANY WARRANTY; without even the implied warranty of 8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9# GNU General Public License for more details. 10# You should have received a copy of the GNU General Public License 11# along with this program. If not, see <http://www.gnu.org/licenses/>. 12 13from gi.repository import Gio, GLib 14from gi.repository.Gio import FILE_ATTRIBUTE_STANDARD_NAME, \ 15 FILE_ATTRIBUTE_TIME_MODIFIED 16 17import json 18from time import time 19 20from eolie.content_blocker import ContentBlocker 21from eolie.define import ADBLOCK_URIS, App 22from eolie.logger import Logger 23 24 25SCAN_QUERY_INFO = "{},{}".format(FILE_ATTRIBUTE_STANDARD_NAME, 26 FILE_ATTRIBUTE_TIME_MODIFIED) 27 28 29class AdContentBlocker(ContentBlocker): 30 """ 31 A WebKit Content Blocker for ads 32 """ 33 34 def __init__(self): 35 """ 36 Init adblock helper 37 """ 38 try: 39 ContentBlocker.__init__(self, "block-ads") 40 f = Gio.File.new_for_path( 41 "%s/block-ads.json" % self._JSON_PATH) 42 if f.query_exists(): 43 info = f.query_info(SCAN_QUERY_INFO, 44 Gio.FileQueryInfoFlags.NONE, 45 None) 46 mtime = int(info.get_attribute_as_string("time::modified")) 47 else: 48 mtime = 0 49 if App().settings.get_value("block-ads"): 50 GLib.timeout_add_seconds(7200, self.__download_task, True) 51 if time() - mtime > 7200: 52 GLib.timeout_add_seconds(20, self.__download_task, False) 53 except Exception as e: 54 Logger.error("AdContentBlocker::__init__(): %s", e) 55 56####################### 57# PRIVATE # 58####################### 59 def __download_task(self, loop): 60 """ 61 Update database from the web, for timeout_add() 62 @param loop as bool 63 """ 64 if not Gio.NetworkMonitor.get_default().get_network_metered(): 65 self.__download_uris(list(ADBLOCK_URIS)) 66 return loop 67 68 def __download_uris(self, uris, rules=[]): 69 """ 70 Update database from the web 71 @param uris as [str] 72 @param data as [] 73 """ 74 if not Gio.NetworkMonitor.get_default().get_network_available(): 75 return 76 if uris: 77 uri = uris.pop(0) 78 self._task_helper.load_uri_content(uri, 79 self._cancellable, 80 self.__on_load_uri_content, 81 uris, 82 rules) 83 84 def __on_load_uri_content(self, uri, status, content, uris, rules): 85 """ 86 Save loaded values 87 @param uri as str 88 @param status as bool 89 @param content as bytes 90 @param uris as [str] 91 @param rules as [] 92 """ 93 try: 94 Logger.debug("AdContentBlocker::__on_load_uri_content(): %s", uri) 95 if status: 96 rules += json.loads(content.decode("utf-8")) 97 if uris: 98 self.__download_uris(uris, rules) 99 elif rules: 100 # Save to sources 101 f = Gio.File.new_for_path( 102 "%s/block-ads.json" % self._JSON_PATH) 103 content = json.dumps(rules).encode("utf-8") 104 f.replace_contents(content, 105 None, 106 False, 107 Gio.FileCreateFlags.REPLACE_DESTINATION, 108 None) 109 self._task_helper.run(self._save_rules, rules) 110 except Exception as e: 111 Logger.error("AdContentBlocker::__on_load_uri_content(): %s", e) 112