Browse Source

More pep8 non-agressive fixes.

pull/346/head
Jonathon Saine 10 years ago
parent
commit
cc0b15eb46
  1. 4
      SABHelper.py
  2. 530
      sabnzbd/api.py
  3. 4
      sabnzbd/bpsmeter.py
  4. 22
      sabnzbd/cfg.py
  5. 83
      sabnzbd/config.py
  6. 29
      sabnzbd/constants.py
  7. 29
      sabnzbd/utils/diskspeed.py
  8. 4
      sabnzbd/utils/getipaddress.py
  9. 2
      sabnzbd/utils/getperformance.py
  10. 34
      sabnzbd/utils/happyeyeballs.py
  11. 7
      sabnzbd/utils/servertests.py
  12. 34
      sabnzbd/utils/systrayiconthread.py
  13. 5
      sabnzbd/utils/upload.py

4
SABHelper.py

@ -102,8 +102,6 @@ def main():
############################################################################## ##############################################################################
# Windows Service Support # Windows Service Support
############################################################################## ##############################################################################
import servicemanager import servicemanager
@ -152,8 +150,6 @@ class SABHelper(win32serviceutil.ServiceFramework):
############################################################################## ##############################################################################
# Platform specific startup code # Platform specific startup code
############################################################################## ##############################################################################
if __name__ == '__main__': if __name__ == '__main__':
win32serviceutil.HandleCommandLine(SABHelper, argv=sys.argv) win32serviceutil.HandleCommandLine(SABHelper, argv=sys.argv)

530
sabnzbd/api.py

File diff suppressed because it is too large

4
sabnzbd/bpsmeter.py

@ -253,8 +253,7 @@ class BPSMeter(object):
# Speedometer # Speedometer
try: try:
self.bps = (self.bps * (self.last_update - self.start_time) self.bps = (self.bps * (self.last_update - self.start_time) + amount) / (t - self.start_time)
+ amount) / (t - self.start_time)
except: except:
self.bps = 0.0 self.bps = 0.0
@ -406,7 +405,6 @@ class BPSMeter(object):
# The <day> and <hh:mm> part can both be optional # The <day> and <hh:mm> part can both be optional
__re_day = re.compile('^\s*(\d+)[^:]*') __re_day = re.compile('^\s*(\d+)[^:]*')
__re_hm = re.compile('(\d+):(\d+)\s*$') __re_hm = re.compile('(\d+):(\d+)\s*$')
def get_quota(self): def get_quota(self):
""" If quota active, return check-function, hour, minute """ """ If quota active, return check-function, hour, minute """
if self.have_quota: if self.have_quota:

22
sabnzbd/cfg.py

