diff --git a/common.py b/common.py index d8135de..8b1e179 100644 --- a/common.py +++ b/common.py @@ -6,6 +6,7 @@ __author__ = 'jeff@rebeiro.net (Jeff Rebeiro)' import ConfigParser +import logging import os import socket import uuid @@ -19,6 +20,7 @@ config.read(CONFIG_FILE) if not config.has_section('AUTOBACKUP'): + logging.info('Creating configuration file %s', CONFIG_FILE) config.add_section('AUTOBACKUP') config.set('AUTOBACKUP', 'backup_dir', os.path.expanduser('~/PCAutoBackup')) diff --git a/mediaserver.py b/mediaserver.py index 050e5ab..a3b8dc3 100644 --- a/mediaserver.py +++ b/mediaserver.py @@ -6,12 +6,14 @@ __author__ = 'jeff@rebeiro.net (Jeff Rebeiro)' import HTMLParser +import logging import os import random import re import string from twisted.internet import reactor +from twisted.web.error import NoResource from twisted.web.resource import Resource from twisted.web.server import Site @@ -94,6 +96,8 @@ def CreateObject(self, obj_name, obj_date, obj_type, obj_size): (parent_id, obj_id) = self._GenerateObjectID(obj_date) + logging.debug('Creating Backup Object for %s (type:%s size:%s)', obj_name, + obj_type, obj_size) self.backup_objects[obj_id] = {'obj_name': obj_name, 'obj_date': obj_date, 'obj_type': obj_type, @@ -117,10 +121,12 @@ obj_details['obj_date']) if not os.path.isdir(obj_dir): + logging.info('Creating output dir %s', obj_dir) os.makedirs(obj_dir) obj_file = os.path.join(obj_dir, obj_details['obj_name']) + logging.info('Saving %s', obj_file) with open(obj_file, 'wb') as f: f.write(data) @@ -131,44 +137,45 @@ isLeaf = True - def __init__(self, debug=False): + def __init__(self): self.config = common.LoadOrCreateConfig() - self.debug = debug def render_GET(self, request): - if self.debug: - print 'Request headers:' - print request.getAllHeaders() + logging.debug('Request Headers: %s', request.getAllHeaders()) if request.path == '/DMS/SamsungDmsDesc.xml': - return self.GetDMSDescriptionResponse() + logging.info('New connection from %s', request.getHeader('user-agent')) + response = self.GetDMSDescriptionResponse() else: - print 'Unhandled GET request: %s' % request.path + logging.error('Unhandled GET request: %s', request.path) + return NoResource() + + logging.debug('Response: %s', response) + return response def render_POST(self, request): - if self.debug: - print 'Request args:' - print request.args - print 'Request headers:' - print request.getAllHeaders() + logging.debug('Request args: %s', request.args) + logging.debug('Request headers: %s', request.getAllHeaders()) + if request.path == '/cd/content': - return self.ReceiveUpload(request) - if request.path == '/upnp/control/ContentDirectory1': - return self.GetContentDirectoryResponse(request) + response = self.ReceiveUpload(request) + elif request.path == '/upnp/control/ContentDirectory1': + response = self.GetContentDirectoryResponse(request) else: - print 'Unhandled POST request: %s' % request.path + logging.error('Unhandled POST request: %s', request.path) + return NoResource() + + logging.debug('Response: %s', response) + return response def GetContentDirectoryResponse(self, request): - soapaction = request.getHeader('soapaction') + logging.debug('Request content: %s', request.content.read()) + request.content.seek(0) - response = '' + soapaction = request.getHeader('soapaction') if soapaction == X_BACKUP_START: response = X_BACKUP_RESPONSE % 'START' - if self.debug: - print 'Response:' - print response - if soapaction == CREATE_OBJ: - request.content.seek(0) + elif soapaction == CREATE_OBJ: soap_xml = request.content.read() m = CREATE_OBJ_DIDL.match(soap_xml) @@ -188,43 +195,44 @@ 'obj_type': obj_type, 'obj_size': obj_size, 'parent_id': obj_details['parent_id']} - if soapaction == X_BACKUP_DONE: + elif soapaction == X_BACKUP_DONE: response = X_BACKUP_RESPONSE % 'DONE' + else: + logging.error('Unhandled soapaction: %s', soapaction) + return NoResource() - if self.debug: - print 'Response:' - print response return response def GetDMSDescriptionResponse(self): response = DMS_DESC_RESPONSE % { 'friendly_name': self.config.get('AUTOBACKUP', 'server_name'), 'uuid': self.config.get('AUTOBACKUP', 'uuid')} - if self.debug: - print 'Response:' - print response return response def ReceiveUpload(self, request): response = '' + obj_id = request.args['didx'][0].split('=')[1] backup = Backup() data = request.content.read() backup.WriteObject(obj_id, data) + return response -def StartMediaServer(debug=False): - resource = MediaServer(debug=debug) +def StartMediaServer(): + logging.info('MediaServer started') + resource = MediaServer() factory = Site(resource) reactor.listenTCP(52235, factory) reactor.run() def main(): - StartMediaServer(debug=True) + logging.basicConfig(filename='mediaserver.log', level=logging.DEBUG) + StartMediaServer() if __name__ == '__main__': diff --git a/pc-autobackup.py b/pc-autobackup.py index b24e462..4d9afb7 100644 --- a/pc-autobackup.py +++ b/pc-autobackup.py @@ -5,6 +5,7 @@ __author__ = 'jeff@rebeiro.net (Jeff Rebeiro)' +import logging import optparse from twisted.internet import reactor @@ -18,22 +19,43 @@ def main(): parser = optparse.OptionParser() parser.add_option('-b', '--bind', dest='bind', - help='Bind the server to a specific IP', - metavar='IPADDRESS') - parser.add_option('-d', '--debug', dest='debug', action="store_true", - default=False, help='Print debug information') + help='bind the server to a specific IP', + metavar='IP') + parser.add_option('-d', '--debug', dest='debug', action='store_true', + default=False, help='debug output') + parser.add_option('--log_file', dest='log_file', + help='output log to file', metavar='FILE') + 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') (options, args) = parser.parse_args() + logging_options = {'level': logging.WARN} + + if options.verbose: + logging_options['level'] = logging.INFO + if options.debug: + logging_options['level'] = logging.DEBUG + if options.log_file: + logging_options['filename'] = options.log_file + + logging.basicConfig(**logging_options) + + logging.info('pc-autobackup started') + config = common.LoadOrCreateConfig() if options.bind: config.set('AUTOBACKUP', 'default_interface', options.bind) + if options.output_dir: + config.set('AUTOBACKUP', 'backup_dir', options.output_dir) - #ssdp.StartSSDPServer(debug=options.debug) - #mediaserver.StartMediaServer(debug=options.debug) - resource = mediaserver.MediaServer(debug=options.debug) + resource = mediaserver.MediaServer() factory = Site(resource) - reactor.listenMulticast(1900, ssdp.SSDPServer(debug=options.debug)) + reactor.listenMulticast(1900, ssdp.SSDPServer()) + logging.info('SSDPServer started') reactor.listenTCP(52235, factory) + logging.info('MediaServer started') reactor.run() diff --git a/ssdp.py b/ssdp.py index 4a0bad1..0327979 100644 --- a/ssdp.py +++ b/ssdp.py @@ -6,6 +6,7 @@ __author__ = 'jeff@rebeiro.net (Jeff Rebeiro)' import ConfigParser +import logging import re from twisted.internet import reactor @@ -27,9 +28,8 @@ class SSDPServer(DatagramProtocol): - def __init__(self, debug=False): + def __init__(self): self.config = common.LoadOrCreateConfig() - self.debug = debug def startProtocol(self): self.transport.setTTL(5) @@ -40,8 +40,7 @@ if m: # TODO(jrebeiro): Verify that MediaServer is the only discovery request # PCAutoBackup responds to. - if self.debug: - print 'Received M-SEARCH for %s from %r' % (m.group(3), address) + logging.debug('Received M-SEARCH for %s from %r', m.group(3), address) if m.group(3) == 'MediaServer': self.SendSSDPResponse(address) @@ -55,18 +54,18 @@ 'default_interface'), self.config.get('AUTOBACKUP', 'uuid')) self.transport.write(response, address) - if self.debug: - print "Response:" - print response + logging.debug('Response: %s', response) -def StartSSDPServer(debug=False): - reactor.listenMulticast(1900, SSDPServer(debug=debug)) +def StartSSDPServer(): + logging.info('SSDPServer started') + reactor.listenMulticast(1900, SSDPServer()) reactor.run() def main(): - StartSSDPServer(debug=True) + logging.basicConfig(filename='ssdp.log', level=logging.DEBUG) + StartSSDPServer() if __name__ == "__main__":