summaryrefslogtreecommitdiffstats
path: root/deluge/plugins/Blocklist/deluge_blocklist/readers.py
diff options
context:
space:
mode:
Diffstat (limited to 'deluge/plugins/Blocklist/deluge_blocklist/readers.py')
-rw-r--r--deluge/plugins/Blocklist/deluge_blocklist/readers.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/deluge/plugins/Blocklist/deluge_blocklist/readers.py b/deluge/plugins/Blocklist/deluge_blocklist/readers.py
new file mode 100644
index 0000000..14230ed
--- /dev/null
+++ b/deluge/plugins/Blocklist/deluge_blocklist/readers.py
@@ -0,0 +1,99 @@
+#
+# Copyright (C) 2009-2010 John Garland <johnnybg+deluge@gmail.com>
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+import logging
+import re
+
+from deluge.common import decode_bytes
+
+from .common import IP, BadIP, raises_errors_as
+
+log = logging.getLogger(__name__)
+
+
+class ReaderParseError(Exception):
+ pass
+
+
+class BaseReader:
+ """Base reader for blocklist files"""
+
+ def __init__(self, _file):
+ """Creates a new BaseReader given a file"""
+ self.file = _file
+
+ def open(self):
+ """Opens the associated file for reading"""
+ return open(self.file)
+
+ def parse(self, line):
+ """Extracts ip range from given line"""
+ raise NotImplementedError
+
+ def read(self, callback):
+ """Calls callback on each ip range in the file"""
+ for start, end in self.readranges():
+ try:
+ callback(IP.parse(start), IP.parse(end))
+ except BadIP as ex:
+ log.error('Failed to parse IP: %s', ex)
+ return self.file
+
+ def is_ignored(self, line):
+ """Ignore commented lines and blank lines"""
+ line = line.strip()
+ return line.startswith('#') or not line
+
+ def is_valid(self):
+ """Determines whether file is valid for this reader"""
+ blocklist = self.open()
+ valid = True
+ for line in blocklist:
+ line = decode_bytes(line)
+ if not self.is_ignored(line):
+ try:
+ (start, end) = self.parse(line)
+ if not re.match(r'^(\d{1,3}\.){4}$', start + '.') or not re.match(
+ r'^(\d{1,3}\.){4}$', end + '.'
+ ):
+ valid = False
+ except Exception:
+ valid = False
+ break
+ blocklist.close()
+ return valid
+
+ @raises_errors_as(ReaderParseError)
+ def readranges(self):
+ """Yields each ip range from the file"""
+ blocklist = self.open()
+ for line in blocklist:
+ line = decode_bytes(line)
+ if not self.is_ignored(line):
+ yield self.parse(line)
+ blocklist.close()
+
+
+class EmuleReader(BaseReader):
+ """Blocklist reader for emule style blocklists"""
+
+ def parse(self, line):
+ return line.strip().split(' , ')[0].split(' - ')
+
+
+class SafePeerReader(BaseReader):
+ """Blocklist reader for SafePeer style blocklists"""
+
+ def parse(self, line):
+ return line.strip().split(':')[-1].split('-')
+
+
+class PeerGuardianReader(SafePeerReader):
+ """Blocklist reader for PeerGuardian style blocklists"""
+
+ pass