@ -30,9 +30,9 @@ from sabnzbd.config import OptionBool, OptionNumber, OptionPassword, \
validate_octal, validate_safedir, validate_dir_exists, \ validate_octal, validate_safedir, validate_dir_exists, \
create_api_key, validate_notempty create_api_key, validate_notempty
#------------------------------------------------------------------------------ ##############################################################################
# Email validation support # Email validation support
# ##############################################################################
RE_VAL = re.compile('[^@ ]+@[^.@ ]+\.[^.@ ]') RE_VAL = re.compile('[^@ ]+@[^.@ ]+\.[^.@ ]')
def validate_email(value): def validate_email(value):
global email_endjob, email_full, email_rss global email_endjob, email_full, email_rss
@ -55,15 +55,14 @@ def validate_server(value):
else: else:
return None, value return None, value
#------------------------------------------------------------------------------
if sabnzbd.WIN32: if sabnzbd.WIN32:
DEF_FOLDER_MAX = 128 DEF_FOLDER_MAX = 128
else: else:
DEF_FOLDER_MAX = 256 DEF_FOLDER_MAX = 256
#------------------------------------------------------------------------------ ##############################################################################
# Configuration instances # Configuration instances
# ##############################################################################
quick_check = OptionBool('misc', 'quick_check', True) quick_check = OptionBool('misc', 'quick_check', True)
sfv_check = OptionBool('misc', 'sfv_check', True) sfv_check = OptionBool('misc', 'sfv_check', True)
@ -181,12 +180,12 @@ configlock = OptionBool('misc', 'config_lock', 0)
umask = OptionStr('misc', 'permissions', '', validation=validate_octal) umask = OptionStr('misc', 'permissions', '', validation=validate_octal)
download_dir = OptionDir('misc', 'download_dir', DEF_DOWNLOAD_DIR, create=False, validation=validate_safedir) download_dir = OptionDir('misc', 'download_dir', DEF_DOWNLOAD_DIR, create=False, validation=validate_safedir)
download_free = OptionStr('misc', 'download_free') download_free = OptionStr('misc', 'download_free')
complete_dir = OptionDir('misc', 'complete_dir', DEF_COMPLETE_DIR, create=False, \ complete_dir = OptionDir('misc', 'complete_dir', DEF_COMPLETE_DIR, create=False,
apply_umask=True, validation=validate_notempty) apply_umask=True, validation=validate_notempty)
script_dir = OptionDir('misc', 'script_dir', create=True, writable=False) script_dir = OptionDir('misc', 'script_dir', create=True, writable=False)
nzb_backup_dir = OptionDir('misc', 'nzb_backup_dir', DEF_NZBBACK_DIR) nzb_backup_dir = OptionDir('misc', 'nzb_backup_dir', DEF_NZBBACK_DIR)
admin_dir = OptionDir('misc', 'admin_dir', DEF_ADMIN_DIR, validation=validate_safedir) admin_dir = OptionDir('misc', 'admin_dir', DEF_ADMIN_DIR, validation=validate_safedir)
#log_dir = OptionDir('misc', 'log_dir', 'logs') # log_dir = OptionDir('misc', 'log_dir', 'logs')
dirscan_dir = OptionDir('misc', 'dirscan_dir', create=False) dirscan_dir = OptionDir('misc', 'dirscan_dir', create=False)
dirscan_speed = OptionNumber('misc', 'dirscan_speed', DEF_SCANRATE, 0, 3600) dirscan_speed = OptionNumber('misc', 'dirscan_speed', DEF_SCANRATE, 0, 3600)
size_limit = OptionStr('misc', 'size_limit', '0') size_limit = OptionStr('misc', 'size_limit', '0')
@ -212,7 +211,7 @@ login_realm = OptionStr('misc', 'login_realm', 'SABnzbd')
bandwidth_perc = OptionNumber('misc', 'bandwidth_perc', 0, 0, 100) bandwidth_perc = OptionNumber('misc', 'bandwidth_perc', 0, 0, 100)
bandwidth_max = OptionStr('misc', 'bandwidth_max') bandwidth_max = OptionStr('misc', 'bandwidth_max')
refresh_rate = OptionNumber('misc', 'refresh_rate', 0) refresh_rate = OptionNumber('misc', 'refresh_rate', 0)
rss_rate = OptionNumber('misc', 'rss_rate', 60, 15, 24*60) rss_rate = OptionNumber('misc', 'rss_rate', 60, 15, 24 * 60)
cache_limit = OptionStr('misc', 'cache_limit') cache_limit = OptionStr('misc', 'cache_limit')
web_dir = OptionStr('misc', 'web_dir', DEF_STDINTF) web_dir = OptionStr('misc', 'web_dir', DEF_STDINTF)
web_dir2 = OptionStr('misc', 'web_dir2') web_dir2 = OptionStr('misc', 'web_dir2')
@ -234,7 +233,7 @@ log_new = OptionBool('logging', 'log_new', False)
https_cert = OptionDir('misc', 'https_cert', 'server.cert', create=False) https_cert = OptionDir('misc', 'https_cert', 'server.cert', create=False)
https_key = OptionDir('misc', 'https_key', 'server.key', create=False) https_key = OptionDir('misc', 'https_key', 'server.key', create=False)
https_chain = OptionDir('misc','https_chain', create=False) https_chain = OptionDir('misc', 'https_chain', create=False)
enable_https = OptionBool('misc', 'enable_https', False) enable_https = OptionBool('misc', 'enable_https', False)
language = OptionStr('misc', 'language', 'en') language = OptionStr('misc', 'language', 'en')
@ -365,9 +364,9 @@ warn_dupl_jobs = OptionBool('misc', 'warn_dupl_jobs', True)
new_nzb_on_failure = OptionBool('misc', 'new_nzb_on_failure', False) new_nzb_on_failure = OptionBool('misc', 'new_nzb_on_failure', False)
#------------------------------------------------------------------------------ ##############################################################################
# Set root folders for Folder config-items # Set root folders for Folder config-items
# ##############################################################################
def set_root_folders(home, lcldata): def set_root_folders(home, lcldata):
email_dir.set_root(home) email_dir.set_root(home)
download_dir.set_root(home) download_dir.set_root(home)
@ -379,6 +378,7 @@ def set_root_folders(home, lcldata):
log_dir.set_root(lcldata) log_dir.set_root(lcldata)
password_file.set_root(home) password_file.set_root(home)
def set_root_folders2(): def set_root_folders2():
https_cert.set_root(admin_dir.get_path()) https_cert.set_root(admin_dir.get_path())
https_key.set_root(admin_dir.get_path()) https_key.set_root(admin_dir.get_path())

83
sabnzbd/config.py

