Home | History | Annotate | Download | only in cowbell
      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