OLD | NEW |
1 # This file is part of Adblock Plus <https://adblockplus.org/>, | 1 # This file is part of Adblock Plus <https://adblockplus.org/>, |
2 # Copyright (C) 2006-present eyeo GmbH | 2 # Copyright (C) 2006-present eyeo GmbH |
3 # | 3 # |
4 # Adblock Plus is free software: you can redistribute it and/or modify | 4 # Adblock Plus is free software: you can redistribute it and/or modify |
5 # it under the terms of the GNU General Public License version 3 as | 5 # it under the terms of the GNU General Public License version 3 as |
6 # published by the Free Software Foundation. | 6 # published by the Free Software Foundation. |
7 # | 7 # |
8 # Adblock Plus is distributed in the hope that it will be useful, | 8 # Adblock Plus is distributed in the hope that it will be useful, |
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 # GNU General Public License for more details. | 11 # GNU General Public License for more details. |
12 # | 12 # |
13 # You should have received a copy of the GNU General Public License | 13 # You should have received a copy of the GNU General Public License |
14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
15 | 15 |
16 """Combine filter list fragments to produce filter lists.""" | 16 """Combine filter list fragments to produce filter lists.""" |
17 | 17 |
18 from __future__ import unicode_literals | 18 from __future__ import unicode_literals |
19 | 19 |
20 import base64 | |
21 import hashlib | |
22 import itertools | 20 import itertools |
23 import logging | 21 import logging |
24 import time | 22 import time |
25 | 23 |
26 from .parser import parse_filterlist, Comment, Metadata | 24 from .parser import parse_filterlist, Comment, Metadata |
27 from .sources import NotFound | 25 from .sources import NotFound |
28 | 26 |
29 __all__ = ['IncludeError', 'MissingHeader', 'render_filterlist'] | 27 __all__ = ['IncludeError', 'MissingHeader', 'render_filterlist'] |
30 | 28 |
31 _logger = logging.getLogger(__name__) | 29 _logger = logging.getLogger(__name__) |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 if line.key not in seen: | 130 if line.key not in seen: |
133 seen.add(line.key) | 131 seen.add(line.key) |
134 yield line | 132 yield line |
135 elif line.type == 'header': | 133 elif line.type == 'header': |
136 if i == 0: | 134 if i == 0: |
137 yield line | 135 yield line |
138 else: | 136 else: |
139 yield line | 137 yield line |
140 | 138 |
141 | 139 |
142 def _insert_checksum(lines): | |
143 """Add checksum to the filter list. | |
144 | |
145 See https://adblockplus.org/filters#special-comments for description | |
146 of the checksum algorithm. | |
147 """ | |
148 md5sum = hashlib.md5() | |
149 | |
150 for line in lines: | |
151 if line.type != 'emptyline': | |
152 md5sum.update(line.to_string().encode('utf-8') + b'\n') | |
153 yield line | |
154 | |
155 checksum = base64.b64encode(md5sum.digest()).rstrip(b'=') | |
156 yield Metadata('Checksum', checksum.decode('utf-8')) | |
157 | |
158 | |
159 def _validate(lines): | 140 def _validate(lines): |
160 """Validate the final list.""" | 141 """Validate the final list.""" |
161 first_line, rest = _first_and_rest(lines) | 142 first_line, rest = _first_and_rest(lines) |
162 if first_line.type != 'header': | 143 if first_line.type != 'header': |
163 raise MissingHeader('No header found at the beginning of the input.') | 144 raise MissingHeader('No header found at the beginning of the input.') |
164 return itertools.chain([first_line], rest) | 145 return itertools.chain([first_line], rest) |
165 | 146 |
166 | 147 |
167 def render_filterlist(name, sources, top_source=None): | 148 def render_filterlist(name, sources, top_source=None): |
168 """Produce filter list from fragments. | 149 """Produce filter list from fragments. |
(...skipping 20 matching lines...) Expand all Loading... |
189 When any of the fragments contain lines that can't be parsed. | 170 When any of the fragments contain lines that can't be parsed. |
190 MissingHeader | 171 MissingHeader |
191 If the top level fragment doesn't start with a valid header. This would | 172 If the top level fragment doesn't start with a valid header. This would |
192 lead to rendering an invalid filter list, so we immediately abort. | 173 lead to rendering an invalid filter list, so we immediately abort. |
193 | 174 |
194 """ | 175 """ |
195 _logger.info('Rendering: %s', name) | 176 _logger.info('Rendering: %s', name) |
196 lines, default_source = _get_and_parse_fragment(name, sources, top_source) | 177 lines, default_source = _get_and_parse_fragment(name, sources, top_source) |
197 lines = _process_includes(sources, default_source, [name], lines) | 178 lines = _process_includes(sources, default_source, [name], lines) |
198 for proc in [_process_timestamps, _insert_version, _remove_duplicates, | 179 for proc in [_process_timestamps, _insert_version, _remove_duplicates, |
199 _insert_checksum, _validate]: | 180 _validate]: |
200 lines = proc(lines) | 181 lines = proc(lines) |
201 return lines | 182 return lines |
OLD | NEW |