Browse Source

Add Bonjour/ZeroConfig Support.

Basic ZeroConfig support, only when SABnzbd listens to external addresses.
On all platforms, ZeroConfig/Bonjour libraries fail to implement "localhost" support properly.
Default on when support libraries are installed, special option to disable in case of trouble.
HTTP-->HTTPS redirection only enabled when ZeroConfig is active.
pull/91/head
shypike 12 years ago
parent
commit
46dd2137ea
  1. 3
      SABnzbd.py
  2. 10
      licenses/License-pybonjour.txt
  3. 3
      sabnzbd/__init__.py
  4. 1
      sabnzbd/cfg.py
  5. 2
      sabnzbd/interface.py
  6. 2073
      sabnzbd/utils/pybonjour.py
  7. 114
      sabnzbd/zconfig.py

3
SABnzbd.py

@ -98,6 +98,7 @@ import sabnzbd.cfg
import sabnzbd.downloader import sabnzbd.downloader
from sabnzbd.encoding import unicoder, latin1, deunicode from sabnzbd.encoding import unicoder, latin1, deunicode
import sabnzbd.growler as growler import sabnzbd.growler as growler
import sabnzbd.zconfig
from threading import Thread from threading import Thread
@ -1531,12 +1532,12 @@ def main():
# Wait for server to become ready # Wait for server to become ready
cherrypy.engine.wait(cherrypy.process.wspbus.states.STARTED) cherrypy.engine.wait(cherrypy.process.wspbus.states.STARTED)
sabnzbd.zconfig.set_bonjour(cherryhost, cherryport)
if enable_https: if enable_https:
browser_url = "https://%s:%s/sabnzbd" % (browserhost, cherryport) browser_url = "https://%s:%s/sabnzbd" % (browserhost, cherryport)
else: else:
browser_url = "http://%s:%s/sabnzbd" % (browserhost, cherryport) browser_url = "http://%s:%s/sabnzbd" % (browserhost, cherryport)
cherrypy.wsgiserver.REDIRECT_URL = browser_url
sabnzbd.BROWSER_URL = browser_url sabnzbd.BROWSER_URL = browser_url
if not autorestarted: if not autorestarted:

10
licenses/License-pybonjour.txt

@ -0,0 +1,10 @@
The module pybonjour is (C) Christopher Stawarz <cstawarz@gmail.com>
Version: 1.1.1
May 8, 2008
Home of the module:
http://pseudogreen.org/bzr/pybonjour/
It is covered by the following license:
"pybonjour is free software, distributed under the MIT license."

3
sabnzbd/__init__.py

@ -170,6 +170,7 @@ def sig_handler(signum = None, frame = None):
logging.warning(Ta('Signal %s caught, saving and exiting...'), signum) logging.warning(Ta('Signal %s caught, saving and exiting...'), signum)
try: try:
save_state(flag=True) save_state(flag=True)
sabnzbd.zconfig.remove_server()
finally: finally:
if sabnzbd.WIN32: if sabnzbd.WIN32:
from util.apireg import del_connection_info from util.apireg import del_connection_info
@ -361,6 +362,8 @@ def halt():
logging.info('SABnzbd shutting down...') logging.info('SABnzbd shutting down...')
__SHUTTING_DOWN__ = True __SHUTTING_DOWN__ = True
sabnzbd.zconfig.remove_server()
rss.stop() rss.stop()
logging.debug('Stopping URLGrabber') logging.debug('Stopping URLGrabber')

1
sabnzbd/cfg.py

@ -301,6 +301,7 @@ wait_ext_drive = OptionNumber('misc', 'wait_ext_drive', 5, 1, 60)
history_limit = OptionNumber('misc', 'history_limit', 50, 0) history_limit = OptionNumber('misc', 'history_limit', 50, 0)
show_sysload = OptionNumber('misc', 'show_sysload', 2, 0, 2) show_sysload = OptionNumber('misc', 'show_sysload', 2, 0, 2)
web_watchdog = OptionBool('misc', 'web_watchdog', False) web_watchdog = OptionBool('misc', 'web_watchdog', False)
enable_bonjour = OptionBool('misc', 'enable_bonjour', True)
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Set root folders for Folder config-items # Set root folders for Folder config-items

2
sabnzbd/interface.py

