Browse Source

Py3: Get SABnzbd to start

pull/1161/head
Safihre 8 years ago
parent
commit
c451f15afe
  1. 40
      SABnzbd.py
  2. 22
      sabnzbd/__init__.py
  3. 6
      sabnzbd/assembler.py
  4. 4
      sabnzbd/cfg.py
  5. 15
      sabnzbd/config.py
  6. 47
      sabnzbd/encoding.py
  7. 6
      sabnzbd/getipaddress.py
  8. 2
      sabnzbd/lang.py
  9. 2
      sabnzbd/scheduler.py
  10. 2
      sabnzbd/utils/kronos.py

40
SABnzbd.py

@ -17,18 +17,8 @@
import sys
import imp
if sys.version_info[:2] < (2, 7) or sys.version_info[:2] >= (3, 0):
print("Sorry, requires Python 2.7.")
sys.exit(1)
# Make sure UTF-8 is default 8bit encoding
if not hasattr(sys, "setdefaultencoding"):
imp.reload(sys)
try:
sys.setdefaultencoding('utf-8')
except:
print('Sorry, you MUST add the SABnzbd folder to the PYTHONPATH environment variable')
print('or find another way to force Python to use UTF-8 for text encoding.')
if sys.version_info[:2] <= (3, 0):
print("Sorry, requires Python 3")
sys.exit(1)
import logging
@ -45,10 +35,10 @@ import re
try:
import Cheetah
if Cheetah.Version[0] != '2':
if Cheetah.Version[0] != '3':
raise ValueError
except ValueError:
print("Sorry, requires Python module Cheetah 2.0rc7 or higher.")
print("Sorry, requires Python module Cheetah 3 or higher.")
sys.exit(1)
except:
print("The Python module Cheetah is required")
@ -72,13 +62,7 @@ except:
SQLITE_DLL = False
import locale
import builtins
try:
locale.setlocale(locale.LC_ALL, "")
builtins.__dict__['codepage'] = locale.getlocale()[1] or 'cp1252'
except:
# Work-around for Python-ports with bad "locale" support
builtins.__dict__['codepage'] = 'cp1252'
import sabnzbd
import sabnzbd.lang
@ -1078,8 +1062,7 @@ def main():
logdir = sabnzbd.cfg.log_dir.get_path()
if fork and not logdir:
print("Error:")
print("I refuse to fork without a log directory!")
print("Error: I refuse to fork without a log directory!")
sys.exit(1)
if clean_up:
@ -1161,16 +1144,11 @@ def main():
logging.info('Arguments = %s', sabnzbd.CMDLINE)
# Find encoding; relevant for unrar activities
try:
preferredencoding = locale.getpreferredencoding()
logging.info('Preferred encoding = %s', preferredencoding)
except:
logging.info('Preferred encoding = ERROR')
preferredencoding = ''
logging.info('Preferred encoding = %s', sys.stdin.encoding)
# On Linux/FreeBSD/Unix "UTF-8" is strongly, strongly adviced:
if not sabnzbd.WIN32 and not sabnzbd.DARWIN and not ('utf' in preferredencoding.lower() and '8' in preferredencoding.lower()):
logging.warning(T("SABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.") % preferredencoding)
if not sabnzbd.WIN32 and not sabnzbd.DARWIN and not ('utf' in sys.stdin.encoding.lower() and '8' in sys.stdin.encoding.lower()):
logging.warning(T("SABnzbd was started with encoding %s, this should be UTF-8. Expect problems with Unicoded file and directory names in downloads.") % sys.stdin.encoding)
# SSL Information
logging.info("SSL version = %s", ssl.OPENSSL_VERSION)

22
sabnzbd/__init__.py

