Index: abp/filters/blocks.py |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/abp/filters/blocks.py |
@@ -0,0 +1,83 @@ |
+# This file is part of Adblock Plus <https://adblockplus.org/>, |
+# Copyright (C) 2006-present eyeo GmbH |
+# |
+# Adblock Plus is free software: you can redistribute it and/or modify |
+# it under the terms of the GNU General Public License version 3 as |
+# published by the Free Software Foundation. |
+# |
+# Adblock Plus is distributed in the hope that it will be useful, |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+# GNU General Public License for more details. |
+# |
+# You should have received a copy of the GNU General Public License |
+# along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
+ |
+"""Extract blocks of filters separated by comments.""" |
+ |
+from __future__ import unicode_literals |
+ |
+import re |
+ |
+from abp.filters.parser import ParseError |
+ |
+VAR_REGEXP = re.compile(r'^:(\w+)=(.*)$') |
+ |
+ |
+class FilterBlock(object): |
+ """A block of filters. |
+ |
+ Blocks are consecutive groups of filters separated by comments. |
+ |
+ """ |
+ |
+ def __init__(self, comments, filters): |
+ self.filters = filters |
+ descr_lines = [] |
+ for comment in comments: |
+ match = VAR_REGEXP.search(comment.text) |
+ if match: |
+ name, value = match.groups() |
+ if name.startswith('_') or name in {'filters', 'description'}: |
+ raise ParseError('Invalid variable name', |
+ comment.to_string()) |
+ setattr(self, name, value) |
+ else: |
+ descr_lines.append(comment.text) |
+ self.description = '\n'.join(descr_lines) |
+ |
+ def _asdict(self): |
+ ret = dict(self.__dict__) |
+ ret['filters'] = [f._asdict() for f in ret['filters']] |
+ return ret |
+ |
+ |
+def to_blocks(parsed_lines): |
+ """Convert a sequence of parser filter list lines to blocks. |
+ |
+ Parameters |
+ ---------- |
+ parsed_lines : iterable of namedtuple |
+ Parsed filter list (see `parser.py` for details on how it's |
+ represented). |
+ |
+ Returns |
+ ------- |
+ blocks : iterable of FilterBlock. |
+ |
+ """ |
+ comments = [] |
+ filters = [] |
+ |
+ for line in parsed_lines: |
+ if line.type == 'comment': |
+ if filters: |
+ yield FilterBlock(comments, filters) |
+ comments = [] |
+ filters = [] |
+ comments.append(line) |
+ elif line.type == 'filter': |
+ filters.append(line) |
+ |
+ if filters: |
+ yield FilterBlock(comments, filters) |