@ -46,13 +46,14 @@ modified = False # Signals a change in option dictionary
class Option(object): class Option(object):
""" Basic option class, basic fields """ """ Basic option class, basic fields """
def __init__(self, section, keyword, default_val=None, add=True, protect=False): def __init__(self, section, keyword, default_val=None, add=True, protect=False):
""" Basic option """ Basic option
section : single section or comma-separated list of sections section : single section or comma-separated list of sections
a list will be a hierarchy: "foo, bar" --> [foo][[bar]] a list will be a hierarchy: "foo, bar" --> [foo][[bar]]
keyword : keyword in the (last) section keyword : keyword in the (last) section
default_val : value returned when no value has been set default_val : value returned when no value has been set
callback : procedure to call when value is succesfully changed callback : procedure to call when value is successfully changed
protect : Do not allow setting via the API (specifically set_dict) protect : Do not allow setting via the API (specifically set_dict)
""" """
self.__sections = section.split(',') self.__sections = section.split(',')
@ -88,7 +89,7 @@ class Option(object):
def get_dict(self, safe=False): def get_dict(self, safe=False):
""" Return value a dictionary """ """ Return value a dictionary """
return { self.__keyword : self.get() } return {self.__keyword: self.get()}
def set_dict(self, dict): def set_dict(self, dict):
""" Set value based on dictionary """ """ Set value based on dictionary """
@ -125,9 +126,9 @@ class Option(object):
return self.__sections, self.__keyword return self.__sections, self.__keyword
class OptionNumber(Option): class OptionNumber(Option):
""" Numeric option class, int/float is determined from default value """ """ Numeric option class, int/float is determined from default value """
def __init__(self, section, keyword, default_val=0, minval=None, maxval=None, validation=None, add=True, protect=False): def __init__(self, section, keyword, default_val=0, minval=None, maxval=None, validation=None, add=True, protect=False):
Option.__init__(self, section, keyword, default_val, add=add, protect=protect) Option.__init__(self, section, keyword, default_val, add=add, protect=protect)
self.__minval = minval self.__minval = minval
@ -159,6 +160,7 @@ class OptionNumber(Option):
class OptionBool(Option): class OptionBool(Option):
""" Boolean option class """ """ Boolean option class """
def __init__(self, section, keyword, default_val=False, add=True, protect=False): def __init__(self, section, keyword, default_val=False, add=True, protect=False):
Option.__init__(self, section, keyword, int(default_val), add=add, protect=protect) Option.__init__(self, section, keyword, int(default_val), add=add, protect=protect)
@ -174,6 +176,7 @@ class OptionBool(Option):
class OptionDir(Option): class OptionDir(Option):
""" Directory option class """ """ Directory option class """
def __init__(self, section, keyword, default_val='', apply_umask=False, create=True, validation=None, writable=True, add=True): def __init__(self, section, keyword, default_val='', apply_umask=False, create=True, validation=None, writable=True, add=True):
self.__validation = validation self.__validation = validation
self.__root = '' # Base directory for relative paths self.__root = '' # Base directory for relative paths
@ -193,7 +196,6 @@ class OptionDir(Option):
else: else:
return p.replace('\\', '/') if '\\' in p else p return p.replace('\\', '/') if '\\' in p else p
def get_path(self): def get_path(self):
""" Return full absolute path """ """ Return full absolute path """
value = self.get() value = self.get()
@ -240,8 +242,10 @@ class OptionDir(Option):
""" Set auto-creation value """ """ Set auto-creation value """
self.__create = value self.__create = value
class OptionList(Option): class OptionList(Option):
""" List option class """ """ List option class """
def __init__(self, section, keyword, default_val=None, validation=None, add=True, protect=False): def __init__(self, section, keyword, default_val=None, validation=None, add=True, protect=False):
self.__validation = validation self.__validation = validation
if default_val is None: if default_val is None:
@ -249,7 +253,7 @@ class OptionList(Option):
Option.__init__(self, section, keyword, default_val, add=add, protect=protect) Option.__init__(self, section, keyword, default_val, add=add, protect=protect)
def set(self, value): def set(self, value):
""" Set the list given a comma-separated string or a list""" """ Set the list given a comma-separated string or a list """
error = None error = None
if value is not None: if value is not None:
if not isinstance(value, list): if not isinstance(value, list):
@ -272,12 +276,14 @@ class OptionList(Option):
r = len(lst) r = len(lst)
for n in xrange(r): for n in xrange(r):
txt += lst[n] txt += lst[n]
if n < r-1: txt += ', ' if n < r - 1:
txt += ', '
return txt return txt
class OptionStr(Option): class OptionStr(Option):
""" String class """ """ String class """
def __init__(self, section, keyword, default_val='', validation=None, add=True, strip=True, protect=False): def __init__(self, section, keyword, default_val='', validation=None, add=True, strip=True, protect=False):
Option.__init__(self, section, keyword, default_val, add=add, protect=protect) Option.__init__(self, section, keyword, default_val, add=add, protect=protect)
self.__validation = validation self.__validation = validation
@ -306,6 +312,7 @@ class OptionStr(Option):
class OptionPassword(Option): class OptionPassword(Option):
""" Password class """ """ Password class """
def __init__(self, section, keyword, default_val='', add=True): def __init__(self, section, keyword, default_val='', add=True):
Option.__init__(self, section, keyword, default_val, add=add) Option.__init__(self, section, keyword, default_val, add=add)
self.get_string = self.get_stars self.get_string = self.get_stars
@ -325,9 +332,9 @@ class OptionPassword(Option):
def get_dict(self, safe=False): def get_dict(self, safe=False):
""" Return value a dictionary """ """ Return value a dictionary """
if safe: if safe:
return { self._Option__keyword : self.get_stars() } return {self._Option__keyword: self.get_stars()}
else: else:
return { self._Option__keyword : self.get() } return {self._Option__keyword: self.get()}
def set(self, pw): def set(self, pw):
""" Set password, encode it """ """ Set password, encode it """
@ -361,6 +368,7 @@ def delete_from_database(section, keyword):
class ConfigServer(object): class ConfigServer(object):
""" Class defining a single server """ """ Class defining a single server """
def __init__(self, name, values): def __init__(self, name, values):
self.__name = name self.__name = name
@ -368,7 +376,7 @@ class ConfigServer(object):
self.displayname = OptionStr(name, 'displayname', '', add=False) self.displayname = OptionStr(name, 'displayname', '', add=False)
self.host = OptionStr(name, 'host', '', add=False) self.host = OptionStr(name, 'host', '', add=False)
self.port = OptionNumber(name, 'port', 119, 0, 2**16-1, add=False) self.port = OptionNumber(name, 'port', 119, 0, 2 ** 16 - 1, add=False)
self.timeout = OptionNumber(name, 'timeout', 120, 30, 240, add=False) self.timeout = OptionNumber(name, 'timeout', 120, 30, 240, add=False)
self.username = OptionStr(name, 'username', '', add=False) self.username = OptionStr(name, 'username', '', add=False)
self.password = OptionPassword(name, 'password', '', add=False) self.password = OptionPassword(name, 'password', '', add=False)
@ -441,6 +449,7 @@ class ConfigServer(object):
class ConfigCat(object): class ConfigCat(object):
""" Class defining a single category """ """ Class defining a single category """
def __init__(self, name, values): def __init__(self, name, values):
self.__name = name self.__name = name
name = 'categories,' + name name = 'categories,' + name
@ -482,6 +491,7 @@ class ConfigCat(object):
class OptionFilters(Option): class OptionFilters(Option):
""" Filter list class """ """ Filter list class """
def __init__(self, section, keyword, add=True): def __init__(self, section, keyword, add=True):
Option.__init__(self, section, keyword, add=add) Option.__init__(self, section, keyword, add=add)
self.set([]) self.set([])
@ -521,7 +531,7 @@ class OptionFilters(Option):
dict = {} dict = {}
n = 0 n = 0
for filter in self.get(): for filter in self.get():
dict['filter'+str(n)] = filter dict['filter' + str(n)] = filter
n = n + 1 n = n + 1
return dict return dict
@ -545,8 +555,10 @@ class OptionFilters(Option):
self.set(filters) self.set(filters)
return True return True
class ConfigRSS(object): class ConfigRSS(object):
""" Class defining a single Feed definition """ """ Class defining a single Feed definition """
def __init__(self, name, values): def __init__(self, name, values):
self.__name = name self.__name = name
name = 'rss,' + name name = 'rss,' + name
@ -598,7 +610,6 @@ class ConfigRSS(object):
return 'rss', self.__name return 'rss', self.__name
def get_dconfig(section, keyword, nested=False): def get_dconfig(section, keyword, nested=False):
""" Return a config values dictonary, """ Return a config values dictonary,
Single item or slices based on 'section', 'keyword' Single item or slices based on 'section', 'keyword'
@ -633,16 +644,15 @@ def get_dconfig(section, keyword, nested=False):
data = item.get_dict(safe=True) data = item.get_dict(safe=True)
if not nested: if not nested:
if section in ('servers', 'categories', 'rss'): if section in ('servers', 'categories', 'rss'):
data = {section : [ data ]} data = {section: [data]}
else: else:
data = {section : data} data = {section: data}
return True, data return True, data
def get_config(section, keyword): def get_config(section, keyword):
""" Return a config object, based on 'section', 'keyword' """ Return a config object, based on 'section', 'keyword' """
"""
try: try:
return database[section][keyword] return database[section][keyword]
except KeyError: except KeyError:
@ -651,8 +661,7 @@ def get_config(section, keyword):
def set_config(kwargs): def set_config(kwargs):
""" Set a config item, using values in dictionary """ Set a config item, using values in dictionary """
"""
try: try:
item = database[kwargs.get('section')][kwargs.get('keyword')] item = database[kwargs.get('section')][kwargs.get('keyword')]
except KeyError: except KeyError:
@ -662,21 +671,19 @@ def set_config(kwargs):
def delete(section, keyword): def delete(section, keyword):
""" Delete specific config item """ Delete specific config item """
"""
try: try:
database[section][keyword].delete() database[section][keyword].delete()
except KeyError: except KeyError:
return return
################################################################################ ##############################################################################
#
# INI file support # INI file support
# #
# This does input and output of configuration to an INI file. # This does input and output of configuration to an INI file.
# It translates this data structure to the config database. # It translates this data structure to the config database.
##############################################################################
@synchronized(SAVE_CONFIG_LOCK) @synchronized(SAVE_CONFIG_LOCK)
def read_config(path): def read_config(path):
""" Read the complete INI file and check its version number """ Read the complete INI file and check its version number
@ -775,7 +782,6 @@ def _read_config(path, try_backup=False):
return True, "" return True, ""
@synchronized(SAVE_CONFIG_LOCK) @synchronized(SAVE_CONFIG_LOCK)
def save_config(force=False): def save_config(force=False):
""" Update Setup file with current option values """ """ Update Setup file with current option values """
@ -793,7 +799,7 @@ def save_config(force=False):
CFG[section] = {} CFG[section] = {}
for subsec in database[section]: for subsec in database[section]:
if section == 'servers': if section == 'servers':
subsec_mod = subsec.replace('[', '{').replace(']','}') subsec_mod = subsec.replace('[', '{').replace(']', '}')
else: else:
subsec_mod = subsec subsec_mod = subsec
try: try:
@ -833,7 +839,7 @@ def save_config(force=False):
except: except:
# Something wrong with the backup, # Something wrong with the backup,
logging.error(T('Cannot create backup file for %s'), bakname) logging.error(T('Cannot create backup file for %s'), bakname)
logging.info("Traceback: ", exc_info = True) logging.info("Traceback: ", exc_info=True)
return res return res
# Write new config file # Write new config file
@ -843,7 +849,7 @@ def save_config(force=False):
res = True res = True
except: except:
logging.error(T('Cannot write to INI file %s'), filename) logging.error(T('Cannot write to INI file %s'), filename)
logging.info("Traceback: ", exc_info = True) logging.info("Traceback: ", exc_info=True)
try: try:
os.remove(filename) os.remove(filename)
except: except:
@ -854,7 +860,6 @@ def save_config(force=False):
return res return res
def define_servers(): def define_servers():
""" Define servers listed in the Setup file """ Define servers listed in the Setup file
return a list of ConfigServer instances return a list of ConfigServer instances
@ -871,6 +876,7 @@ def define_servers():
except KeyError: except KeyError:
pass pass
def get_servers(): def get_servers():
global database global database
try: try:
@ -909,8 +915,8 @@ def get_categories(cat=0):
database['categories'] = {} database['categories'] = {}
cats = database['categories'] cats = database['categories']
if '*' not in cats: if '*' not in cats:
ConfigCat('*', {'pp' : old_def('dirscan_opts', '3'), 'script' : old_def('dirscan_script', 'None'), \ ConfigCat('*', {'pp': old_def('dirscan_opts', '3'), 'script': old_def('dirscan_script', 'None'),
'priority' : old_def('dirscan_priority', NORMAL_PRIORITY)}) 'priority': old_def('dirscan_priority', NORMAL_PRIORITY)})
save_config(True) save_config(True)
if not isinstance(cat, int): if not isinstance(cat, int):
try: try:
@ -931,6 +937,7 @@ def define_rss():
except KeyError: except KeyError:
pass pass
def get_rss(): def get_rss():
global database global database
try: try:
@ -938,18 +945,16 @@ def get_rss():
except KeyError: except KeyError:
return {} return {}
def get_filename(): def get_filename():
global CFG global CFG
return CFG.filename return CFG.filename
################################################################################ ##############################################################################
#
# Default Validation handlers # Default Validation handlers
# ##############################################################################
__PW_PREFIX = '!!!encoded!!!' __PW_PREFIX = '!!!encoded!!!'
#------------------------------------------------------------------------------
def encode_password(pw): def encode_password(pw):
""" Encode password in hexadecimal if needed """ """ Encode password in hexadecimal if needed """
enc = False enc = False
@ -973,7 +978,7 @@ def decode_password(pw, name):
if pw and pw.startswith(__PW_PREFIX): if pw and pw.startswith(__PW_PREFIX):
for n in range(len(__PW_PREFIX), len(pw), 2): for n in range(len(__PW_PREFIX), len(pw), 2):
try: try:
ch = chr( int(pw[n] + pw[n+1], 16) ) ch = chr(int(pw[n] + pw[n + 1], 16))
except ValueError: except ValueError:
logging.error(T('Incorrectly encoded password %s'), name) logging.error(T('Incorrectly encoded password %s'), name)
return '' return ''
@ -1041,8 +1046,7 @@ def validate_notempty(root, value, default):
def create_api_key(): def create_api_key():
""" Return a new randomized API_KEY """ Return a new randomized API_KEY """
"""
import time import time
try: try:
from hashlib import md5 from hashlib import md5
@ -1061,12 +1065,11 @@ def create_api_key():
return m.hexdigest() return m.hexdigest()
#------------------------------------------------------------------------------ _FIXES = (
_FIXES = \
(
('enable_par_multicore', 'par2_multicore'), ('enable_par_multicore', 'par2_multicore'),
) )
def compatibility_fix(cf): def compatibility_fix(cf):
""" Convert obsolete INI entries """ """ Convert obsolete INI entries """
for item in _FIXES: for item in _FIXES:

