src/eric7/WebBrowser/AdBlock/AdBlockSearchTree.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2017 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the AdBlock search tree.
8 """
9
10 from .AdBlockRule import AdBlockRuleType
11
12
13 class AdBlockSearchTreeNode:
14 """
15 Class implementing the AdBlock search tree node.
16 """
17 def __init__(self):
18 """
19 Constructor
20 """
21 self.char = ''
22 self.rule = None
23 self.children = {}
24
25
26 class AdBlockSearchTree:
27 """
28 Class implementing the AdBlock search tree.
29 """
30 def __init__(self):
31 """
32 Constructor
33 """
34 self.__root = AdBlockSearchTreeNode()
35
36 def clear(self):
37 """
38 Public method to clear the search tree.
39 """
40 self.__deleteNode(self.__root)
41 self.__root = AdBlockSearchTreeNode()
42
43 def add(self, rule):
44 """
45 Public method to add a rule to the search tree.
46
47 @param rule rule to be added
48 @type AdBlockRule
49 @return flag indicating a successful addition
50 @rtype bool
51 """
52 if rule.ruleType() != AdBlockRuleType.StringContainsMatchRule:
53 return False
54
55 filterString = rule.matchString()
56
57 if len(filterString) <= 0:
58 return False
59
60 node = self.__root
61
62 for filterChar in filterString:
63 try:
64 nextNode = node.children[filterChar]
65 except KeyError:
66 nextNode = AdBlockSearchTreeNode()
67 nextNode.char = filterChar
68 node.children[filterChar] = nextNode
69 node = nextNode
70
71 node.rule = rule
72
73 return True
74
75 def find(self, request, domain, urlString):
76 """
77 Public method to find a matching rule.
78
79 @param request URL request to be matched
80 @type QWebEngineUrlRequestInfo
81 @param domain domain of the URL
82 @type str
83 @param urlString requested URL as a lowercase string
84 @type str
85 @return reference to the matched rule
86 @rtype AdBlockRule
87 """
88 length = len(urlString)
89
90 if length <= 0:
91 return None
92
93 for index in range(length):
94 rule = self.__prefixSearch(request, domain, urlString,
95 urlString[index:], length - index)
96 if rule:
97 return rule
98
99 return None
100
101 def __deleteNode(self, node):
102 """
103 Private method to delete a search tree node.
104
105 @param node reference to the node to be deleted
106 @type AdBlockSearchTreeNode
107 """
108 if not node:
109 return
110
111 for key in node.children:
112 self.__deleteNode(node.children[key])
113
114 node.children = {}
115 node = None
116
117 def __prefixSearch(self, request, domain, urlString, string, length):
118 """
119 Private method to perform a prefix search.
120
121 @param request URL request to be matched
122 @type QWebEngineUrlRequestInfo
123 @param domain domain of the URL
124 @type str
125 @param urlString requested URL as a lowercase string
126 @type str
127 @param string prefix string to search for
128 @type str
129 @param length length to be considered
130 @type int
131 @return reference to the matched rule
132 @rtype AdBlockRule
133 """
134 if length <= 0:
135 return None
136
137 char = string[0]
138
139 try:
140 node = self.__root.children[char]
141 except KeyError:
142 return None
143
144 for char in string[1:]:
145 if (
146 node.rule and
147 node.rule.networkMatch(request, domain, urlString)
148 ):
149 return node.rule
150
151 try:
152 node = node.children[char]
153 except KeyError:
154 return None
155
156 if node.rule and node.rule.networkMatch(request, domain, urlString):
157 return node.rule
158
159 return None

eric ide

mercurial