| Index: abp/filters/fldiff.py |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/abp/filters/fldiff.py |
| @@ -0,0 +1,74 @@ |
| +# This file is part of the Adblock Plus web scripts, |
| +# 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/>. |
| + |
| +"""Generate a diff between two filter lists.""" |
| + |
| +import re |
| + |
| +from .renderer import _insert_checksum |
| + |
| + |
| +def generate_diff(base, latest): |
| + """Return a diff between two filter lists.""" |
| + # Collect the special comments |
| + diff = '[Adblock Plus Diff 2.0]\n' |
| + sp_comment = re.compile(r'!\s(.*):\s(.*)') |
| + latest_fl = set() |
| + latest_md = set() |
| + latest_keys = set() |
| + base_fl = set() |
| + base_md = set() |
| + base_keys = set() |
| + for line in latest.splitlines(): |
| + m = sp_comment.match(line) |
| + if m: |
| + latest_md.add(line) |
| + latest_keys.add(m.groups()[0]) |
| + elif not line.startswith('!'): |
| + latest_fl.add(line.strip()) |
| + |
| + # Get the diff between the rest of the lines |
| + for line in base.splitlines(): |
| + if not line.startswith('!'): |
| + base_fl.add(line.strip()) |
| + else: |
| + m = sp_comment.match(line) |
| + if m: |
| + base_md.add(line) |
| + base_keys.add(m.groups()[0]) |
| + new_md = latest_md - base_md |
| + removed_keys = base_keys - latest_keys |
| + add_fl = latest_fl - base_fl |
| + remove_fl = base_fl - latest_fl |
| + for item in new_md: |
| + diff += item + '\n' |
| + for key in removed_keys: |
| + # If a special comment has been removed, enter it with a blank value |
| + # sp the client will set it back to the default value |
| + diff += '! {}:\n'.format(key) |
| + for item in add_fl: |
| + diff += '+ {}\n'.format(item) |
| + for item in remove_fl: |
| + diff += '- {}\n'.format(item) |
| + |
| + # Add the checksum |
| + _insert_checksum(diff) |
| + return diff |
| + |
| + |
| +def publish_diff(diff, outfile): |
| + """Write the diff to the outfile.""" |
| + with open(outfile, 'w+') as outfile: |
| + outfile.write(diff) |