29
sabnzbd/constants.py

@ -87,14 +87,14 @@ DEF_INT_LANGUAGE = 'locale'
DEF_EMAIL_TMPL = 'email' DEF_EMAIL_TMPL = 'email'
DEF_STDCONFIG = 'Config' DEF_STDCONFIG = 'Config'
DEF_STDINTF = 'Glitter' DEF_STDINTF = 'Glitter'
DEF_SKIN_COLORS = {'smpl' : 'white', 'Glitter' : 'Default', 'plush' : 'gold'} DEF_SKIN_COLORS = {'smpl': 'white', 'Glitter': 'Default', 'plush': 'gold'}
DEF_MAIN_TMPL = 'templates/main.tmpl' DEF_MAIN_TMPL = 'templates/main.tmpl'
DEF_INI_FILE = 'sabnzbd.ini' DEF_INI_FILE = 'sabnzbd.ini'
DEF_HOST = '127.0.0.1' DEF_HOST = '127.0.0.1'
DEF_PORT_WIN = 8080 DEF_PORT_WIN = 8080
DEF_PORT_UNIX = 8080 DEF_PORT_UNIX = 8080
DEF_PORT_WIN_SSL = 9090 DEF_PORT_WIN_SSL = 9090
DEF_PORT_UNIX_SSL= 9090 DEF_PORT_UNIX_SSL = 9090
DEF_WORKDIR = 'sabnzbd' DEF_WORKDIR = 'sabnzbd'
DEF_LOG_FILE = 'sabnzbd.log' DEF_LOG_FILE = 'sabnzbd.log'
DEF_LOG_ERRFILE = 'sabnzbd.error.log' DEF_LOG_ERRFILE = 'sabnzbd.error.log'
@ -123,31 +123,28 @@ VALID_ARCHIVES = ('.zip', '.rar', '.7z')
IGNORED_FOLDERS = ('@eaDir', '.appleDouble') IGNORED_FOLDERS = ('@eaDir', '.appleDouble')
#(MATCHER, [EXTRA,MATCHERS]) # (MATCHER, [EXTRA, MATCHERS])
series_match = [ (r'( [sS]|[\d]+)x(\d+)', # 1x01 series_match = [(r'( [sS]|[\d]+)x(\d+)', # 1x01
[ r'^[-\.]+([sS]|[\d])+x(\d+)', [r'^[-\.]+([sS]|[\d])+x(\d+)', r'^[-\.](\d+)']),
r'^[-\.](\d+)'
] ),
(r'[Ss](\d+)[\.\-]?[Ee](\d+)', # S01E01 (r'[Ss](\d+)[\.\-]?[Ee](\d+)', # S01E01
[ r'^[-\.]+[Ss](\d+)[\.\-]?[Ee](\d+)', [r'^[-\.]+[Ss](\d+)[\.\-]?[Ee](\d+)', r'^[-\.](\d+)']),
r'^[-\.](\d+)'
] ),
(r'[ \-_\.](\d)(\d{2,2})[ \-_\.]', # .101. / _101_ / etc. (r'[ \-_\.](\d)(\d{2,2})[ \-_\.]', # .101. / _101_ / etc.
[ []),
] ),
(r'[ \-_\.](\d)(\d{2,2})$', # .101 at end of title (r'[ \-_\.](\d)(\d{2,2})$', # .101 at end of title
[ [])
] )
] ]
date_match = [r'(\d{4})\W(\d{1,2})\W(\d{1,2})', #2008-10-16 date_match = [r'(\d{4})\W(\d{1,2})\W(\d{1,2})', # 2008-10-16
r'(\d{1,2})\W(\d{1,2})\W(\d{4})'] #10.16.2008 r'(\d{1,2})\W(\d{1,2})\W(\d{4})'] # 10.16.2008
year_match = r'[\W]([1|2]\d{3})([^\w]|$)' # Something '(YYYY)' or '.YYYY.' or ' YYYY ' year_match = r'[\W]([1|2]\d{3})([^\w]|$)' # Something '(YYYY)' or '.YYYY.' or ' YYYY '
sample_match = r'((^|[\W_])sample\d*[\W_])' # something-sample.avi sample_match = r'((^|[\W_])sample\d*[\W_])' # something-sample.avi
class Status(): class Status():
COMPLETED = 'Completed' COMPLETED = 'Completed'
CHECKING = 'Checking' CHECKING = 'Checking'

