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