remove plugin preference page properly, handle downloads/timeouts better, fixed inf download loop

This commit is contained in:
Mark Stahler 2008-03-10 22:12:31 +00:00
commit 87e7fd5869
3 changed files with 89 additions and 78 deletions

View file

@ -33,14 +33,12 @@
# this exception statement from your version. If you delete this exception # this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here. # statement from all source files in the program, then also delete it here.
import deluge.component
from torrentblocklist import TorrentBlockList from torrentblocklist import TorrentBlockList
from deluge.log import LOG as log from deluge.log import LOG as log
from deluge.plugins.corepluginbase import CorePluginBase from deluge.plugins.corepluginbase import CorePluginBase
class Core(CorePluginBase): class Core(CorePluginBase):
def enable(self): def enable(self):
deluge.component.get("Core").session.set_max_connections(0)
self.blocklist = TorrentBlockList(self.plugin) self.blocklist = TorrentBlockList(self.plugin)
self.plugin.register_hook("post_session_load", self._post_session_load) self.plugin.register_hook("post_session_load", self._post_session_load)
log.debug('Blocklist: Plugin enabled..') log.debug('Blocklist: Plugin enabled..')

View file

@ -71,6 +71,7 @@ class GtkUI(ui.UI):
def disable(self): def disable(self):
deluge.component.get("StatusBar").remove_item(self.blocklist_status) deluge.component.get("StatusBar").remove_item(self.blocklist_status)
self.plugin.deregister_hook("on_apply_prefs", self.apply_prefs) self.plugin.deregister_hook("on_apply_prefs", self.apply_prefs)
self.plugin.remove_preferences_page("Blocklist")
def get_pixmap(self, fname): def get_pixmap(self, fname):
"""Returns a pixmap file included with plugin""" """Returns a pixmap file included with plugin"""

View file