29
sabnzbd/utils/diskspeed.py

@ -1,11 +1,14 @@
#!/usr/bin/env python #!/usr/bin/env python
import time, os, sys import time
import os
import sys
def writetofile(filename,mysizeMB):
# writes string to specified file repeatdely, until mysizeMB is reached. Then deletes fle def writetofile(filename, mysizeMB):
# writes string to specified file repeat delay, until mysizeMB is reached. Then deletes file
mystring = "The quick brown fox jumps over the lazy dog" mystring = "The quick brown fox jumps over the lazy dog"
writeloops = int(1000000*mysizeMB/len(mystring)) writeloops = int(1000000 * mysizeMB / len(mystring))
try: try:
f = open(filename, 'w') f = open(filename, 'w')
except: except:
@ -16,14 +19,13 @@ def writetofile(filename,mysizeMB):
f.close() f.close()
os.remove(filename) os.remove(filename)
##############
def diskspeedmeasure(dirname): def diskspeedmeasure(dirname):
# returns writing speed to dirname in MB/s # returns writing speed to dirname in MB/s
# method: keep writing a file, until 0.5 seconds is passed. Then divide bytes written by time passed # method: keep writing a file, until 0.5 seconds is passed. Then divide bytes written by time passed
filesize = 1 # in MB filesize = 1 # MB
maxtime = 0.5 # in sec maxtime = 0.5 # sec
filename = os.path.join(dirname,'outputTESTING.txt') filename = os.path.join(dirname, 'outputTESTING.txt')
start = time.time() start = time.time()
loopcounter = 0 loopcounter = 0
while True: while True:
@ -33,10 +35,9 @@ def diskspeedmeasure(dirname):
return None return None
loopcounter += 1 loopcounter += 1
diff = time.time() - start diff = time.time() - start
if diff > maxtime: break if diff > maxtime:
return (loopcounter*filesize)/diff break
return (loopcounter * filesize) / diff
############## Start of main
if __name__ == "__main__": if __name__ == "__main__":
@ -57,7 +58,7 @@ if __name__ == "__main__":
speed = diskspeedmeasure(dirname) speed = diskspeedmeasure(dirname)
print("Disk writing speed: %.2f Mbytes per second" % speed) print("Disk writing speed: %.2f Mbytes per second" % speed)
except IOError, e: except IOError, e:
#print "IOError:", e # print "IOError:", e
if e.errno == 13: if e.errno == 13:
print "Could not create test file. Check that you have write rights to directory", dirname print "Could not create test file. Check that you have write rights to directory", dirname
except: except:
@ -65,5 +66,3 @@ if __name__ == "__main__":
raise raise
print "Done" print "Done"

