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 14 15import json 16 17from eolie.define import EOLIE_DATA_PATH 18from eolie.logger import Logger 19 20 21class ContentBlockerExceptions: 22 """ 23 Exception handler 24 """ 25 __JSON_PATH = "%s/content_blocker_json" % EOLIE_DATA_PATH 26 27 def __init__(self, name): 28 """ 29 Init constructor 30 """ 31 try: 32 self.__name = name 33 self.__rules = [] 34 f = Gio.File.new_for_path( 35 "%s/exceptions_%s.json" % (self.__JSON_PATH, self.__name)) 36 if f.query_exists(): 37 (status, contents, tag) = f.load_contents(None) 38 if status: 39 self.__rules = json.loads(contents.decode("utf-8")) 40 except Exception as e: 41 Logger.error("AdblockExceptions::__init__(): %s", e) 42 43 def save(self): 44 """ 45 Save rules to disk 46 """ 47 try: 48 f = Gio.File.new_for_path( 49 "%s/exceptions_%s.json" % (self.__JSON_PATH, self.__name)) 50 content = json.dumps(self.__rules) 51 f.replace_contents(content.encode("utf-8"), 52 None, 53 False, 54 Gio.FileCreateFlags.REPLACE_DESTINATION, 55 None) 56 except Exception as e: 57 Logger.error("AdblockExceptions::save(): %s", e) 58 59 def add_domain_exception(self, domain, url_filter=".*", internal=False): 60 """ 61 Add an exception for domain 62 @param domain as str 63 @param url_filter as str 64 @param internal as bool 65 """ 66 if internal: 67 rule = self.__get_rule_for_internal_domain(domain, url_filter) 68 if rule in self.__rules: 69 self.__rules.remove(rule) 70 else: 71 rule = self.__get_rule_for_domain(domain, url_filter) 72 self.__rules.append(rule) 73 74 def remove_domain_exception(self, domain, url_filter=".*", internal=False): 75 """ 76 Remove an exception for domain 77 @param domain as str 78 @param url_filter as str 79 @param internal as bool 80 """ 81 if internal: 82 rule = self.__get_rule_for_internal_domain(domain, url_filter) 83 self.__rules.append(rule) 84 else: 85 rule = self.__get_rule_for_domain(domain, url_filter) 86 if rule in self.__rules: 87 self.__rules.remove(rule) 88 89 def remove_all_domain_exceptions(self, domain): 90 """ 91 Remove all exceptions for a domain 92 @param domain as str 93 """ 94 for rule in list(self.__rules): 95 if rule["trigger"]["if-domain"] == ["*%s" % domain]: 96 self.remove_domain_exception( 97 domain, rule["trigger"]["url-filter"]) 98 99 def is_domain_exception(self, domain, url_filter=".*", internal=False): 100 """ 101 True if domain exception exists 102 @parma domain as str 103 @param url_filter as str 104 @param internal as bool 105 @return bool 106 """ 107 if internal: 108 rule = self.__get_rule_for_internal_domain(domain, url_filter) 109 return rule not in self.__rules 110 else: 111 rule = self.__get_rule_for_domain(domain, url_filter) 112 return rule in self.__rules 113 114 @property 115 def rules(self): 116 """ 117 Get rules 118 @return [] 119 """ 120 return self.__rules 121 122####################### 123# PRIVATE # 124####################### 125 def __get_rule_for_domain(self, domain, url_filter): 126 """ 127 Return rule for domain 128 @param domain as str 129 @param url_filter as str 130 @return {} 131 """ 132 value = "*%s" % domain 133 return { 134 "trigger": { 135 "url-filter": url_filter, 136 "if-domain": [value] 137 }, 138 "action": { 139 "type": "ignore-previous-rules" 140 } 141 } 142 143 def __get_rule_for_internal_domain(self, domain, url_filter): 144 """ 145 Return rule for domain 146 @param domain as str 147 @param url_filter as str 148 @return {} 149 """ 150 value = "*%s" % domain 151 return { 152 "trigger": { 153 "url-filter": url_filter, 154 "if-domain": [value] 155 }, 156 "action": { 157 "type": "block" 158 } 159 } 160