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) |