4
sabnzbd/utils/getipaddress.py

@ -2,6 +2,7 @@
import socket import socket
def localipv4(): def localipv4():
try: try:
s_ipv4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s_ipv4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@ -13,6 +14,7 @@ def localipv4():
pass pass
return ipv4 return ipv4
def publicipv4(): def publicipv4():
try: try:
import urllib2 import urllib2
@ -24,6 +26,7 @@ def publicipv4():
pass pass
return public_ipv4 return public_ipv4
def ipv6(): def ipv6():
try: try:
s_ipv6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s_ipv6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
@ -38,4 +41,3 @@ if __name__ == '__main__':
print localipv4() print localipv4()
print publicipv4() print publicipv4()
print ipv6() print ipv6()

2
sabnzbd/utils/getperformance.py

@ -24,8 +24,6 @@ def getpystone():
return value return value
if __name__ == '__main__': if __name__ == '__main__':
print getpystone() print getpystone()
print getcpu() print getcpu()

34
sabnzbd/utils/happyeyeballs.py

@ -8,31 +8,34 @@ import ssl
def happyeyeballs(HOST, **kwargs): def happyeyeballs(HOST, **kwargs):
try: try:
PORT=kwargs['port'] PORT = kwargs['port']
except: except:
PORT=80 PORT = 80
try: try:
SSL=kwargs['ssl'] SSL = kwargs['ssl']
except: except:
SSL=False SSL = False
try: try:
DEBUG=kwargs['debug'] DEBUG = kwargs['debug']
except: except:
DEBUG=False DEBUG = False
shortesttime = 10000000 # something very big shortesttime = 10000000 # something very big
quickestserver = None quickestserver = None
if DEBUG: print "Checking", HOST, PORT, "SSL:", SSL, "DEBUG:", DEBUG if DEBUG:
print "Checking", HOST, PORT, "SSL:", SSL, "DEBUG:", DEBUG
try: try:
allinfo = socket.getaddrinfo(HOST, 80, 0, 0, socket.IPPROTO_TCP) allinfo = socket.getaddrinfo(HOST, 80, 0, 0, socket.IPPROTO_TCP)
except: except:
if DEBUG: print "Could not resolve", HOST if DEBUG:
print "Could not resolve", HOST
return None return None
for i in allinfo: for i in allinfo:
address = i[4][0] address = i[4][0]
if DEBUG: print "Address is ", address if DEBUG:
print "Address is ", address
# note: i[0] contains socket.AF_INET or socket.AF_INET6 # note: i[0] contains socket.AF_INET or socket.AF_INET6
try: try:
@ -51,19 +54,21 @@ def happyeyeballs(HOST, **kwargs):
# CLOSE SOCKET CONNECTION # CLOSE SOCKET CONNECTION
wrappedSocket.close() wrappedSocket.close()
delay = 1000.0*(time.clock() - start) delay = 1000.0 * (time.clock() - start)
if DEBUG: print "Connecting took:", delay, "msec" if DEBUG:
print "Connecting took:", delay, "msec"
if delay < shortesttime: if delay < shortesttime:
shortesttime = delay shortesttime = delay
quickestserver = address quickestserver = address
except: except:
if DEBUG: print "Something went wrong (possibly just no connection)" if DEBUG:
print "Something went wrong (possibly just no connection)"
pass pass
if DEBUG: print "Quickest server is", quickestserver if DEBUG:
print "Quickest server is", quickestserver
return quickestserver return quickestserver
if __name__ == '__main__': if __name__ == '__main__':
print happyeyeballs('www.google.com') print happyeyeballs('www.google.com')
print happyeyeballs('www.google.com', port=443, ssl=True) print happyeyeballs('www.google.com', port=443, ssl=True)
@ -74,4 +79,3 @@ if __name__ == '__main__':
print happyeyeballs('newszilla.xs4all.nl', port=119) print happyeyeballs('newszilla.xs4all.nl', port=119)
print happyeyeballs('does.not.resolve', port=443, ssl=True, debug=True) print happyeyeballs('does.not.resolve', port=443, ssl=True, debug=True)
print happyeyeballs('216.58.211.164') print happyeyeballs('216.58.211.164')