@ -1231,7 +1231,7 @@ SPECIAL_BOOL_LIST = \
'never_repair', 'allow_streaming', 'ignore_unrar_dates', 'rss_filenames', 'news_items', 'never_repair', 'allow_streaming', 'ignore_unrar_dates', 'rss_filenames', 'news_items',
'osx_menu', 'osx_speed', 'win_menu', 'uniconfig', 'use_pickle', 'allow_incomplete_nzb', 'osx_menu', 'osx_speed', 'win_menu', 'uniconfig', 'use_pickle', 'allow_incomplete_nzb',
'randomize_server_ip', 'no_ipv6', 'keep_awake', 'overwrite_files', 'empty_postproc', 'randomize_server_ip', 'no_ipv6', 'keep_awake', 'overwrite_files', 'empty_postproc',
'web_watchdog', 'wait_for_dfolder', 'warn_empty_nzb' 'web_watchdog', 'wait_for_dfolder', 'warn_empty_nzb', 'enable_bonjour'
) )
SPECIAL_VALUE_LIST = \ SPECIAL_VALUE_LIST = \
( 'size_limit', 'folder_max_length', 'fsys_type', 'movie_rename_limit', 'nomedia_marker', ( 'size_limit', 'folder_max_length', 'fsys_type', 'movie_rename_limit', 'nomedia_marker',

2073
sabnzbd/utils/pybonjour.py

File diff suppressed because it is too large

114
sabnzbd/zconfig.py

@ -0,0 +1,114 @@
#!/usr/bin/python -OO
# Copyright 2008-2012 The SABnzbd-Team <team@sabnzbd.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""
sabnzbd.zconfig - bonjour/zeroconfig support
"""
import os
import logging
import socket
import cherrypy
_HOST_PORT = (None, None)
try:
from sabnzbd.utils import pybonjour
from threading import Thread
_HAVE_BONJOUR = True
except:
_HAVE_BONJOUR = False
import sabnzbd
import sabnzbd.cfg as cfg
from sabnzbd.misc import match_str
_BONJOUR_OBJECT = None
def hostname():
""" Return host's pretty name """
if sabnzbd.WIN32:
return os.environ.get('computername', 'unknown')
try:
return os.uname()[1]
except:
return 'unknown'
def _zeroconf_callback(sdRef, flags, errorCode, name, regtype, domain):
logging.debug('Full Bonjour-callback sdRef=%s, flags=%s, errorCode=%s, name=%s, regtype=%s, domain=%s',
sdRef, flags, errorCode, name, regtype, domain)
if errorCode == pybonjour.kDNSServiceErr_NoError:
logging.info('Registered in Bonjour as "%s" (%s)', name, domain)
def set_bonjour(host=None, port=None):
""" Publish host/port combo through Bonjour
"""
global _HOST_PORT, _BONJOUR_OBJECT
if not _HAVE_BONJOUR or not cfg.enable_bonjour():
logging.debug('No Bonjour/ZeroConfig support installed')
return
if host is None and port is None:
host, port = _HOST_PORT
else:
_HOST_PORT = (host, port)
scope = pybonjour.kDNSServiceInterfaceIndexAny
zhost = None
domain = None
if match_str(host, ('localhost', '127.0.', '::1')):
logging.info('Bonjour/ZeroConfig does not support "localhost"')
# All implementations fail to implement "localhost" properly
# A false addresss is published even when scope==kDNSServiceInterfaceIndexLocalOnly
return
name = hostname()
if '.local' in name:
suffix = ''
else:
suffix = '.local'
cherrypy.wsgiserver.redirect_url("https://%s%s:%s/sabnzbd" % (name, suffix, port))
refObject = pybonjour.DNSServiceRegister(
interfaceIndex = scope,
name = 'SABnzbd on %s' % name,
regtype = '_http._tcp',
domain = domain,
host = zhost,
port = int(port),
txtRecord = pybonjour.TXTRecord({'path': '/sabnzbd/'}),
callBack = _zeroconf_callback)
logging.debug('Try to publish in Bonjour as "%s" (%s:%s)', name, host, port)
Thread(target=_bonjour_server, args=(refObject,))
_BONJOUR_OBJECT = refObject
def _bonjour_server(refObject):
while 1:
pybonjour.DNSServiceProcessResult(refObject)
logging.debug('GOT A BONJOUR CALL')
def remove_server():
""" Remove Bonjour registration """
global _BONJOUR_OBJECT
if _BONJOUR_OBJECT:
_BONJOUR_OBJECT.close()
_BONJOUR_OBJECT = None
Loading…
Cancel
Save