from datetime import datetime import xmlrpclib import BaseHTTPServer from urlparse import urlparse, parse_qs import urllib2 # Following URLs are examples for the 3 different kinds of log events. # url_viewed : # mail_viewed : # attachment_viewed : # Where do we listen for requests? http_address = 'localhost' http_port = 8880 # Print debug statements to console? debugprint = True # General fields; change to reflect installation parameters xmlrpc_path = 'http://localhost:8069/xmlrpc/object' xmlrpc_model = 'mck.base.tracklog' xmlrpc_method = 'generate_event_log' db = 'mck_us' uid = 1 pwd = 'd' # Image types, attachment types image_types = ['jpg', 'jpeg', 'gif', 'png'] attachment_types = ['pdf', 'xls', 'xlsx', 'doc', 'docx'] # Content of the error page error_page = """ An error occured.

The resource you requested can not be found. We apologise for the inconvenience

""" class LogTracker(BaseHTTPServer.BaseHTTPRequestHandler): # Fetches the content, and returns response code, Content-type parameter and actual content def get_content(self, url): try: req = urllib2.Request(url) response = urllib2.urlopen(req) info = content_type = info['Content-Type'] content = return (200, content_type, content) except urllib2.URLError: return (503, 'text/html', error_page) # Serves content to the client def serve_content(self, code, content_type, content): self.send_response(code) self.send_header("Content-type", content_type) self.end_headers() self.wfile.write(content) # Main method that responds to client requests def do_GET(self): dt_log ='%Y-%m-%d %H:%M:%S') parsed_path = urlparse(self.path) get_params = parse_qs(parsed_path.query) # Return an error page if there's no "url" parameter as it's required for the rest to work if not 'url' in get_params: log_url = '' self.serve_content(503, 'text/html', error_page) return # Get the "url" parameter log_url = urllib2.unquote(get_params['url'][0]) # And analyse it to determine the type of resource that was requested (image, attachment, anything else) parsed_url = urlparse(log_url) resource_type = parsed_url.path.split('/')[-1].split('.')[-1] if resource_type.lower() in image_types: log_type = 'mail_viewed' elif resource_type in attachment_types: log_type = 'attachment_viewed' else: log_type = 'url_viewed' # Get the client's IP, and the template + invitee tracking strings log_ip = self.client_address[0] tpl_track_str = get_params['t'][0] inv_track_str = get_params['i'][0] # Do the redirection, or serve the content if log_type == 'url_viewed': self.send_response(301) self.send_header("Location", log_url) self.end_headers() else: (response_code, resource_type, content_to_serve) = self.get_content(log_url) self.serve_content(response_code, resource_type, content_to_serve) if debugprint: print """ Date : %s IP : %s File type : %s Status : %s URL : %s Template : %s Invitee : %s """ % (dt_log, log_ip, resource_type, log_type, log_url, tpl_track_str, inv_track_str) # For testing purposes, the following two lines can be commented out. That way, no connection to OpenERP is made. sock = xmlrpclib.ServerProxy(xmlrpc_path) sock.execute(db, uid, pwd, xmlrpc_model, xmlrpc_method, dt_log, log_type, log_ip, log_url, tpl_track_str, inv_track_str) if __name__ == '__main__': server = BaseHTTPServer.HTTPServer((http_address, http_port), LogTracker) print 'Starting server, use to stop.' try: server.serve_forever() except KeyboardInterrupt: # Just printing an empty line so the CTRL-C doesn't appear before the "Stopped server" message. print '' server.server_close() print 'Stopped server.'