7
sabnzbd/utils/servertests.py

@ -28,6 +28,7 @@ from sabnzbd.config import get_servers
from sabnzbd.encoding import xml_name from sabnzbd.encoding import xml_name
from sabnzbd.misc import int_conv from sabnzbd.misc import int_conv
def test_nntp_server_dict(kwargs): def test_nntp_server_dict(kwargs):
# Grab the host/port/user/pass/connections/ssl # Grab the host/port/user/pass/connections/ssl
host = kwargs.get('host', '').strip() host = kwargs.get('host', '').strip()
@ -48,13 +49,12 @@ def test_nntp_server_dict(kwargs):
else: else:
port = 119 port = 119
return test_nntp_server(host, port, server, username=username,
return test_nntp_server(host, port, server, username=username, \
password=password, ssl=ssl, ssl_type=ssl_type) password=password, ssl=ssl, ssl_type=ssl_type)
def test_nntp_server(host, port, server=None, username=None, password=None, ssl=None, ssl_type='t1'): def test_nntp_server(host, port, server=None, username=None, password=None, ssl=None, ssl_type='t1'):
''' Will connect (blocking) to the nttp server and report back any errors ''' """ Will connect (blocking) to the nttp server and report back any errors """
timeout = 4.0 timeout = 4.0
if '*' in password and not password.strip('*'): if '*' in password and not password.strip('*'):
# If the password is masked, try retrieving it from the config # If the password is masked, try retrieving it from the config
@ -104,7 +104,6 @@ def test_nntp_server(host, port, server=None, username=None, password=None, ssl=
except: except:
return False, unicode(sys.exc_info()[1]) return False, unicode(sys.exc_info()[1])
if not username or not password: if not username or not password:
nw.nntp.sock.sendall('ARTICLE <test@home>\r\n') nw.nntp.sock.sendall('ARTICLE <test@home>\r\n')
try: try:

34
sabnzbd/utils/systrayiconthread.py

@ -19,8 +19,8 @@ except ImportError:
from threading import Thread from threading import Thread
from time import sleep from time import sleep
class SysTrayIconThread(Thread): class SysTrayIconThread(Thread):
'''TODO'''
QUIT = 'QUIT' QUIT = 'QUIT'
SPECIAL_ACTIONS = [QUIT] SPECIAL_ACTIONS = [QUIT]
@ -40,30 +40,28 @@ class SysTrayIconThread(Thread):
self.hover_text = hover_text self.hover_text = hover_text
self.on_quit = on_quit self.on_quit = on_quit
# menu_options = menu_options + (('Quit', None, self.QUIT),) # menu_options = menu_options + (('Quit', None, self.QUIT),)
self._next_action_id = self.FIRST_ID self._next_action_id = self.FIRST_ID
self.menu_actions_by_id = set() self.menu_actions_by_id = set()
self.menu_options = self._add_ids_to_menu_options(list(menu_options)) self.menu_options = self._add_ids_to_menu_options(list(menu_options))
self.menu_actions_by_id = dict(self.menu_actions_by_id) self.menu_actions_by_id = dict(self.menu_actions_by_id)
del self._next_action_id del self._next_action_id
self.default_menu_index = (default_menu_index or 0) self.default_menu_index = (default_menu_index or 0)
self.window_class_name = window_class_name or "SysTrayIconPy" self.window_class_name = window_class_name or "SysTrayIconPy"
self.start() self.start()
def initialize(self): def initialize(self):
message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart, message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart,
win32con.WM_DESTROY: self.destroy, win32con.WM_DESTROY: self.destroy,
win32con.WM_COMMAND: self.command, win32con.WM_COMMAND: self.command,
win32con.WM_USER+20 : self.notify,} win32con.WM_USER + 20: self.notify, }
# Register the Window class. # Register the Window class.
window_class = win32gui.WNDCLASS() window_class = win32gui.WNDCLASS()
hinst = window_class.hInstance = win32gui.GetModuleHandle(None) hinst = window_class.hInstance = win32gui.GetModuleHandle(None)
window_class.lpszClassName = self.window_class_name window_class.lpszClassName = self.window_class_name
window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW; window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW
window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW) window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)
window_class.hbrBackground = win32con.COLOR_WINDOW window_class.hbrBackground = win32con.COLOR_WINDOW
window_class.lpfnWndProc = message_map # could also specify a wndproc. window_class.lpfnWndProc = message_map # could also specify a wndproc.
@ -115,8 +113,9 @@ class SysTrayIconThread(Thread):
return result return result
def get_icon(self, path): def get_icon(self, path):
hicon = self.icons.get(path); hicon = self.icons.get(path)
if hicon != None: return hicon if hicon != None:
return hicon
# Try and find a custom icon # Try and find a custom icon
hinst = win32gui.GetModuleHandle(None) hinst = win32gui.GetModuleHandle(None)
@ -137,12 +136,14 @@ class SysTrayIconThread(Thread):
def refresh_icon(self): def refresh_icon(self):
hicon = self.get_icon(self.icon) hicon = self.get_icon(self.icon)
if self.notify_id: message = win32gui.NIM_MODIFY if self.notify_id:
else: message = win32gui.NIM_ADD message = win32gui.NIM_MODIFY
else:
message = win32gui.NIM_ADD
self.notify_id = (self.hwnd, self.notify_id = (self.hwnd,
0, 0,
win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP, win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,
win32con.WM_USER+20, win32con.WM_USER + 20,
hicon, hicon,
self.hover_text) self.hover_text)
try: try:
@ -155,17 +156,18 @@ class SysTrayIconThread(Thread):
self.refresh_icon() self.refresh_icon()
def destroy(self, hwnd, msg, wparam, lparam): def destroy(self, hwnd, msg, wparam, lparam):
if self.on_quit: self.on_quit(self) if self.on_quit:
self.on_quit(self)
nid = (self.hwnd, 0) nid = (self.hwnd, 0)
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid) win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
win32gui.PostQuitMessage(0) # Terminate the app. win32gui.PostQuitMessage(0) # Terminate the app.
def notify(self, hwnd, msg, wparam, lparam): def notify(self, hwnd, msg, wparam, lparam):
if lparam==win32con.WM_LBUTTONDBLCLK: if lparam == win32con.WM_LBUTTONDBLCLK:
self.execute_menu_option(self.default_menu_index + self.FIRST_ID) self.execute_menu_option(self.default_menu_index + self.FIRST_ID)
elif lparam==win32con.WM_RBUTTONUP: elif lparam == win32con.WM_RBUTTONUP:
self.show_menu() self.show_menu()
elif lparam==win32con.WM_LBUTTONUP: elif lparam == win32con.WM_LBUTTONUP:
pass pass
return True return True
@ -242,6 +244,7 @@ class SysTrayIconThread(Thread):
else: else:
menu_action(self) menu_action(self)
def non_string_iterable(obj): def non_string_iterable(obj):
try: try:
iter(obj) iter(obj)
@ -249,4 +252,3 @@ def non_string_iterable(obj):
return False return False
else: else:
return not isinstance(obj, basestring) return not isinstance(obj, basestring)

5
sabnzbd/utils/upload.py

@ -16,7 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
""" """
sabnzbd.utils.upload - File assosiation functions for adding nzb files to sabnzbd sabnzbd.utils.upload - File association functions for adding nzb files to sabnzbd
""" """
import urllib2 import urllib2
@ -30,6 +30,7 @@ from sabnzbd.constants import VALID_ARCHIVES
from sabnzbd.dirscanner import ProcessArchiveFile, ProcessSingleFile from sabnzbd.dirscanner import ProcessArchiveFile, ProcessSingleFile
def upload_file(url, fp): def upload_file(url, fp):
""" Function for uploading nzbs to a running sabnzbd instance """ """ Function for uploading nzbs to a running sabnzbd instance """
try: try:
@ -48,7 +49,7 @@ def upload_file(url, fp):
sabnzbd.newsunpack.get_from_url(url) sabnzbd.newsunpack.get_from_url(url)
except: except:
logging.error("Failed to upload file: %s", fp) logging.error("Failed to upload file: %s", fp)
logging.info("Traceback: ", exc_info = True) logging.info("Traceback: ", exc_info=True)
def add_local(f): def add_local(f):

Loading…
Cancel
Save