@ -42,8 +42,9 @@
import urllib2, httplib, socket, os, datetime, sys import urllib2, httplib, socket, os, datetime, sys
import deluge.common import deluge.common
import deluge.component # for libtorrent session reference to change connection number import deluge.component # for libtorrent session reference to change connection number
import deluge.configmanager # used to retrieve max_global_connections
from deluge.log import LOG as log from deluge.log import LOG as log
import ui # added by Mark for pausing torrents #import ui # added by Mark for pausing torrents
from peerguardian import PGReader, PGException from peerguardian import PGReader, PGException
from text import TextReader, GZMuleReader, PGZip from text import TextReader, GZMuleReader, PGZip
@ -76,8 +77,7 @@ class HTTPConnection(httplib.HTTPConnection):
self.timeout = timeout self.timeout = timeout
def connect(self): def connect(self):
"""Override HTTPConnection.connect to connect to """Override HTTPConnection.connect to connect to host/port specified in __init__."""
host/port specified in __init__."""
msg = "getaddrinfo returns an empty list" msg = "getaddrinfo returns an empty list"
for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
@ -114,32 +114,28 @@ class HTTPHandler(urllib2.HTTPHandler):
return self.do_open(makeConnection, req) return self.do_open(makeConnection, req)
class TorrentBlockList: class TorrentBlockList:
def __init__(self, coreplugin): def __init__(self, coreplugin):
self.plugin = coreplugin # reference from plugin core self.plugin = coreplugin # reference from plugin core
log.info('Blocklist: TorrentBlockList instantiated') log.info('Blocklist: TorrentBlockList instantiated')
self.config = deluge.configmanager.ConfigManager("blocklist.conf", BLOCKLIST_PREFS) self.config = deluge.configmanager.ConfigManager("blocklist.conf", BLOCKLIST_PREFS)
self.curr = 0 self.curr = 0
self.load_options() self.load_options()
# Make sure we have a current block list file locally # Make sure we have a current block list file locally
self.fetch = False self.fetch = False
self.local_blocklist = deluge.common.get_config_dir("blocklist.cache") self.local_blocklist = deluge.common.get_config_dir("blocklist.cache")
# Check list for modifications from online version # Check list for modifications from online version
self.check_update() self.check_update()
# Initialize download attempt
self.attempt = 0
if self.fetch == True: if self.fetch == True:
self.download() self.download()
log.debug('Blocklist: TorrentBlockList Constructor finished') log.debug('Blocklist: TorrentBlockList Constructor finished')
def load_options(self): def load_options(self):
#self.config.load()
# Fill variables with settings from block list configuration file # Fill variables with settings from block list configuration file
self.url = self.config['url'] self.url = self.config['url']
self.listtype = self.config['listtype'] self.listtype = self.config['listtype']
@ -147,12 +143,12 @@ class TorrentBlockList:
self.load_on_start = self.config['load_on_start'] self.load_on_start = self.config['load_on_start']
self.timeout = self.config['timeout'] self.timeout = self.config['timeout']
self.try_times = self.config['try_times'] self.try_times = self.config['try_times']
self.old_url = self.url self.old_url = self.url
self.old_listtype = self.listtype self.old_listtype = self.listtype
socket.setdefaulttimeout(self.timeout) socket.setdefaulttimeout(self.timeout)
def set_options(self, options): def set_options(self, options):
log.info('Blocklist: Options saved...') log.info('Blocklist: Options saved...')
self.config.set('url', options['url']) self.config.set('url', options['url'])
@ -165,26 +161,26 @@ class TorrentBlockList:
self.config.save() self.config.save()
# Load newly set options to core plugin # Load newly set options to core plugin
self.load_options() self.load_options()
def check_update(self, force_check=False): def check_update(self, force_check=False):
log.info('Blocklist: Checking for updates') log.info('Blocklist: Checking for updates')
try: try:
# Check current block lists time stamp and decide if it needs to be replaced # Check current block lists time stamp and decide if it needs to be replaced
list_stats = os.stat(self.local_blocklist) list_stats = os.stat(self.local_blocklist)
list_time = datetime.datetime.fromtimestamp(list_stats.st_mtime) list_time = datetime.datetime.fromtimestamp(list_stats.st_mtime)
list_size = list_stats.st_size list_size = list_stats.st_size
current_time = datetime.datetime.today() current_time = datetime.datetime.today()
except: except:
self.fetch = True self.fetch = True
return return
# If local blocklist file exists but nothing is in it # If local blocklist file exists but nothing is in it
if list_size == 0: if list_size == 0:
self.fetch = True self.fetch = True
return return
if current_time >= (list_time + datetime.timedelta(self.check_after_days)): if current_time >= (list_time + datetime.timedelta(self.check_after_days)):
check_newer = True check_newer = True
log.debug('Blocklist: List may need to be replaced') log.debug('Blocklist: List may need to be replaced')
@ -194,29 +190,36 @@ class TorrentBlockList:
# If the program decides it is time to get a new list # If the program decides it is time to get a new list
if check_newer == True or force_check == True: if check_newer == True or force_check == True:
log.debug('Blocklist: Attempting check') log.debug('Blocklist: Attempting check')
j = 0 # counter for loop j = 0 # counter for loop
while j < self.try_times: while j < self.try_times:
# Get current online block lists time stamp and compare it with current # Get current online block lists time stamp and compare it with current
try: try:
http_handler = HTTPHandler(timeout = 15) http_handler = HTTPHandler(timeout = self.timeout)
opener = urllib2.build_opener(http_handler) opener = urllib2.build_opener(http_handler)
request = urllib2.Request(self.url) request = urllib2.Request(self.url)
try: try:
new_listinfo = opener.open(request) # Can Raise URLError new_listinfo = opener.open(request) # Can Raise URLError
header = new_listinfo.info() header = new_listinfo.info()
remote_size = int(header['content-length']) remote_size = int(header['content-length'])
remote_time = datetime.datetime.strptime(header['last-modified'],"%a, %d %b %Y %H:%M:%S GMT") remote_time = datetime.datetime.strptime(header['last-modified'],"%a, %d %b %Y %H:%M:%S GMT")
remote_type = header['content-type'] remote_type = header['content-type']
except URLError, e:
log.warning("Blocklist: Requesnt online blocklist info failed")
j += 1
break
except Exception, e: except Exception, e:
log.warning(e) log.warning(e)
# HANDLE EXCEPTOIN # HANDLE EXCEPTOIN
j = self.try_times
break
log.debug(self.listtype) log.debug(self.listtype)
# check expected list type # check expected list type
if self.listtype == "spzip": if self.listtype == "spzip":
list_type = "application/zip" list_type = "application/zip"
@ -224,7 +227,7 @@ class TorrentBlockList:
list_type = "application/x-gzip" list_type = "application/x-gzip"
else: else:
list_type = "text/html" list_type = "text/html"
# Print remote file information and local # Print remote file information and local
log.debug('Blocklist: remote') log.debug('Blocklist: remote')
log.debug(remote_type) log.debug(remote_type)
@ -234,7 +237,7 @@ class TorrentBlockList:
log.debug(list_type) log.debug(list_type)
log.debug(list_time) log.debug(list_time)
log.debug(list_size) log.debug(list_size)
# Compare MIME types of local and remote list # Compare MIME types of local and remote list
if list_type == remote_type: if list_type == remote_type:
log.info('Blocklist: Remote and Local have the same list type') log.info('Blocklist: Remote and Local have the same list type')
@ -242,70 +245,79 @@ class TorrentBlockList:
if list_time < remote_time or list_size != remote_size: if list_time < remote_time or list_size != remote_size:
self.fetch = True self.fetch = True
log.info('Blocklist: Local blocklist list is out of date') log.info('Blocklist: Local blocklist list is out of date')
else: else:
self.fetch = False self.fetch = False
log.info('Blocklist: Local block list is up to date') log.info('Blocklist: Local block list is up to date')
return return
j+=1 j+=1
log.debug('Blocklist: 6 TRY AGAIN FOO') log.debug('Blocklist: TRY AGAIN FOO')
# Connection can't be made to check remote time stamps # Connection can't be made to check remote time stamps
except: # && urllib2.URLError except: # && urllib2.URLError
log.debug('Blocklist: Connection to remote server timed out') log.debug('Blocklist: Connection to remote server timed out')
self.fetch = False self.fetch = False
j+=1 j+=1
else: else:
log.info('Blocklist: Not enough time has passed to check for a new list') log.info('Blocklist: Not enough time has passed to check for a new list')
return return
def download(self): def download(self):
log.info('Blocklist: Beginning download') log.info('Blocklist: Beginning download')
self.attempt += 1
i = 0 i = 0
while i < self.try_times: success = False
while i < self.try_times or success == False:
# Download a new block list # Download a new block list
try: try:
log.info('Blocklist: Downloading new list...') log.info('Blocklist: Downloading new list...')
http_handler = HTTPHandler(timeout = 15) http_handler = HTTPHandler(timeout = self.timeout)
opener = urllib2.build_opener(http_handler) opener = urllib2.build_opener(http_handler)
request = urllib2.Request(self.url) request = urllib2.Request(self.url)
new_list = opener.open(request) new_list = opener.open(request)
file = open(deluge.common.get_config_dir("blocklist.cache"), 'w') file = open(deluge.common.get_config_dir("blocklist.cache"), 'w')
log.info('Blocklist: Writing blocklist to disk')
# Write new blocklist to disk
while 1: while 1:
data = new_list.read() data = new_list.read()
if not len(data): if not len(data):
break break
file.write(data) file.write(data)
file.close() file.close()
except OSError, e: except OSError, e:
log.debug('Blocklist: Unable to write blocklist file') log.debug('Blocklist: Unable to write blocklist file')
return return
except: except:
if self.attempt > self.try_times: if i > self.try_times:
log.warning('Blocklist: All download attempts failed') log.warning('Blocklist: All download attempts failed')
return return
else: else:
log.warning('Blocklist: Try list download again') log.warning('Blocklist: Try list download again')
i += 1 i += 1
# CHECKSUM # CHECKSUM
success = True
log.info('Blocklist: List downloaded sucessfully')
break break
# end while loop
log.info('Blocklist: List downloaded sucessfully')
# Download completed # Download completed
def import_list(self): def import_list(self):
log.info('Blocklist: Importing list...') log.info('Blocklist: Importing list...')
# During import, disable remote connections by setting max to 0
deluge.component.get("Core").session.set_max_connections(0)
#TODO: Dont need try anymore
try: try:
self.plugin.reset_ip_filter() self.plugin.reset_ip_filter()
self.curr = 0 self.curr = 0
@ -313,61 +325,61 @@ class TorrentBlockList:
except: except:
log.debug('Blocklist: Reset filter failed') log.debug('Blocklist: Reset filter failed')
pass pass
# Instantiate format class that will read the lists file format # Instantiate format class that will read the lists file format
try: try:
log.info('Blocklist: ' + str(self.listtype)) log.info('Blocklist: ' + str(self.listtype))
read_list = FORMATS[self.listtype][1](self.local_blocklist) read_list = FORMATS[self.listtype][1](self.local_blocklist)
except: except:
log.warning('Blocklist: Error: Format read error') log.warning('Blocklist: Error: Format read error')
self.reset_critical_settings() self.reset_critical_settings()
try: try:
ips = read_list.next() ips = read_list.next()
print ips
while ips: while ips:
self.plugin.block_ip_range(ips) self.plugin.block_ip_range(ips)
ips = read_list.next() ips = read_list.next()
self.curr += 1 self.curr += 1
# Progress measurement here # Progress measurement here
log.info(self.curr) log.info(self.curr)
except IOError, e: except IOError, e:
log.debug('Blocklist: Problem with list, re-download') log.debug('Blocklist: Problem with list, re-download')
return return
# Throw exception if curr = 0 reset critical settings # If experiencing an unrecoverable error, reset critical settings (url, listtype)
if self.curr == 0: if self.curr == 0:
log.warning("Blocklist: Improper list read") log.warning("Blocklist: Improper list read")
self.reset_critical_settings() self.reset_critical_settings()
else:
else: # Sucessful import
deluge.component.get("Core").session.set_max_connections(deluge.configmanager.ConfigManager("core.conf")["max_connections_global"]) deluge.component.get("Core").session.set_max_connections(deluge.configmanager.ConfigManager("core.conf")["max_connections_global"])
log.info('Blocklist: Import completed sucessfully') log.info('Blocklist: Import completed sucessfully')
def reset_critical_settings(self): def reset_critical_settings(self):
log.info('Blocklist: URL and List type reset') log.info('Blocklist: URL and List type reset')
reset_url = BACKUP_PREFS["url"] reset_url = BACKUP_PREFS["url"]
reset_listtype = BACKUP_PREFS["listtype"] reset_listtype = BACKUP_PREFS["listtype"]
log.info(reset_url) log.info(reset_url)
log.info(reset_listtype) log.info(reset_listtype)
self.config.set('url', reset_url) self.config.set('url', reset_url)
self.config.set('listtype', reset_listtype) self.config.set('listtype', reset_listtype)
self.config.save() self.config.save()
self.load_options() self.load_options()
log.info(self.url) log.info(self.url)
log.info(self.listtype) log.info(self.listtype)
self.download() self.download()
self.import_list() self.import_list()
def return_count(self): def return_count(self):
return self.curr return self.curr
def get_config_value(self, key): # url, check_after_days, listtype def get_config_value(self, key): # url, check_after_days, listtype
val = self.config[key] val = self.config[key]
log.debug('Blocklist: Get_config_val') log.debug('Blocklist: Get_config_val')