@ -269,13 +269,13 @@ def initialize(pause_downloader=False, clean_up=False, evalSched=False, repair=0
cfg.quota_size.callback(guard_quota_size)
cfg.quota_day.callback(guard_quota_dp)
cfg.quota_period.callback(guard_quota_dp)
cfg.fsys_type.callback(guard_fsys_type)
###### cfg.fsys_type.callback(guard_fsys_type)
cfg.language.callback(sabnzbd.notifier.reset_growl)
cfg.enable_https_verification.callback(guard_https_ver)
guard_https_ver()
# Set Posix filesystem encoding
sabnzbd.encoding.change_fsys(cfg.fsys_type())
###### sabnzbd.encoding.change_fsys(cfg.fsys_type())
# Set cache limit
if not cfg.cache_limit() or (cfg.cache_limit() == '200M' and (sabnzbd.WIN32 or sabnzbd.DARWIN)):
@ -512,9 +512,9 @@ def guard_quota_dp():
scheduler.restart(force=True)
def guard_fsys_type():
""" Callback for change of file system naming type """
sabnzbd.encoding.change_fsys(cfg.fsys_type())
# def guard_fsys_type():
# """ Callback for change of file system naming type """
# sabnzbd.encoding.change_fsys(cfg.fsys_type())
def set_https_verification(value):
@ -882,9 +882,6 @@ def save_data(data, _id, path, do_pickle=True, silent=False):
try:
with open(path, 'wb') as data_file:
if do_pickle:
if cfg.use_pickle():
pickle.dump(data, data_file)
else:
pickle.dump(data, data_file)
else:
data_file.write(data)
@ -915,9 +912,6 @@ def load_data(_id, path, remove=True, do_pickle=True, silent=False):
try:
with open(path, 'rb') as data_file:
if do_pickle:
if cfg.use_pickle():
data = pickle.load(data_file)
else:
data = pickle.load(data_file)
else:
data = data_file.read()
@ -951,9 +945,6 @@ def save_admin(data, _id):
for t in range(3):
try:
with open(path, 'wb') as data_file:
if cfg.use_pickle():
data = pickle.dump(data, data_file)
else:
data = pickle.dump(data, data_file)
break
except:
@ -976,9 +967,6 @@ def load_admin(_id, remove=False, silent=False):
try:
with open(path, 'rb') as data_file:
if cfg.use_pickle():
data = pickle.load(data_file)
else:
data = pickle.load(data_file)
if remove:
misc.remove_file(path)

6
sabnzbd/assembler.py

@ -45,12 +45,8 @@ from sabnzbd.rating import Rating
class Assembler(Thread):
do = None # Link to the instance of this method
def __init__(self, queue=None):
def __init__(self):
Thread.__init__(self)
if queue:
self.queue = queue
else:
self.queue = queue.Queue()
Assembler.do = self

4
sabnzbd/cfg.py

@ -79,7 +79,6 @@ configlock = OptionBool('misc', 'config_lock', 0)
##############################################################################
# One time trackers
##############################################################################
converted_nzo_pickles = OptionBool('misc', 'converted_nzo_pickles', False)
warned_old_queue = OptionNumber('misc', 'warned_old_queue', QUEUE_VERSION)
sched_converted = OptionBool('misc', 'sched_converted', False)
notified_new_skin = OptionNumber('misc', 'notified_new_skin', 0)
@ -255,7 +254,6 @@ allow_incomplete_nzb = OptionBool('misc', 'allow_incomplete_nzb', False)
enable_bonjour = OptionBool('misc', 'enable_bonjour', True)
reject_duplicate_files = OptionBool('misc', 'reject_duplicate_files', False)
max_art_opt = OptionBool('misc', 'max_art_opt', False)
use_pickle = OptionBool('misc', 'use_pickle', False)
ipv6_hosting = OptionBool('misc', 'ipv6_hosting', False)
fixed_ports = OptionBool('misc', 'fixed_ports', False)
api_warnings = OptionBool('misc', 'api_warnings', True, protect=True)
@ -270,7 +268,7 @@ req_completion_rate = OptionNumber('misc', 'req_completion_rate', 100.2, 100, 20
selftest_host = OptionStr('misc', 'selftest_host', 'self-test.sabnzbd.org')
movie_rename_limit = OptionStr('misc', 'movie_rename_limit', '100M')
size_limit = OptionStr('misc', 'size_limit', '0')
fsys_type = OptionNumber('misc', 'fsys_type', 0, 0, 2)
###### fsys_type = OptionNumber('misc', 'fsys_type', 0, 0, 2)
show_sysload = OptionNumber('misc', 'show_sysload', 2, 0, 2)
history_limit = OptionNumber('misc', 'history_limit', 10, 0)
wait_ext_drive = OptionNumber('misc', 'wait_ext_drive', 5, 1, 60)

15
sabnzbd/config.py

@ -26,7 +26,7 @@ import threading
import shutil
import time
import random
from hashlib import md5
import uuid
from urllib.parse import urlparse
import sabnzbd.misc
from sabnzbd.constants import CONFIG_VERSION, NORMAL_PRIORITY, DEFAULT_PRIORITY, MAX_WIN_DFOLDER
@ -727,7 +727,7 @@ def _read_config(path, try_backup=False):
return False, 'Cannot create INI file %s' % path
try:
fp = open(path, 'rb')
fp = open(path, 'r')
lines = fp.read().split('\n')
if len(lines) == 1:
fp.seek(0)
@ -1093,13 +1093,4 @@ def validate_notempty(root, value, default):
def create_api_key():
""" Return a new randomized API_KEY """
# Create some values to seed md5
t = str(time.time())
r = str(random.random())
# Create the md5 instance and give it the current time
m = md5(t)
# Update the md5 instance with the random variable
m.update(r)
# Return a hex digest of the md5, eg 49f68a5c8493ec2c0bf489821c21fc3b
return m.hexdigest()
return uuid.uuid4().hex

47
sabnzbd/encoding.py

@ -52,6 +52,7 @@ def change_fsys(value):
def platform_encode(p):
return p
""" Return Unicode name, if not already Unicode, decode with UTF-8 or latin1 """
if isinstance(p, str):
try:
@ -92,6 +93,7 @@ def special_fixer(p):
def unicoder(p, force=False):
return p
""" Make sure a Unicode string is returned
When `force` is True, ignore filesystem encoding
"""
@ -109,6 +111,7 @@ def unicoder(p, force=False):
def xml_name(p, keep_escape=False, encoding=None):
return p
""" Prepare name for use in HTML/XML contect """
if isinstance(p, str):
@ -135,18 +138,8 @@ class LatinFilter(Filter):
def filter(self, val, str=str, **kw):
if isinstance(val, str):
return val
elif isinstance(val, str):
try:
if sabnzbd.WIN32:
return val.decode(codepage)
else:
return val.decode('utf-8')
except:
return val.decode(codepage, 'replace')
elif val is None:
return ''
else:
return str(str(val))
return str(val)
class EmailFilter(Filter):
@ -155,6 +148,9 @@ class EmailFilter(Filter):
"""
def filter(self, val, str=str, **kw):
return val
if isinstance(val, str):
return val
elif isinstance(val, str):
@ -174,32 +170,11 @@ class EmailFilter(Filter):
#
# Use to transform 8-bit console output to plain Python strings
#
import string
TAB_850 = \
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F" \
"\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F" \
"\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF" \
"\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF" \
"\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF" \
"\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF" \
"\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF" \
"\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"
TAB_LATIN = \
"\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5" \
"\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xF8\xA3\xD8\xD7\x66" \
"\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\xAE\xAC\xDB\xBC\xA1\xAB\xBB" \
"\x7E\x7E\x7E\x7E\x7E\xC1\xC2\xC0\xA9\x7E\x7E\x7E\x7E\xA2\xA5\x7E" \
"\x7E\x7E\x7E\x7E\x7E\x7E\xE3\xc3\x7E\x7E\x7E\x7E\x7E\x7E\x7E\xA4" \
"\xF0\xD0\xCA\xCB\xC8\x7E\xCD\xCE\xCF\x7E\x7E\x7E\x7E\xA6\xCC\x7E" \
"\xD3\xDF\xD4\xD2\xF5\xD5\xB5\xFE\xDE\xDA\xDB\xD9\xFD\xDD\xAF\xB4" \
"\xAD\xB1\x5F\xBE\xB6\xA7\xF7\xB8\xB0\xA8\xB7\xB9\xB3\xB2\x7E\xA0"
gTABLE_850_LATIN = string.maketrans(TAB_850, TAB_LATIN)
gTABLE_LATIN_850 = string.maketrans(TAB_LATIN, TAB_850)
def TRANS(p):
return p
""" For Windows: Translate CP850 to Python's Latin-1 and return in Unicode
Others: return original string
"""
@ -215,6 +190,7 @@ def TRANS(p):
def UNTRANS(p):
return p
""" For Windows: Translate Python's Latin-1 to CP850
Others: return original string
"""
@ -230,6 +206,7 @@ def UNTRANS(p):
def fixup_ff4(p):
return p
""" Fix incompatibility between CherryPy and Firefox-4 on OSX,
where a filename contains &#xx; encodings
"""
@ -279,6 +256,7 @@ def html_escape(txt):
def deunicode(p):
return p
""" Return the correct 8bit ASCII encoding for the platform:
Latin-1 for Windows/Posix-non-UTF and UTF-8 for OSX/Posix-UTF
"""
@ -303,4 +281,3 @@ def deunicode(p):
return p
auto_fsys()

6
sabnzbd/getipaddress.py

@ -80,6 +80,7 @@ def publicipv4():
# something very bad: no urllib2, no resolving of selftest_host, no network at all
public_ipv4 = None
return public_ipv4
# we got one or more IPv4 address(es), so let's connect to them
for item in result:
selftest_ipv4 = item[4][0] # get next IPv4 address of sabnzbd.cfg.selftest_host()
@ -90,8 +91,8 @@ def publicipv4():
req.add_header('User-Agent', 'SABnzbd+/%s' % sabnzbd.version.__version__ )
# specify the Host, because we only provide the IPv4 address in the URL:
req.add_header('Host', sabnzbd.cfg.selftest_host())
# get the response
public_ipv4 = urllib.request.urlopen(req, timeout=2).read() # timeout 2 seconds, in case the website is not accessible
# get the response, timeout 2 seconds, in case the website is not accessible
public_ipv4 = urllib.request.urlopen(req, timeout=2).read().decode('utf-8')
# ... check the response is indeed an IPv4 address:
socket.inet_aton(public_ipv4) # if we got anything else than a plain IPv4 address, this will raise an exception
# if we get here without exception, we're done:
@ -101,6 +102,7 @@ def publicipv4():
# the connect OR the inet_aton raised an exception, so:
# continue the for loop to try next server IPv4 address
pass
if not ipv4_found:
public_ipv4 = None
return public_ipv4

2
sabnzbd/lang.py

@ -67,7 +67,7 @@ def set_language(language=None):
lng = gettext.translation(_DOMAIN, _LOCALEDIR, [language], fallback=True, codeset='latin-1')
# The unicode flag will make _() return Unicode
lng.install(str=True, names=['lgettext'])
lng.install(names=['lgettext'])
builtins.__dict__['T'] = builtins.__dict__['_'] # Unicode
builtins.__dict__['Ta'] = builtins.__dict__['_'] # Unicode (Used to Latin-1, compatibility support)
builtins.__dict__['Tx'] = builtins.__dict__['_'] # Dynamic translation (unicode)

2
sabnzbd/scheduler.py

@ -299,7 +299,7 @@ def sort_schedules(all_events, now=None):
if not all_events:
break
events.sort(lambda x, y: x[0] - y[0])
events.sort(key=lambda x, y: x[0] - y[0])
return events

2
sabnzbd/utils/kronos.py

@ -361,7 +361,7 @@ class DayTaskRescheduler:
now[3], now[4] = self.timeonday
# seconds
now[5] = 0
return time.mktime(now)
return time.mktime(tuple(now))
def reschedule(self, scheduler):
"""Reschedule this task according to the daytime for the task.

Loading…
Cancel
Save