1 # Cowbell images: http://commons.wikimedia.org/wiki/Image:Cowbell-1.jpg 2 import os 3 import re 4 from paste.fileapp import FileApp 5 from paste.response import header_value, remove_header 6 7 SOUND = "http://www.c-eye.net/eyeon/WalkenWAVS/explorestudiospace.wav" 8 9 class MoreCowbell(object): 10 def __init__(self, app): 11 self.app = app 12 def __call__(self, environ, start_response): 13 path_info = environ.get('PATH_INFO', '') 14 script_name = environ.get('SCRIPT_NAME', '') 15 for filename in ['bell-ascending.png', 'bell-descending.png']: 16 if path_info == '/.cowbell/'+ filename: 17 app = FileApp(os.path.join(os.path.dirname(__file__), filename)) 18 return app(environ, start_response) 19 type = [] 20 body = [] 21 def repl_start_response(status, headers, exc_info=None): 22 ct = header_value(headers, 'content-type') 23 if ct and ct.startswith('text/html'): 24 type.append(ct) 25 remove_header(headers, 'content-length') 26 start_response(status, headers, exc_info) 27 return body.append 28 return start_response(status, headers, exc_info) 29 app_iter = self.app(environ, repl_start_response) 30 if type: 31 # Got text/html 32 body.extend(app_iter) 33 body = ''.join(body) 34 body = insert_head(body, self.javascript.replace('__SCRIPT_NAME__', script_name)) 35 body = insert_body(body, self.resources.replace('__SCRIPT_NAME__', script_name)) 36 return [body] 37 else: 38 return app_iter 39 40 javascript = '''\ 41 <script type="text/javascript"> 42 var cowbellState = 'hidden'; 43 var lastCowbellPosition = null; 44 function showSomewhere() { 45 var sec, el; 46 if (cowbellState == 'hidden') { 47 el = document.getElementById('cowbell-ascending'); 48 lastCowbellPosition = [parseInt(Math.random()*(window.innerWidth-200)), 49 parseInt(Math.random()*(window.innerHeight-200))]; 50 el.style.left = lastCowbellPosition[0] + 'px'; 51 el.style.top = lastCowbellPosition[1] + 'px'; 52 el.style.display = ''; 53 cowbellState = 'ascending'; 54 sec = 1; 55 } else if (cowbellState == 'ascending') { 56 document.getElementById('cowbell-ascending').style.display = 'none'; 57 el = document.getElementById('cowbell-descending'); 58 el.style.left = lastCowbellPosition[0] + 'px'; 59 el.style.top = lastCowbellPosition[1] + 'px'; 60 el.style.display = ''; 61 cowbellState = 'descending'; 62 sec = 1; 63 } else { 64 document.getElementById('cowbell-descending').style.display = 'none'; 65 cowbellState = 'hidden'; 66 sec = Math.random()*20; 67 } 68 setTimeout(showSomewhere, sec*1000); 69 } 70 setTimeout(showSomewhere, Math.random()*20*1000); 71 </script> 72 ''' 73 74 resources = '''\ 75 <div id="cowbell-ascending" style="display: none; position: fixed"> 76 <img src="__SCRIPT_NAME__/.cowbell/bell-ascending.png"> 77 </div> 78 <div id="cowbell-descending" style="display: none; position: fixed"> 79 <img src="__SCRIPT_NAME__/.cowbell/bell-descending.png"> 80 </div> 81 ''' 82 83 def insert_head(body, text): 84 end_head = re.search(r'</head>', body, re.I) 85 if end_head: 86 return body[:end_head.start()] + text + body[end_head.end():] 87 else: 88 return text + body 89 90 def insert_body(body, text): 91 end_body = re.search(r'</body>', body, re.I) 92 if end_body: 93 return body[:end_body.start()] + text + body[end_body.end():] 94 else: 95 return body + text 96 97 def make_cowbell(global_conf, app): 98 return MoreCowbell(app) 99 100 if __name__ == '__main__': 101 from paste.debug.debugapp import SimpleApplication 102 app = MoreCowbell(SimpleApplication()) 103 from paste.httpserver import serve 104 serve(app) 105