Skip to content
Browse files

new django example

git-svn-id: http://evserver.googlecode.com/svn/trunk@87 e9bb6d7e-af12-11dd-bad7-87afd3b02348
  • Loading branch information...
1 parent f9fc3ee commit 0c42eae39d4c4d6fdae1c5b4b7df622f7f8d7d9c majek04 committed Feb 9, 2009
View
0 evserver/examples/django_agentpush/__init__.py
No changes.
View
11 evserver/examples/django_agentpush/manage.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+from django.core.management import execute_manager
+try:
+ import settings # Assumed to be in the same directory.
+except ImportError:
+ import sys
+ sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+ sys.exit(1)
+
+if __name__ == "__main__":
+ execute_manager(settings)
View
86 evserver/examples/django_agentpush/settings.py
@@ -0,0 +1,86 @@
+# Django settings for agentpush project.
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+ # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = '' # Or path to database file if using sqlite3.
+DATABASE_USER = '' # Not used with sqlite3.
+DATABASE_PASSWORD = '' # Not used with sqlite3.
+DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
+DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'America/Chicago'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = ''
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '(lwr-lwh(09f0$pd8s@(0op#css$_#yo3(xyl_vq(k9uwk0cqs'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+ 'django.template.loaders.filesystem.load_template_source',
+ 'django.template.loaders.app_directories.load_template_source',
+# 'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+)
+
+ROOT_URLCONF = 'django_agentpush.urls'
+
+TEMPLATE_DIRS = (
+ # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
+ # Always use forward slashes, even on Windows.
+ # Don't forget to use absolute paths, not relative paths.
+)
+
+INSTALLED_APPS = (
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.sites',
+ 'evserver', # <<< THIS LINE enables runevserver command
+)
+
+import os.path
+STATIC_DIR = os.path.join(os.getcwd(), 'static')
+assert os.path.isdir(STATIC_DIR)
+
+
View
633 evserver/examples/django_agentpush/static/comet.js
@@ -0,0 +1,633 @@
+/*
+ Based on orbited.js from the Orbited project.
+*/
+
+/********************************************************************/
+/** settings **/
+/* how long to wait after the connection is lost (server died) */
+comet_restart_timeout = 8000; // 5 seconds
+/* if no keepalive in this time - reconnect */
+comet_keepalive_timeout = 76*1000; // 66 seconds with no data
+
+/********************************************************************/
+
+
+
+/********************************************************************/
+/** comet engines **/
+/*
+ parameters:
+ url - url string to connect to, should contain ? character
+ inside, we're going to append &transport= to it.
+ callback - user callback function
+ server_reconnect - the function that is going to be called
+ when the connection will be lost
+ return value:
+ - function that is going to destroy current conenction
+ for garbage collecting
+ */
+
+/* xhr stream, for firefox and safari */
+function schedule_connection_xhr(url, callback, server_reconnect) {
+ var boundary = '\r\n|O|\r\n';
+ var xhr = null;
+ var offset = 0;
+
+ var onreadystatechange = function(event) {
+ if(!xhr)
+ return;
+ if(xhr.readyState==4)
+ server_reconnect(true);
+ else if(xhr.readyState==3 && xhr.status==200) {
+ /* skip initial padding */
+ if(offset == 0){
+ offset = xhr.responseText.indexOf('\r\n\r\n');
+ if(offset == -1)
+ offset = 0;
+ else
+ offset += 4;
+ }
+ while(true){
+ if(!xhr || !xhr.responseText)
+ break;
+ var data = xhr.responseText.substr(offset);
+ var end = data.indexOf(boundary);
+ if(end == -1)
+ break;
+ offset = offset + end + boundary.length;
+ callback( decode_utf8(data.substr(0, end)) );
+ }
+ }
+ }
+ xhr = comet_create_ajax(url + '&transport=xhr', 'GET', null, onreadystatechange);
+
+ function xhr_gc(){
+ if(xhr){
+ try{
+ xhr.onreadystatechange=function () {};
+ xhr.abort();
+ }catch(e){};
+ }
+ delete(xhr);
+ delete(offset);
+ offset = null;
+ xhr = null;
+ };
+
+ return xhr_gc;
+}
+
+
+/* long polling */
+function schedule_connection_longpoll(url, callback, server_reconnect) {
+ var xhr = null;
+ var eid = 0;
+ var schedule = function(){
+ if(xhr){
+ try{
+ xhr.onreadystatechange=function () {};
+ xhr.abort();
+ }catch(e){};
+ try{
+ delete(xhr);
+ }catch(e){};
+ }
+ var onreadystatechange = function() {
+ if(!xhr)
+ return;
+ if(xhr.readyState==4){
+ if(xhr.status==200){
+ eid += 1;
+ var data = xhr.responseText;
+ if(schedule)
+ schedule();
+
+ callback( data );
+ }else{
+ server_reconnect(true);
+ }
+ }
+ }
+ xhr = comet_create_ajax(url + '&transport=longpoll&eid=' + eid, 'GET', null, onreadystatechange)
+ };
+
+ schedule();
+
+ function xhr_gc(){
+ if(xhr){
+ try{
+ xhr.onreadystatechange=function () {};
+ xhr.abort();
+ }catch(e){};
+ }
+ delete(xhr);
+ xhr = null;
+ delete(schedule);
+ schedule = null;
+ };
+
+ return xhr_gc;
+}
+
+
+
+/* htmlfile, for ie */
+function schedule_connection_htmlfile(url, user_callback, server_reconnect) {
+ var i=0; while(window['c'+i] != undefined) i += 1;
+ var fname = 'c' + i;
+
+ function recon(){
+ server_reconnect(true);
+ }
+ window[fname] = user_callback;
+ window[fname + '_reconnect'] = recon;
+
+ var transferDoc = new ActiveXObject('htmlfile');
+ transferDoc.open();
+ transferDoc.write(
+ '<html><script>\n' +
+ ' document.domain = "' + document.domain + '";\n' +
+ '</script></html>\n');
+ transferDoc.close();
+ var ifrDiv = transferDoc.createElement("div");
+ transferDoc.parentWindow[fname] = user_callback;
+ transferDoc.parentWindow[fname +'_reconnect'] = recon;
+ transferDoc.body.appendChild(ifrDiv);
+ ifrDiv.innerHTML = "<iframe src='" + url +
+ '&transport=htmlfile'+
+ '&domain=' + document.domain +
+ '&callback=' + fname +
+ "' ></iframe>";
+
+ // for ie 6
+ kill_load_bar();
+ function htmlfile_close() {
+ window[fname] = function(){};
+ window[fname+'_reconnect'] = function(){};
+ if(transferDoc){
+ transferDoc.body.removeChild(ifrDiv);
+ delete(trasferDoc);
+ transferDoc = null;
+ }
+ if(ifrDiv){
+ delete(ifrDiv);
+ ifrDiv = null;
+ }
+ CollectGarbage();
+ }
+ comet_attach_unload_event(htmlfile_close);
+ return htmlfile_close;
+}
+
+/* iframe, fallback for konqueror */
+function schedule_connection_iframe(url, user_callback, server_reconnect) {
+ var i=0; while(window['c'+i] != undefined) i += 1;
+ var fname = 'c' + i;
+ window[fname] = function (data){
+ user_callback(data);
+ kill_load_bar();
+ }
+ window[fname + '_reconnect'] = function(){
+ server_reconnect(true);
+ }
+
+ var ifr = document.createElement('iframe');
+ hide_iframe(ifr);
+ ifr.setAttribute('src', url +
+ '&transport=iframe'+
+ '&callback=' + fname );
+ document.body.appendChild(ifr);
+
+ kill_load_bar();
+ var gc = function () {
+ window[fname] = function(){};
+ window[fname+'_reconnect'] = function(){};
+ if(ifr){
+ document.body.removeChild(ifr);
+ delete(ifr);
+ ifr=null;
+ }
+ try{
+ CollectGarbage();
+ }catch(e){};
+ };
+ comet_attach_unload_event(gc);
+ return gc;
+}
+function hide_iframe(ifr) {
+ ifr.style.display = 'block';
+ ifr.style.width = '0';
+ ifr.style.height = '0';
+ ifr.style.border = '0';
+ ifr.style.margin = '0';
+ ifr.style.padding = '0';
+ ifr.style.overflow = 'hidden';
+ ifr.style.visibility = 'hidden';
+}
+
+
+
+
+/* server_sent_events for opera
+opera 9.60 is delivering messages _TWICE_.
+to fix that we need to keep track on messages. fuck.
+If they will fix it, it's going to be a huge memory drainer.
+*/
+function schedule_connection_sse(url, callback) {
+ var es = document.createElement('event-source');
+ es.setAttribute('src', url +"&transport=sse");
+ document.body.appendChild(es);
+
+ var last_events = {};
+ var event_callback = function (event){
+ var k = event.data.substr(0,32);
+ if(last_events[k]){
+ comet_log('REPEATED EVENT: ' + event.data);
+ delete(last_events[k]);
+ return;
+ }
+ if(callback){
+ if(event.data)
+ callback(decode_utf8(unescape(event.data)));
+ }
+
+ last_events[k] = true;
+ };
+
+ es.addEventListener('payload', event_callback, false);
+
+
+ var gc = function () {
+ if(es){
+ es.removeEventListener('payload', event_callback, false);
+ document.body.removeChild(es);
+ es.src='';
+ }
+ event_callback=null;
+ delete(es);
+ es = null;
+ };
+ return gc;
+}
+
+
+comet_transports = {
+ xhr: schedule_connection_xhr,
+ xhrstream: schedule_connection_xhr,
+ longpoll: schedule_connection_longpoll,
+ htmlfile: schedule_connection_htmlfile,
+ iframe: schedule_connection_iframe,
+ sse: schedule_connection_sse
+};
+/********************************************************************/
+/** find proper transport for current browser **/
+function guess_transport() {
+ // IF we're on IE 5.01/5.5/6/7 we want to use an htmlfile
+ try {
+ var test = ActiveXObject;
+ return 'htmlfile';
+ }catch (e) {}
+
+ // If the browser supports server-sent events, we should use those
+ if ((typeof window.addEventStream) == 'function') {
+ return 'sse';
+ }
+
+ if( navigator.userAgent.indexOf('Konqueror')!= -1)
+ return 'iframe';
+
+ if( navigator.userAgent.indexOf('Safari')!= -1 || navigator.userAgent.indexOf('Webkit')!= -1){
+ return 'xhrstream';
+ }
+
+ return 'xhrstream';
+}
+
+transport_global = guess_transport();
+
+
+
+/********************************************************************/
+/** The Most Important Function. schedule connection for user **/
+/*
+ url - static url or function that returns url
+ user_callback - callback function, is going to be called each time with
+ one parameter - data
+ */
+function comet_connection(url, user_callback_o, transport_local) {
+ var keepalive_timer = null;
+ var connect_function = null;
+ var garbage_function = null;
+ var comet_transport = '';
+ function get_url(url){
+ var c = url;
+ if(typeof(url) == "function")
+ c = url();
+
+ if(c.indexOf('?') == -1)
+ c = c + '?a=' + Math.random();
+ return c;
+ }
+ function user_callback(data){
+ /*
+ if(strip(data) == '' || data == 'ping'){
+ //comet_log('comet: got keepalive');
+ return;
+ }
+ */
+ //comet_log('comet: got data length:' + data.length);
+ if(typeof(data) != "string" && typeof(data)!="String")
+ data = '';
+ user_callback_o(data);
+ }
+ function server_reconnect(conn_broken) {
+ if(conn_broken == true){
+ if(garbage_function)
+ garbage_function();
+ garbage_function = null;
+
+ comet_log('comet: '+comet_transport +' conn broken, reconnecting in '+ comet_restart_timeout +'....');
+ setTimeout(function () {
+ garbage_function = connect_function(get_url(url), callback, server_reconnect);
+ }, comet_restart_timeout);
+ }else{
+ comet_log('comet: '+comet_transport +' no keepalive reconnecting now...');
+ if(garbage_function)
+ garbage_function();
+ garbage_function = null;
+ garbage_function = connect_function(get_url(url), callback, server_reconnect);
+ }
+ update_keepalive();
+ }
+ function update_keepalive() {
+ clearTimeout(keepalive_timer);
+ keepalive_timer = setTimeout( server_reconnect, comet_keepalive_timeout);
+ }
+ keepalive_timer = setTimeout( server_reconnect, comet_keepalive_timeout);
+
+ var callback = function (data){
+ update_keepalive();
+ user_callback(data);
+ };
+
+ if(!transport_local){
+ comet_transport = transport_global;
+ }else{
+ comet_transport = transport_local;
+ }
+ comet_log('comet: using transport:' + comet_transport +' restart_timeout:' + comet_restart_timeout + ' keepalive_timeout:' + comet_keepalive_timeout);
+ connect_function = comet_transports[comet_transport];
+
+ if(!connect_function){
+ comet_log('comet: bad transport: '+ comet_transport);
+ return null;
+ }
+
+ garbage_function = connect_function(get_url(url), callback, server_reconnect);
+ var xx = function (){
+ clearTimeout(keepalive_timer);
+ if(garbage_function)
+ garbage_function();
+ if(comet_log)
+ comet_log('comet: cleaning connection');
+ }
+ return xx;
+}
+
+
+
+
+/********************************************************************/
+function comet_crossdomain_connection(iframe_uri, comet_uri, user_callback, transport){
+ var i=0; while(window['c'+i] != undefined) i += 1;
+ var fname = 'c' + i;
+ var transportstr = '';
+ if(transport)
+ transportstr = '&transport=' + transport;
+
+ comet_log('cometcrossdomain: started');
+ window[fname] = user_callback;
+ window[fname + '_uri'] = comet_uri;
+
+ if(iframe_uri.indexOf('?') == -1)
+ iframe_uri = iframe_uri + '?a=' + Math.random()
+
+ var ifr = document.createElement('iframe');
+ hide_iframe(ifr);
+ ifr.setAttribute('src', iframe_uri +
+ '&callback=' + fname + transportstr);
+ document.body.appendChild(ifr);
+ function garbc(){
+ if(ifr){
+ comet_log('cometcrossdomain: stopped');
+ var doc = ifr.contentDocument;
+ if(doc == undefined || doc == null){
+ doc = null;
+ if(ifr.contentWindow)
+ doc = ifr.contentWindow.document;
+ }
+ try{
+ if(doc && doc.comet_garbage)
+ doc.comet_garbage();
+ }catch(e){};
+ document.body.removeChild(ifr);
+ delete(ifr);
+ ifr=null;
+ }
+ window[fname] = function(){};
+ window[fname + '_uri'] = null;
+ }
+ comet_attach_unload_event(garbc);
+ return garbc;
+}
+
+
+/********************************************************************/
+function comet_create_crossdomain_ajax(iframe_uri, ajax_uri, method, post_data, user_callback, mimetype) {
+ var queue_key = escape(iframe_uri) + '_queue';
+ var garbc_key = escape(iframe_uri) + '_garbc';
+ var push_key = escape(iframe_uri) + '_push';
+ if(window[queue_key] == undefined){
+ window[queue_key] = [];
+ window[push_key] = function(){};
+ }
+
+ var v = [ajax_uri, method, post_data, user_callback, mimetype];
+ window[queue_key] = ([v]).concat(window[queue_key]);
+ window[push_key]();
+
+ if(window[garbc_key] == undefined) {
+ window[garbc_key] = comet_create_crossdomain_ajax_iframe(iframe_uri);
+ }
+}
+
+function comet_create_crossdomain_ajax_iframe(iframe_uri) {
+ var i=0; while(window['ajc'+i] != undefined) i += 1;
+ var fname = 'ajc' + i;
+ var ifr;
+ window[fname] = escape(iframe_uri);
+ var queue_key = fname + '_data';
+
+
+ if(iframe_uri.indexOf('?') == -1)
+ iframe_uri = iframe_uri + '?a=' + Math.random()
+
+ ifr = document.createElement('iframe');
+ hide_iframe(ifr);
+ ifr.setAttribute('src', iframe_uri +
+ '&callback=' + fname);
+ document.body.appendChild(ifr);
+ kill_load_bar();
+
+ var garbc = function(){
+ if(ifr){
+ document.body.removeChild(ifr);
+ delete(ifr);
+ ifr=null;
+ }
+ window[fname] = null;
+ }
+ comet_attach_unload_event(garbc);
+ return garbc;
+}
+
+
+
+
+/********************************************************************/
+/** various helpers **/
+/********************************************************************/
+function strip(str) {
+ return str.replace(/^\s*(.*?)\s*$/, "$1");
+ return(str);
+}
+
+function getURLParam(strParamName){
+ var strReturn = "";
+ var strHref = window.location.href;
+ if ( strHref.indexOf("?") > -1 ){
+ var strQueryString = strHref.substr(strHref.indexOf("?")).toLowerCase();
+ var aQueryString = strQueryString.split("&");
+ for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
+ if(aQueryString[iParam].indexOf(strParamName.toLowerCase() + "=") > -1 ){
+ var aParam = aQueryString[iParam].split("=");
+ strReturn = aParam[1];
+ break;
+ }
+ }
+ }
+ return unescape(strReturn);
+}
+
+
+function comet_log(arg){
+ arg = arg.substr(0, 512);
+ if (typeof window.console !== 'undefined') {
+ console.log(arg);
+ }
+ else if (typeof window.opera !== 'undefined') {
+ opera.postError(arg);
+ }else if (window['YAHOO'] && YAHOO.log){
+ YAHOO.log(arg, 'info');
+ }/*else
+ alert(arg);
+ */
+}
+
+
+function comet_raw_xhr() {
+ try { return new ActiveXObject('MSXML3.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('MSXML2.XMLHTTP.3.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+ try { return new XMLHttpRequest(); } catch(e) {}
+ throw new Error('Could not find XMLHttpRequest or an alternative.');
+}
+
+function comet_create_xhr() {
+ var xhr = comet_raw_xhr();
+ // stolen from http://blog.mibbit.com/?p=143
+ function safeSet(k, v) {
+ try {
+ xhr.setRequestHeader(k, v);
+ } catch(e) {}
+ }
+
+ safeSet("User-Agent", null);
+ safeSet("Accept", null);
+ safeSet("Accept-Language", null);
+ safeSet("Content-Type", "M");
+ safeSet("Connection", "keep-alive");
+ safeSet("Keep-Alive", null);
+ return(xhr);
+}
+
+function comet_create_ajax(url, method, data, onreadystatechange, mimetype) {
+ var xhr = comet_create_xhr();
+ xhr.open(method, url, true);
+ if(data){
+ if(!mimetype)
+ mimetype = "application/x-www-form-urlencoded";
+ xhr.setRequestHeader("Content-type", mimetype);
+ xhr.setRequestHeader("Content-length", data.length);
+ }
+ if(onreadystatechange)
+ xhr.onreadystatechange = onreadystatechange;
+ xhr.send(data);
+ return(xhr);
+}
+
+
+load_kill_ifr = null;
+function kill_load_bar() {
+ if (load_kill_ifr == null) {
+ load_kill_ifr = document.createElement('iframe');
+ hide_iframe(load_kill_ifr);
+ }
+ document.body.appendChild(this.load_kill_ifr);
+ document.body.removeChild(this.load_kill_ifr);
+}
+
+function comet_attach_unload_event(foo){
+ if(window.addEventListener){
+ document.addEventListener('unload', foo, false);
+ window.addEventListener('unload', foo, false);
+ } else { // IE
+ document.attachEvent('onunload', foo);
+ window.attachEvent('onunload', foo);
+ }
+}
+
+function extract_xss_domain(old_domain) {
+ var domain_pieces = old_domain.split('.');
+ if (domain_pieces.length === 4) {
+ var is_ip = !isNaN(Number(domain_pieces.join('')));
+ if (is_ip) {
+ return old_domain;
+ }
+ }
+ var new_domain = domain_pieces.slice(-2).join('.');
+ var colon = old_domain.split(':');
+ if(colon.length > 1)
+ return new_domain + ':' + colon[1];
+ return new_domain;
+}
+
+function encode_utf8( s )
+{
+ try{
+ return unescape( encodeURIComponent( s ) );
+ }catch(e){
+ return(s);
+ }
+}
+
+function decode_utf8( s )
+{
+ try{
+ return decodeURIComponent( escape( s ) );
+ }catch(e){
+ return(s);
+ }
+}
+
View
26 evserver/examples/django_agentpush/static/index.html
@@ -0,0 +1,26 @@
+<style type="text/css">
+pre {
+ border: 1px dashed #333333;
+ padding: 10px;
+ height: 80%;
+ width:80%;
+ overflow:scroll;
+
+}
+</style>
+
+<script src="./static/comet.js" type="text/javascript"></script>
+
+<h3>Real-time referers log:</h3>
+<pre id='p' >
+</pre>
+
+<script>
+var p = document.getElementById('p');
+function user_callback(data){
+ var i = p.innerHTML
+ p.innerHTML = i + '<br>'+data;
+ p.scrollTop = p.scrollHeight;
+}
+close_comet_function = comet_connection('./comet/', user_callback);
+</script>
View
13 evserver/examples/django_agentpush/urls.py
@@ -0,0 +1,13 @@
+from django.conf.urls.defaults import *
+import django.views.static
+from django.conf import settings
+import views
+
+
+urlpatterns = patterns('',
+ (r'^static/(?P<path>.*)$', django.views.static.serve, {'document_root': settings.STATIC_DIR}),
+ (r'^$', views.index),
+ (r'^index.html$', views.index),
+ (r'^comet/$', views.comet),
+)
+
View
141 evserver/examples/django_agentpush/views.py
@@ -0,0 +1,141 @@
+'''
+# PYTHONPATH="$HOME/evserver:$HOME/amqplib-0.6"
+ ./manage.py runevserver
+
+or
+ PYTHONPATH="$HOME/amqplib-0.6:.." DJANGO_SETTINGS_MODULE=django_agentpush.settings
+ evserver --listen 127.0.0.1:8080 --framework=django
+
+Beware, static files are served from ./static directory!
+'''
+
+from django.http import HttpResponse
+from django.conf import settings
+
+import socket
+import datetime
+import sys
+import time
+import os.path
+import socket
+import evserver.transports
+import logging
+import amqplib.client_0_8 as amqp
+logging.getLogger('amqplib').setLevel(logging.INFO) # ignore msgs from there
+log = logging.getLogger(os.path.basename(__file__))
+
+
+cached_publisher_connection = None
+cached_publisher_channel = None
+
+def send_amqp_message(msg_body):
+ global cached_publisher_connection, cached_publisher_channel
+ if not cached_publisher_channel:
+ conn = amqp.Connection('localhost', userid='guest', password='guest')
+ ch = conn.channel()
+ ch.access_request('/data', active=True, write=True)
+ ch.exchange_declare('myfan', 'fanout', auto_delete=True)
+
+ cached_publisher_connection = conn
+ cached_publisher_channel = ch
+
+ msg = amqp.Message(msg_body, content_type='text/plain')
+ cached_publisher_channel.basic_publish(msg, 'myfan')
+
+
+import cgi
+
+# that is a raw hack that doesn't scale!
+counter = 0
+state_cache = []
+
+def index(request):
+ global counter
+ counter += 1
+
+ referer = request.META.get('HTTP_REFERER', '')
+ agent = request.META.get('HTTP_USER_AGENT', '')
+ msg = cgi.escape('#%i: %r %r' % (counter, referer, agent))
+ send_amqp_message(msg)
+ state_cache.append(msg)
+ if len(state_cache) > 30: state_cache.pop(0) # remove first element
+
+ f = open(os.path.join(settings.STATIC_DIR, 'index.html'), 'rb')
+ data = f.read()
+ f.close()
+
+ return HttpResponse(data, mimetype="text/html")
+
+
+
+
+def set_ridiculously_high_buffers(sd):
+ for flag in [socket.SO_SNDBUF, socket.SO_RCVBUF]:
+ for i in range(10):
+ bef = sd.getsockopt(socket.SOL_SOCKET, flag)
+ sd.setsockopt(socket.SOL_SOCKET, flag, bef*2)
+ aft = sd.getsockopt(socket.SOL_SOCKET, flag)
+ if aft <= bef or aft >= 16777216: # 16M
+ break
+
+def comet(request):
+ t = evserver.transports.get_transport(request.GET.get('transport','basic'))
+
+ # setup the amqp subscriber
+ msgs = []
+ def callback(msg):
+ msgs.append(msg.body)
+ msg.channel.basic_ack(msg.delivery_tag)
+
+ t0 = time.time()
+ conn = amqp.Connection('localhost', userid='guest', password='guest')
+
+ ch = conn.channel()
+ ch.access_request('/data', active=True, read=True)
+
+ ch.exchange_declare('myfan', 'fanout', auto_delete=True)
+ qname, _, _ = ch.queue_declare()
+ ch.queue_bind(qname, 'myfan')
+ ch.basic_consume(qname, callback=callback)
+
+ sd = conn.transport.sock
+ sd.setblocking(False)
+ set_ridiculously_high_buffers(sd)
+
+ def iterator():
+ try:
+ yield t.start()
+ for msg in state_cache:# feed with the initial state
+ yield t.write(msg)
+
+ while ch.callbacks:
+ try:
+ while True: # until exception
+ ch.wait()
+ except (TypeError,), e:
+ pass
+
+ while msgs:
+ msg = msgs.pop(0)
+ yield t.write(msg)
+
+ yield request.environ['x-wsgiorg.fdevent.readable'](conn.transport.sock)
+ except GeneratorExit:
+ pass
+
+ try:
+ ch.close()
+ except Exception:
+ pass
+ try:
+ conn.close()
+ except Exception:
+ pass
+
+ # build the response
+ response = HttpResponse(iterator())
+ for k, v in t.get_headers():
+ response[k] = v
+ return response
+
+

0 comments on commit 0c42eae

Please sign in to comment.
Something went wrong with that request. Please try again.