diff --git a/common.py b/common.py index c93380f..73c6800 100644 --- a/common.py +++ b/common.py @@ -1,5 +1,3 @@ -#!/usr/bin/python -# # Copyright 2013 Jeff Rebeiro (jeff@rebeiro.net) All rights reserved # Common functions for PC Autobackup @@ -15,7 +13,7 @@ LOG_DATE_FMT = '[%m/%d/%Y %I:%M %p]' LOG_FMT = '%(asctime)s[%(name)s] %(levelname)s:%(message)s' -LOG_DEFAULTS = {'level': logging.WARN, +LOG_DEFAULTS = {'level': logging.INFO, 'format': LOG_FMT, 'datefmt': LOG_DATE_FMT} @@ -30,11 +28,17 @@ config.add_section('AUTOBACKUP') config.set('AUTOBACKUP', 'backup_dir', os.path.expanduser('~/PCAutoBackup')) - config.set('AUTOBACKUP', 'default_interface', - socket.gethostbyname(socket.gethostname())) - config.set('AUTOBACKUP', 'server_name', '[PC]AutoBackup') + try: + config.set('AUTOBACKUP', 'default_interface', + socket.gethostbyname(socket.gethostname())) + except socket.error: + logging.error('Unable to determine IP address. Please set manually!') + config.set('AUTOBACKUP', 'default_interface', '127.0.0.1') + config.set('AUTOBACKUP', 'server_name', + '[%s]AutoBackup' % socket.gethostname()) config.set('AUTOBACKUP', 'uuid', uuid.uuid4()) with open(CONFIG_FILE, 'wb') as config_file: config.write(config_file) return config + \ No newline at end of file diff --git a/mediaserver.py b/mediaserver.py index 1cd823b..fec2480 100644 --- a/mediaserver.py +++ b/mediaserver.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2013 Jeff Rebeiro (jeff@rebeiro.net) All rights reserved # Simple UPNP MediaServer implementation for PC Autobackup @@ -145,7 +145,11 @@ self.config = common.LoadOrCreateConfig() def render_GET(self, request): - self.logger.debug('Request Headers: %s', request.getAllHeaders()) + self.logger.debug('Request args for %s from %s: %s', request.path, + request.getClientIP(), request.args) + self.logger.debug('Request headers for %s from %s: %s', request.path, + request.getClientIP(), request.args) + if request.path == '/DMS/SamsungDmsDesc.xml': self.logger.info('New connection from %s (%s)', request.getClientIP(), @@ -153,29 +157,35 @@ self.clients[request.getClientIP()] = request.getHeader('user-agent') response = self.GetDMSDescriptionResponse() else: - self.logger.error('Unhandled GET request: %s', request.path) + self.logger.error('Unhandled GET request from %s: %s', + request.getClientIP(), request.path) return NoResource() self.logger.debug('Response: %s', response) return response def render_POST(self, request): - self.logger.debug('Request args: %s', request.args) - self.logger.debug('Request headers: %s', request.getAllHeaders()) + self.logger.debug('Request args for %s from %s: %s', request.path, + request.getClientIP(), request.args) + self.logger.debug('Request headers for %s from %s: %s', request.path, + request.getClientIP(), request.args) if request.path == '/cd/content': response = self.ReceiveUpload(request) elif request.path == '/upnp/control/ContentDirectory1': response = self.GetContentDirectoryResponse(request) else: - self.logger.error('Unhandled POST request: %s', request.path) + self.logger.error('Unhandled POST request from %s: %s', + request.getClientIP(), request.path) return NoResource() - self.logger.debug('Response: %s', response) + self.logger.debug('Sending response for %s to %s: %s', request.path, + request.getClientIP(), response) return response def GetContentDirectoryResponse(self, request): - self.logger.debug('Request content: %s', request.content.read()) + self.logger.debug('Request content for %s from %s: %s', request.path, + request.getClientIP(), request.content.read()) request.content.seek(0) soapaction = request.getHeader('soapaction') diff --git a/pc_autobackup.py b/pc_autobackup.py old mode 100644 new mode 100755 index 1e22d58..70999dd --- a/pc_autobackup.py +++ b/pc_autobackup.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2013 Jeff Rebeiro (jeff@rebeiro.net) All rights reserved # Main runnable for PC Autobackup @@ -9,6 +9,7 @@ import optparse import platform import socket +import sys from twisted.internet import reactor from twisted.web.server import Site @@ -20,6 +21,7 @@ def GetSystemInfo(): logger = logging.getLogger('PCAutoBackup') + logger.debug('Command-line: %s', ' '.join(sys.argv)) logger.debug('Python Version: %s', platform.python_version()) logger.debug('System Information (platform): %s', platform.platform()) logger.debug('System Information (uname): %s', ' '.join(platform.uname())) @@ -42,17 +44,21 @@ default=False, help='debug output') parser.add_option('--log_file', dest='log_file', default='backup.log', help='output log to file', metavar='FILE') + parser.add_option('-n', '--name', dest='server_name', + help='change server name', metavar='NAME') parser.add_option('-o', '--output_dir', dest='output_dir', help='output directory for files', metavar='DIR') - parser.add_option('-v', '--verbose', dest='verbose', action='store_true', - default=False, help='verbose output') + parser.add_option('-q', '--quiet', dest='quiet', action='store_true', + default=False, help='only log errors to console') (options, args) = parser.parse_args() - logging_options = common.LOG_DEFAULTS + console_logging_options = common.LOG_DEFAULTS.copy() + logging_options = common.LOG_DEFAULTS.copy() - if options.verbose: - logging_options['level'] = logging.INFO + if options.quiet: + console_logging_options['level'] = logging.WARN if options.debug: + console_logging_options['level'] = logging.DEBUG logging_options['level'] = logging.DEBUG logging_options['filename'] = options.log_file @@ -60,20 +66,32 @@ logging.basicConfig(**logging_options) console = logging.StreamHandler() - console.setLevel(logging_options['level']) + console.setLevel(console_logging_options['level']) formatter = logging.Formatter('%(asctime)s %(message)s', common.LOG_DATE_FMT) console.setFormatter(formatter) logging.getLogger('').addHandler(console) config = common.LoadOrCreateConfig() + update_config = False + if options.bind: config.set('AUTOBACKUP', 'default_interface', options.bind) + update_config = True if options.output_dir: config.set('AUTOBACKUP', 'backup_dir', options.output_dir) + update_config = True + if options.server_name: + config.set('AUTOBACKUP', 'server_name', options.server_name) + update_config = True + + if update_config: + with open(common.CONFIG_FILE, 'wb') as config_file: + config.write(config_file) logger = logging.getLogger('PCAutoBackup') logger.info('PCAutoBackup started on %s', config.get('AUTOBACKUP', - 'default_interface')) + 'default_interface')) + logger.info('Server name: %s', config.get('AUTOBACKUP', 'server_name')) if options.debug: GetSystemInfo() diff --git a/ssdp.py b/ssdp.py index 4a0009d..c18edc8 100644 --- a/ssdp.py +++ b/ssdp.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2013 Jeff Rebeiro (jeff@rebeiro.net) All rights reserved # Simple SSDP implementation for PC Autobackup @@ -41,10 +41,10 @@ if m: # TODO(jrebeiro): Verify that MediaServer is the only discovery request # PCAutoBackup responds to. - self.logger.debug('Received M-SEARCH for %s from %s', m.group(3), + self.logger.debug('Received SSDP M-SEARCH for %s from %s', m.group(3), address[0]) if m.group(3) == 'MediaServer': - self.logger.info('Received discovery request from %s', address[0]) + self.logger.info('Sending SSDP response to %s', address[0]) self.SendSSDPResponse(address) def SendSSDPResponse(self, address):