From ba91b6e587d2b43f3d47905bd55a43c657937858 Mon Sep 17 00:00:00 2001 From: John Garland Date: Wed, 15 Jul 2009 14:00:57 +0000 Subject: [PATCH] Updated imports. Added decompresser and reader dicts. Make import_list actually import list into libtorrent session. Begin auto-detection of blocklists. --- deluge/plugins/blocklist/blocklist/core.py | 75 ++++++++++++++++--- deluge/plugins/blocklist/blocklist/detect.py | 53 +++++++++++++ deluge/plugins/blocklist/blocklist/readers.py | 2 + 3 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 deluge/plugins/blocklist/blocklist/detect.py diff --git a/deluge/plugins/blocklist/blocklist/core.py b/deluge/plugins/blocklist/blocklist/core.py index 937ccbd2f..a5166f3a7 100644 --- a/deluge/plugins/blocklist/blocklist/core.py +++ b/deluge/plugins/blocklist/blocklist/core.py @@ -39,7 +39,7 @@ import datetime import shutil from twisted.internet.task import LoopingCall -from twisted.internet import reactor, threads, defer +from twisted.internet import threads, defer from twisted.web import error from deluge.log import LOG as log @@ -48,6 +48,19 @@ import deluge.component as component import deluge.configmanager from deluge.core.rpcserver import export from deluge.httpdownloader import download_file +from decompressers import Zipped, GZipped, BZipped2 +from readers import EmuleReader, SafePeerReader, PeerGuardianReader +from detect import detect_compression, detect_format, UnknownFormatError + +try: + import deluge.libtorrent as lt +except ImportError: + import libtorrent as lt + if not (lt.version_major == 0 and lt.version_minor == 14): + raise ImportError("This version of Deluge requires libtorrent 0.14!") + +# TODO: check return values for deferred callbacks +# TODO: review class attributes for redundancy DEFAULT_PREFS = { "url": "http://deluge-torrent.org/blocklist/nipfilter.dat.gz", @@ -61,6 +74,23 @@ DEFAULT_PREFS = { "try_times": 3, } +DECOMPRESSERS = { + "Zip" : Zipped, + "GZip" : GZipped, + "BZip2" : BZipped2 +} + +READERS = { + "Emule" : EmuleReader, + "SafePeer" : SafePeerReader, + "PeerGuardian" : PeerGuardianReader +} + +# Libtorrent IP filter constants +START = 0 +END = 1 +BLOCK = 1 + class Core(CorePluginBase): def enable(self): log.debug('Blocklist: Plugin enabled..') @@ -71,13 +101,15 @@ class Core(CorePluginBase): self.up_to_date = False self.num_blocked = 0 self.file_progress = 0.0 - self.reader = None self.core = component.get("Core") + self.config = deluge.configmanager.ConfigManager("blocklist.conf", DEFAULT_PREFS) + + self.reader = READERS.get(self.config["list_type"]) + if self.config["list_compression"]: + self.reader = DECOMPRESSERS.get(self.config["list_compression"])(self.reader) update_now = False - - self.config = deluge.configmanager.ConfigManager("blocklist.conf", DEFAULT_PREFS) if self.config["load_on_start"]: if self.config["last_update"]: now = datetime.datetime.now() @@ -231,22 +263,34 @@ class Core(CorePluginBase): def import_list(self, force=False): """Imports the downloaded blocklist into the session""" def on_read_ip_range(ip_range): - # TODO: add to lt session + self.blocklist.add_rule(ip_range[START], ip_range[END], BLOCK) self.num_blocked += 1 - if self.use_cache and self.has_imported: + def on_finish_read(result): + # Add blocklist to session + self.core.session.set_ip_filter(self.blocklist) + + # TODO: double check logic + if self.up_to_date and self.has_imported: log.debug("Latest blocklist is already imported") - return True + return defer.succeed(None) self.is_importing = True self.num_blocked = 0 + self.blocklist = lt.ip_filter() + + if self.use_cache: + blocklist = deluge.configmanager.get_config_dir("blocklist.cache") + else: + blocklist = deluge.configmanager.get_config_dir("blocklist.download") if not self.reader: - # TODO: auto-detect reader - pass + self.auto_detect(blocklist) - #return threads.deferToThread(self.reader.read(on_read_ip_range)) - return defer.succeed(None) + d = threads.deferToThread(self.reader(blocklist).read(on_read_ip_range)) + d.addCallback(on_finish_read) + + return d def on_import_complete(self, result): """Runs any import clean up functions""" @@ -264,6 +308,8 @@ class Core(CorePluginBase): def on_import_error(self, f): """Recovers from import error""" + # TODO: catch invalid / corrupt list error + # and reset self.reader d = None self.is_importing = False blocklist = deluge.configmanager.get_config_dir("blocklist.cache") @@ -274,3 +320,10 @@ class Core(CorePluginBase): d = self.import_list() d.addCallbacks(self.on_import_complete, self.on_import_error) return d + + def auto_detect(self, blocklist): + self.config["list_compression"] = detect_compression(blocklist) + self.config["list_type"] = detect_format(blocklist) + if not self.config["list_type"]: + self.config["list_compression"] = "" + raise UnknownFormatError diff --git a/deluge/plugins/blocklist/blocklist/detect.py b/deluge/plugins/blocklist/blocklist/detect.py new file mode 100644 index 000000000..9086bae09 --- /dev/null +++ b/deluge/plugins/blocklist/blocklist/detect.py @@ -0,0 +1,53 @@ +# +# detect.py +# +# Copyright (C) 2009 John Garland +# +# Deluge is free software. +# +# You may redistribute it and/or modify it under the terms of the +# GNU General Public License, as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) +# any later version. +# +# deluge 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 deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# +# In addition, as a special exception, the copyright holders give +# permission to link the code of portions of this program with the OpenSSL +# library. +# You must obey the GNU General Public License in all respects for all of +# the code used other than OpenSSL. If you modify file(s) with this +# exception, you may extend this exception to your version of the file(s), +# but you are not obligated to do so. If you do not wish to do so, delete +# this exception statement from your version. If you delete this exception +# statement from all source files in the program, then also delete it here. +# +# + +COMPRESSION_TYPES = { + "PK" : "zip", + "\x1f\x8b" : "gzip", + "BZ" : "bzip2" +} + +class UnknownFormatError(Exception): + pass + +def detect_compression(filename): + f = open(filename, "rb") + magic_number = f.read(2) + f.close() + return COMPRESSION_TYPES.get(magic_number, "") + +def detect_format(filename): + # TODO: implement this function + return "" diff --git a/deluge/plugins/blocklist/blocklist/readers.py b/deluge/plugins/blocklist/blocklist/readers.py index dc72ada1c..8a51008fc 100644 --- a/deluge/plugins/blocklist/blocklist/readers.py +++ b/deluge/plugins/blocklist/blocklist/readers.py @@ -35,6 +35,8 @@ from deluge.log import LOG as log +# TODO: Create exception classes to be raised + class BaseReader(object): """Base reader for blocklist files""" def __init__(self, file):