Merged [5614] and [5622] from mcr@sandelman.ca: added dajaxice.

- Legacy-Id: 5786
Note: SVN reference [5614] has been migrated to Git commit 7e0e027149a37e2fac0b2809e8a18c896f660687

Note: SVN reference [5622] has been migrated to Git commit bde631c87ffd2ce5a93fe3c0559aafef04d23b1f
This commit is contained in:
Henrik Levkowetz 2013-06-10 20:47:51 +00:00
parent ec2550db84
commit c1c529f9ae
29 changed files with 1289 additions and 0 deletions

1
dajaxice/__init__.py Normal file
View file

@ -0,0 +1 @@
VERSION = (0, 2, 0, 0, 'beta')

181
dajaxice/core/Dajaxice.py Normal file
View file

@ -0,0 +1,181 @@
import logging
from django.conf import settings
# Python 2.7 has an importlib with import_module.
# For older Pythons, Django's bundled copy provides it.
# For older Django's dajaxice reduced_import_module.
try:
from importlib import import_module
except:
try:
from django.utils.importlib import import_module
except:
from dajaxice.utils import simple_import_module as import_module
log = logging.getLogger('dajaxice.DajaxiceRequest')
class DajaxiceFunction(object):
def __init__(self, name, path, doc=None):
self.name = name
self.path = path
self.doc = doc
def get_callable_path(self):
return '%s.%s' % (self.path.replace('.ajax', ''), self.name)
def __cmp__(self, other):
return (self.name == other.name and self.path == other.path)
class DajaxiceModule(object):
def __init__(self, module):
self.functions = []
self.sub_modules = []
self.name = module[0]
sub_module = module[1:]
if len(sub_module) != 0:
self.add_submodule(sub_module)
def get_module(self, module):
"""
Recursively get_module util we found it.
"""
if len(module) == 0:
return self
for dajaxice_module in self.sub_modules:
if dajaxice_module.name == module[0]:
return dajaxice_module.get_module(module[1:])
return None
def add_function(self, function):
self.functions.append(function)
def has_sub_modules(self):
return len(self.sub_modules) > 0
def add_submodule(self, module):
"""
Recursively add_submodule, if it's not registered, create it.
"""
if len(module) == 0:
return
else:
sub_module = self.exist_submodule(module[0])
if type(sub_module) == int:
self.sub_modules[sub_module].add_submodule(module[1:])
else:
self.sub_modules.append(DajaxiceModule(module))
def exist_submodule(self, name):
"""
Check if submodule name was already registered.
"""
for module in self.sub_modules:
if module.name == name:
return self.sub_modules.index(module)
return False
class Dajaxice(object):
def __init__(self):
self._registry = []
self._callable = []
for function in getattr(settings, 'DAJAXICE_FUNCTIONS', ()):
function = function.rsplit('.', 1)
self.register_function(function[0], function[1])
def register(self, function):
self.register_function(function.__module__, function.__name__, function.__doc__)
def register_function(self, module, name, doc=None):
"""
Register function at 'module' depth
"""
#Create the dajaxice function.
function = DajaxiceFunction(name=name, path=module, doc=doc)
#Check for already registered functions.
full_path = '%s.%s' % (module, name)
if full_path in self._callable:
log.warning('%s already registered as dajaxice function.' % full_path)
return
self._callable.append(full_path)
#Dajaxice path without ajax.
module_without_ajax = module.replace('.ajax', '').split('.')
#Register module if necessary.
exist_module = self._exist_module(module_without_ajax[0])
if type(exist_module) == int:
self._registry[exist_module].add_submodule(module_without_ajax[1:])
else:
self._registry.append(DajaxiceModule(module_without_ajax))
#Register Function
module = self.get_module(module_without_ajax)
if module:
module.add_function(function)
def get_module(self, module):
"""
Recursively get module from registry
"""
for dajaxice_module in self._registry:
if dajaxice_module.name == module[0]:
return dajaxice_module.get_module(module[1:])
return None
def is_callable(self, name):
return name in self._callable
def _exist_module(self, module_name):
for module in self._registry:
if module.name == module_name:
return self._registry.index(module)
return False
def get_functions(self):
return self._registry
LOADING_DAJAXICE = False
def dajaxice_autodiscover():
"""
Auto-discover INSTALLED_APPS ajax.py modules and fail silently when
not present.
NOTE: dajaxice_autodiscover was inspired/copied from django.contrib.admin autodiscover
"""
global LOADING_DAJAXICE
if LOADING_DAJAXICE:
return
LOADING_DAJAXICE = True
import imp
from django.conf import settings
for app in settings.INSTALLED_APPS:
try:
app_path = import_module(app).__path__
except AttributeError:
continue
try:
imp.find_module('ajax', app_path)
except ImportError:
continue
import_module("%s.ajax" % app)
LOADING_DAJAXICE = False

View file

@ -0,0 +1,214 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
import os
import sys
import logging
import traceback
from django.conf import settings
from django.utils import simplejson
from django.http import HttpResponse
from dajaxice.core import dajaxice_functions
from dajaxice.exceptions import FunctionNotCallableError, DajaxiceImportError
log = logging.getLogger('dajaxice.DajaxiceRequest')
# Python 2.7 has an importlib with import_module.
# For older Pythons, Django's bundled copy provides it.
# For older Django's dajaxice reduced_import_module.
try:
from importlib import import_module
except:
try:
from django.utils.importlib import import_module
except:
from dajaxice.utils import simple_import_module as import_module
def safe_dict(d):
"""
Recursively clone json structure with UTF-8 dictionary keys
http://www.gossamer-threads.com/lists/python/bugs/684379
"""
if isinstance(d, dict):
return dict([(k.encode('utf-8'), safe_dict(v)) for k, v in d.iteritems()])
elif isinstance(d, list):
return [safe_dict(x) for x in d]
else:
return d
class DajaxiceRequest(object):
def __init__(self, request, call):
call = call.rsplit('.', 1)
self.app_name = call[0]
self.method = call[1]
self.request = request
self.project_name = os.environ['DJANGO_SETTINGS_MODULE'].split('.')[0]
self.module = "%s.ajax" % self.app_name
self.full_name = "%s.%s" % (self.module, self.method)
@staticmethod
def get_js_functions():
return dajaxice_functions.get_functions()
@staticmethod
def get_media_prefix():
return getattr(settings, 'DAJAXICE_MEDIA_PREFIX', "dajaxice")
@staticmethod
def get_functions():
return getattr(settings, 'DAJAXICE_FUNCTIONS', ())
@staticmethod
def get_debug():
return getattr(settings, 'DAJAXICE_DEBUG', True)
@staticmethod
def get_notify_exceptions():
return getattr(settings, 'DAJAXICE_NOTIFY_EXCEPTIONS', False)
@staticmethod
def get_cache_control():
if settings.DEBUG:
return 0
return getattr(settings, 'DAJAXICE_CACHE_CONTROL', 5 * 24 * 60 * 60)
@staticmethod
def get_xmlhttprequest_js_import():
return getattr(settings, 'DAJAXICE_XMLHTTPREQUEST_JS_IMPORT', True)
@staticmethod
def get_json2_js_import():
return getattr(settings, 'DAJAXICE_JSON2_JS_IMPORT', True)
@staticmethod
def get_exception_message():
return getattr(settings, 'DAJAXICE_EXCEPTION', u'DAJAXICE_EXCEPTION')
@staticmethod
def get_js_docstrings():
return getattr(settings, 'DAJAXICE_JS_DOCSTRINGS', False)
def _is_callable(self):
"""
Return if the request function was registered.
"""
return dajaxice_functions.is_callable(self.full_name)
def _get_ajax_function(self):
"""
Return a callable ajax function.
This function should be imported according the Django version.
"""
return self._modern_get_ajax_function()
def _modern_get_ajax_function(self):
"""
Return a callable ajax function.
This function uses django.utils.importlib
"""
self.module_import_name = "%s.%s" % (self.project_name, self.module)
try:
return self._modern_import()
except:
self.module_import_name = self.module
return self._modern_import()
def _modern_import(self):
try:
mod = import_module(self.module_import_name)
return mod.__getattribute__(self.method)
except:
raise DajaxiceImportError()
def process(self):
"""
Process the dajax request calling the apropiate method.
"""
if self._is_callable():
log.debug('Function %s is callable' % self.full_name)
argv = self.request.POST.get('argv')
if argv != 'undefined':
try:
argv = simplejson.loads(self.request.POST.get('argv'))
argv = safe_dict(argv)
except Exception, e:
log.error('argv exception %s' % e)
argv = {}
else:
argv = {}
log.debug('argv %s' % argv)
try:
thefunction = self._get_ajax_function()
response = '%s' % thefunction(self.request, **argv)
except Exception, e:
trace = '\n'.join(traceback.format_exception(*sys.exc_info()))
log.error(trace)
response = '%s' % DajaxiceRequest.get_exception_message()
if DajaxiceRequest.get_notify_exceptions():
self.notify_exception(self.request, sys.exc_info())
log.info('response: %s' % response)
return HttpResponse(response, mimetype="application/x-json")
else:
log.debug('Function %s is not callable' % self.full_name)
raise FunctionNotCallableError(name=self.full_name)
def notify_exception(self, request, exc_info):
"""
Send Exception traceback to ADMINS
Similar to BaseHandler.handle_uncaught_exception
"""
from django.conf import settings
from django.core.mail import mail_admins
subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
try:
request_repr = repr(request)
except:
request_repr = "Request repr() unavailable"
trace = '\n'.join(traceback.format_exception(*(exc_info or sys.exc_info())))
message = "%s\n\n%s" % (trace, request_repr)
mail_admins(subject, message, fail_silently=True)

View file

@ -0,0 +1,5 @@
from Dajaxice import Dajaxice
dajaxice_functions = Dajaxice()
from DajaxiceRequest import DajaxiceRequest
from Dajaxice import dajaxice_autodiscover

10
dajaxice/decorators.py Normal file
View file

@ -0,0 +1,10 @@
from dajaxice.core import dajaxice_functions
def dajaxice_register(original_function):
"""
Register the original funcion and returns it
"""
dajaxice_functions.register(original_function)
return original_function

41
dajaxice/exceptions.py Normal file
View file

@ -0,0 +1,41 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
class FunctionNotCallableError(Exception):
def __init__(self, name):
self.name = name
class DajaxiceImportError(Exception):
pass

75
dajaxice/finders.py Normal file
View file

@ -0,0 +1,75 @@
import os
import tempfile
from django.contrib.staticfiles import finders
from django.template import Context
from django.template.loader import get_template
from django.core.exceptions import SuspiciousOperation
class VirtualStorage(finders.FileSystemStorage):
"""" Mock a FileSystemStorage to build tmp files on demand."""
def __init__(self, *args, **kwargs):
self._files_cache = {}
super(VirtualStorage, self).__init__(*args, **kwargs)
def get_or_create_file(self, path):
if path not in self.files:
return ''
data = getattr(self, self.files[path])()
try:
current_file = open(self._files_cache[path])
current_data = current_file.read()
current_file.close()
if current_data != data:
os.remove(path)
raise Exception("Invalid data")
except Exception:
handle, tmp_path = tempfile.mkstemp()
tmp_file = open(tmp_path, 'w')
tmp_file.write(data)
tmp_file.close()
self._files_cache[path] = tmp_path
return self._files_cache[path]
def exists(self, name):
return name in self.files
def listdir(self, path):
folders, files = [], []
for f in self.files:
if f.startswith(path):
f = f.replace(path, '', 1)
if os.sep in f:
folders.append(f.split(os.sep, 1)[0])
else:
files.append(f)
return folders, files
def path(self, name):
try:
path = self.get_or_create_file(name)
except ValueError:
raise SuspiciousOperation("Attempted access to '%s' denied." % name)
return os.path.normpath(path)
class DajaxiceStorage(VirtualStorage):
files = {'dajaxice/dajaxice.core.js': 'dajaxice_core_js'}
def dajaxice_core_js(self):
from dajaxice.core import dajaxice_autodiscover, dajaxice_config
dajaxice_autodiscover()
c = Context({'dajaxice_config': dajaxice_config})
return get_template('dajaxice/dajaxice.core.js').render(c)
class DajaxiceFinder(finders.BaseStorageFinder):
storage = DajaxiceStorage()

View file

View file

View file

@ -0,0 +1,83 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
import httplib
import urllib
from django.core.management.base import BaseCommand
from django.template.loader import render_to_string
from optparse import make_option
from dajaxice.core import DajaxiceRequest
from dajaxice.core import dajaxice_autodiscover
dajaxice_autodiscover()
class Command(BaseCommand):
help = "Generate dajaxice.core.js file to import it as static file"
args = "[--compile]"
option_list = BaseCommand.option_list + (
make_option('--compile', default='no', dest='compile', help='Compile output using Google closure-compiler'),
)
requires_model_validation = False
def handle(self, *app_labels, **options):
compile_output = options.get('compile', 'yes')
data = {'dajaxice_js_functions': DajaxiceRequest.get_js_functions(),
'DAJAXICE_URL_PREFIX': DajaxiceRequest.get_media_prefix(),
'DAJAXICE_XMLHTTPREQUEST_JS_IMPORT': DajaxiceRequest.get_xmlhttprequest_js_import(),
'DAJAXICE_JSON2_JS_IMPORT': DajaxiceRequest.get_json2_js_import(),
'DAJAXICE_EXCEPTION': DajaxiceRequest.get_exception_message()}
js = render_to_string('dajaxice/dajaxice.core.js', data)
if compile_output.lower() == "closure":
print self.complie_js_with_closure(js)
else:
print js
def complie_js_with_closure(self, js):
params = urllib.urlencode([
('js_code', js),
('compilation_level', 'ADVANCED_OPTIMIZATIONS'),
('output_format', 'text'),
('output_info', 'compiled_code'),
])
# Always use the following value for the Content-type header.
headers = {"Content-type": "application/x-www-form-urlencoded"}
conn = httplib.HTTPConnection('closure-compiler.appspot.com')
conn.request('POST', '/compile', params, headers)
response = conn.getresponse()
data = response.read()
conn.close()
return data

0
dajaxice/models.py Normal file
View file

View file

@ -0,0 +1,128 @@
var Dajaxice = {
{% for module in dajaxice_js_functions %}
{% include "dajaxice/dajaxice_core_loop.js" %}
{% endfor %}{% ifnotequal dajaxice_js_functions|length 0 %},{% endifnotequal %}
get_cookie: function(name)
{
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].toString().replace(/^\s+/, "").replace(/\s+$/, "");
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
},
call: function(dajaxice_function, dajaxice_callback, argv, exception_callback)
{
var send_data = [];
var is_callback_a_function = (typeof(dajaxice_callback) == 'function');
if(!is_callback_a_function){
alert("dajaxice_callback should be a function since dajaxice 0.2")
}
if(exception_callback==undefined || typeof(dajaxice_callback) != 'function'){
exception_callback = this.get_setting('default_exception_callback');
}
send_data.push('argv='+encodeURIComponent(JSON.stringify(argv)));
send_data = send_data.join('&');
var oXMLHttpRequest = new XMLHttpRequest;
oXMLHttpRequest.open('POST', '/{{DAJAXICE_URL_PREFIX}}/'+dajaxice_function+'/');
oXMLHttpRequest.setRequestHeader("X-Requested-With", "XMLHttpRequest");
oXMLHttpRequest.setRequestHeader("X-CSRFToken",Dajaxice.get_cookie('csrftoken'));
oXMLHttpRequest.onreadystatechange = function() {
if (this.readyState == XMLHttpRequest.DONE) {
if(this.responseText == Dajaxice.EXCEPTION){
exception_callback();
}
else{
try{
dajaxice_callback(JSON.parse(this.responseText));
}
catch(exception){
dajaxice_callback(this.responseText);
}
}
}
}
oXMLHttpRequest.send(send_data);
},
setup: function(settings)
{
this.settings = settings;
},
get_setting: function(key){
if(this.settings == undefined || this.settings[key] == undefined){
return this.default_settings[key];
}
return this.settings[key];
},
default_exception_callback: function(data){
alert('Something goes wrong');
}
};
Dajaxice.EXCEPTION = '{{ DAJAXICE_EXCEPTION }}';
Dajaxice.default_settings = {'default_exception_callback': Dajaxice.default_exception_callback}
window['Dajaxice'] = Dajaxice;
{% comment %}
/*
XMLHttpRequest.js Compiled with Google Closure
XMLHttpRequest.js Copyright (C) 2008 Sergey Ilinsky (http://www.ilinsky.com)
This work is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This work is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
{% endcomment %}
{% if DAJAXICE_XMLHTTPREQUEST_JS_IMPORT %}
(function(){function b(){this._object=i?new i:new window.ActiveXObject("Microsoft.XMLHTTP");this._listeners=[]}function k(a){b.onreadystatechange&&b.onreadystatechange.apply(a);a.dispatchEvent({type:"readystatechange",bubbles:false,cancelable:false,timeStamp:new Date+0})}function p(a){var c=a.responseXML,d=a.responseText;if(h&&d&&c&&!c.documentElement&&a.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)){c=new window.ActiveXObject("Microsoft.XMLDOM");c.async=false;c.validateOnParse=false;
c.loadXML(d)}if(c)if(h&&c.parseError!=0||!c.documentElement||c.documentElement&&c.documentElement.tagName=="parsererror")return null;return c}function o(a){try{a.responseText=a._object.responseText}catch(c){}try{a.responseXML=p(a._object)}catch(d){}try{a.status=a._object.status}catch(g){}try{a.statusText=a._object.statusText}catch(e){}}function l(a){a._object.onreadystatechange=new window.Function}var i=window.XMLHttpRequest,j=!!window.controllers,h=window.document.all&&!window.opera;if(j&&i.wrapped)b.wrapped=
i.wrapped;b.UNSENT=0;b.OPENED=1;b.HEADERS_RECEIVED=2;b.LOADING=3;b.DONE=4;b.prototype.readyState=b.UNSENT;b.prototype.responseText="";b.prototype.responseXML=null;b.prototype.status=0;b.prototype.statusText="";b.prototype.onreadystatechange=null;b.onreadystatechange=null;b.onopen=null;b.onsend=null;b.onabort=null;b.prototype.open=function(a,c,d,g,e){delete this._headers;if(arguments.length<3)d=true;this._async=d;var f=this,m=this.readyState,n;if(h&&d){n=function(){if(m!=b.DONE){l(f);f.abort()}};window.attachEvent("onunload",
n)}b.onopen&&b.onopen.apply(this,arguments);if(arguments.length>4)this._object.open(a,c,d,g,e);else arguments.length>3?this._object.open(a,c,d,g):this._object.open(a,c,d);if(!j&&!h){this.readyState=b.OPENED;k(this)}this._object.onreadystatechange=function(){if(!(j&&!d)){f.readyState=f._object.readyState;o(f);if(f._aborted)f.readyState=b.UNSENT;else{if(f.readyState==b.DONE){l(f);h&&d&&window.detachEvent("onunload",n)}m!=f.readyState&&k(f);m=f.readyState}}}};b.prototype.send=function(a){b.onsend&&b.onsend.apply(this,
arguments);if(a&&a.nodeType){a=window.XMLSerializer?(new window.XMLSerializer).serializeToString(a):a.xml;this._headers["Content-Type"]||this._object.setRequestHeader("Content-Type","application/xml")}this._object.send(a);if(j&&!this._async){this.readyState=b.OPENED;for(o(this);this.readyState<b.DONE;){this.readyState++;k(this);if(this._aborted)return}}};b.prototype.abort=function(){b.onabort&&b.onabort.apply(this,arguments);if(this.readyState>b.UNSENT)this._aborted=true;this._object.abort();l(this)};
b.prototype.getAllResponseHeaders=function(){return this._object.getAllResponseHeaders()};b.prototype.getResponseHeader=function(a){return this._object.getResponseHeader(a)};b.prototype.setRequestHeader=function(a,c){if(!this._headers)this._headers={};this._headers[a]=c;return this._object.setRequestHeader(a,c)};b.prototype.addEventListener=function(a,c,d){for(var g=0,e;e=this._listeners[g];g++)if(e[0]==a&&e[1]==c&&e[2]==d)return;this._listeners.push([a,c,d])};b.prototype.removeEventListener=function(a,
c,d){for(var g=0,e;e=this._listeners[g];g++)if(e[0]==a&&e[1]==c&&e[2]==d)break;e&&this._listeners.splice(g,1)};b.prototype.dispatchEvent=function(a){a={type:a.type,target:this,currentTarget:this,eventPhase:2,bubbles:a.bubbles,cancelable:a.cancelable,timeStamp:a.timeStamp,stopPropagation:function(){},preventDefault:function(){},initEvent:function(){}};if(a.type=="readystatechange"&&this.onreadystatechange)(this.onreadystatechange.handleEvent||this.onreadystatechange).apply(this,[a]);for(var c=0,d;d=
this._listeners[c];c++)if(d[0]==a.type&&!d[2])(d[1].handleEvent||d[1]).apply(this,[a])};b.prototype.toString=function(){return"[object XMLHttpRequest]"};b.toString=function(){return"[XMLHttpRequest]"};if(!window.Function.prototype.apply)window.Function.prototype.apply=function(a,c){c||(c=[]);a.__func=this;a.__func(c[0],c[1],c[2],c[3],c[4]);delete a.__func};window.XMLHttpRequest=b})();
{% endif %}
{% comment %}
/*
http://www.json.org/json2.js Compiled with Google Closure
This code was released under Public Domain by json.org , Thanks!
I hope that in the future this code won't be neccessary, but today all browsers doesn't supports JSON.stringify().
*/
{% endcomment %}
{% if DAJAXICE_JSON2_JS_IMPORT %}
if(!this.JSON)this.JSON={};
(function(){function k(a){return a<10?"0"+a:a}function n(a){o.lastIndex=0;return o.test(a)?'"'+a.replace(o,function(c){var d=q[c];return typeof d==="string"?d:"\\u"+("0000"+c.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function l(a,c){var d,f,i=g,e,b=c[a];if(b&&typeof b==="object"&&typeof b.toJSON==="function")b=b.toJSON(a);if(typeof j==="function")b=j.call(c,a,b);switch(typeof b){case "string":return n(b);case "number":return isFinite(b)?String(b):"null";case "boolean":case "null":return String(b);case "object":if(!b)return"null";
g+=m;e=[];if(Object.prototype.toString.apply(b)==="[object Array]"){f=b.length;for(a=0;a<f;a+=1)e[a]=l(a,b)||"null";c=e.length===0?"[]":g?"[\n"+g+e.join(",\n"+g)+"\n"+i+"]":"["+e.join(",")+"]";g=i;return c}if(j&&typeof j==="object"){f=j.length;for(a=0;a<f;a+=1){d=j[a];if(typeof d==="string")if(c=l(d,b))e.push(n(d)+(g?": ":":")+c)}}else for(d in b)if(Object.hasOwnProperty.call(b,d))if(c=l(d,b))e.push(n(d)+(g?": ":":")+c);c=e.length===0?"{}":g?"{\n"+g+e.join(",\n"+g)+"\n"+i+"}":"{"+e.join(",")+"}";
g=i;return c}}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+k(this.getUTCMonth()+1)+"-"+k(this.getUTCDate())+"T"+k(this.getUTCHours())+":"+k(this.getUTCMinutes())+":"+k(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var p=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
o=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,g,m,q={"\u0008":"\\b","\t":"\\t","\n":"\\n","\u000c":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},j;if(typeof JSON.stringify!=="function")JSON.stringify=function(a,c,d){var f;m=g="";if(typeof d==="number")for(f=0;f<d;f+=1)m+=" ";else if(typeof d==="string")m=d;if((j=c)&&typeof c!=="function"&&(typeof c!=="object"||typeof c.length!=="number"))throw new Error("JSON.stringify");return l("",
{"":a})};if(typeof JSON.parse!=="function")JSON.parse=function(a,c){function d(f,i){var e,b,h=f[i];if(h&&typeof h==="object")for(e in h)if(Object.hasOwnProperty.call(h,e)){b=d(h,e);if(b!==undefined)h[e]=b;else delete h[e]}return c.call(f,i,h)}p.lastIndex=0;if(p.test(a))a=a.replace(p,function(f){return"\\u"+("0000"+f.charCodeAt(0).toString(16)).slice(-4)});if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){a=eval("("+a+")");return typeof c==="function"?d({"":a},""):a}throw new SyntaxError("JSON.parse");}})();
{% endif %}

View file

@ -0,0 +1,16 @@
{{ module.name }}: {
{% for function in module.functions %}
{% if function.doc and DAJAXICE_JS_DOCSTRINGS %}/* {{ function.doc|default:'' }}*/ {% endif %}
{{ function.name }}: function(callback_function, argv, exception_callback){
Dajaxice.call('{{function.get_callable_path}}', callback_function, argv, exception_callback);
}{% if not forloop.last %},{% endif %}
{% endfor %}
{% for sub_module in module.sub_modules %}
{% with "dajaxice/dajaxice_core_loop.js" as filename %}
{% with sub_module as module %}
{% include filename %}
{% endwith %}
{% endwith %}
{% endfor %}
}{% if not forloop.last %},{% endif %}

View file

@ -0,0 +1,5 @@
{% for function_name, function in module.functions.items %}
{{ function_name }}: function(callback_function, argv, custom_settings){
Dajaxice.call('{{ function.name }}', '{{ function.method }}', callback_function, argv, custom_settings);
}{% if not forloop.last or top %},{% endif %}
{% endfor %}

View file

@ -0,0 +1 @@
<script src="/{{ DAJAXICE_MEDIA_PREFIX }}/dajaxice.core.js" type="text/javascript" charset="utf-8"></script>

View file

@ -0,0 +1,8 @@
{{ name }}: {
{% include "dajaxice/dajaxice_function_loop.js" %}
{% for name, sub_module in module.submodules.items %}
{% with filename="dajaxice/dajaxice_module_loop.js" module=sub_module %}
{% include filename %}
{% endwith %}
{% endfor %}
}{% if not forloop.last %},{% endif %}

View file

View file

@ -0,0 +1,42 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
from django import template
from dajaxice.core import DajaxiceRequest
register = template.Library()
@register.inclusion_tag('dajaxice/dajaxice_js_import.html', takes_context=True)
def dajaxice_js_import(context):
return {'DAJAXICE_MEDIA_PREFIX': DajaxiceRequest.get_media_prefix()}

174
dajaxice/tests/__init__.py Normal file
View file

@ -0,0 +1,174 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
import os
import unittest
from django.test import TestCase
from django.conf import settings
from dajaxice.exceptions import FunctionNotCallableError, DajaxiceImportError
from dajaxice.core import DajaxiceRequest
from dajaxice.core.Dajaxice import Dajaxice, DajaxiceModule, DajaxiceFunction
from dajaxice.core import dajaxice_functions
class DjangoIntegrationTest(TestCase):
urls = 'dajaxice.tests.urls'
def setUp(self):
settings.DAJAXICE_MEDIA_PREFIX = "dajaxice"
settings.DAJAXICE_DEBUG = False
settings.INSTALLED_APPS += ('dajaxice.tests', 'dajaxice.tests.submodules',)
os.environ['DJANGO_SETTINGS_MODULE'] = 'dajaxice'
def test_calling_not_registered_function(self):
self.failUnlessRaises(FunctionNotCallableError, self.client.post, '/dajaxice/dajaxice.tests.this_function_not_exist/', {'callback': 'my_callback'})
def test_calling_registered_function(self):
response = self.client.post('/dajaxice/dajaxice.tests.test_foo/', {'callback': 'my_callback'})
self.failUnlessEqual(response.status_code, 200)
self.failUnlessEqual(response.content, 'my_callback()')
def test_calling_registered_function_with_params(self):
response = self.client.post('/dajaxice/dajaxice.tests.test_foo_with_params/', {'callback': 'my_callback', 'argv': '{"param1":"value1"}'})
self.failUnlessEqual(response.status_code, 200)
self.failUnlessEqual(response.content, 'my_callback("value1")')
def test_bad_function(self):
response = self.client.post('/dajaxice/dajaxice.tests.test_ajax_exception/', {'callback': 'my_callback'})
self.failUnlessEqual(response.status_code, 200)
self.failUnlessEqual(response.content, "my_callback('DAJAXICE_EXCEPTION')")
def test_is_callable(self):
dr = DajaxiceRequest(None, 'dajaxice.tests.test_registered_function')
self.failUnless(dr._is_callable())
dr = DajaxiceRequest(None, 'dajaxice.tests.test_ajax_not_registered')
self.failIf(dr._is_callable())
def test_get_js_functions(self):
js_functions = DajaxiceRequest.get_js_functions()
functions = [DajaxiceFunction('test_registered_function', 'dajaxice.tests.ajax.test_registered_function'),
DajaxiceFunction('test_string', 'dajaxice.tests.ajax.test_string'),
DajaxiceFunction('test_ajax_exception', 'dajaxice.tests.ajax.test_ajax_exception'),
DajaxiceFunction('test_foo', 'dajaxice.tests.ajax.test_foo'),
DajaxiceFunction('test_foo_with_params', 'dajaxice.tests.ajax.test_foo_with_params'),
DajaxiceFunction('test_submodule_registered_function', 'dajaxice.tests.submodules.ajax.test_submodule_registered_function')]
callables = [f.path for f in functions]
self.failUnlessEqual(len(js_functions), 1)
self.failUnlessEqual(dajaxice_functions._callable, callables)
sub = js_functions[0]
self.failUnlessEqual(len(sub.sub_modules), 1)
self.failUnlessEqual(len(sub.functions), 0)
self.failUnlessEqual(sub.name, 'dajaxice')
sub = js_functions[0].sub_modules[0]
self.failUnlessEqual(len(sub.sub_modules), 1)
self.failUnlessEqual(len(sub.functions), 5)
self.failUnlessEqual(sub.functions, functions[:-1])
self.failUnlessEqual(sub.name, 'tests')
sub = js_functions[0].sub_modules[0].sub_modules[0]
self.failUnlessEqual(len(sub.sub_modules), 0)
self.failUnlessEqual(len(sub.functions), 1)
self.failUnlessEqual(sub.functions, functions[-1:])
self.failUnlessEqual(sub.name, 'submodules')
def test_get_ajax_function(self):
# Test modern Import with a real ajax function
dr = DajaxiceRequest(None, 'dajaxice.tests.test_foo')
function = dr._modern_get_ajax_function()
self.failUnless(hasattr(function, '__call__'))
# Test modern Import without a real ajax function
dr = DajaxiceRequest(None, 'dajaxice.tests.test_foo2')
self.failUnlessRaises(DajaxiceImportError, dr._modern_get_ajax_function)
class DajaxiceFunctionTest(unittest.TestCase):
def setUp(self):
self.function = DajaxiceFunction('my_function', 'module.submodule.foo.ajax')
def test_constructor(self):
self.failUnlessEqual(self.function.name, 'my_function')
self.failUnlessEqual(self.function.path, 'module.submodule.foo.ajax')
def test_get_callable_path(self):
self.failUnlessEqual(self.function.get_callable_path(), 'module.submodule.foo.my_function')
class DajaxiceModuleTest(unittest.TestCase):
def setUp(self):
self.module = DajaxiceModule('module.submodule.foo.ajax'.split('.'))
def test_constructor(self):
self.failUnlessEqual(self.module.functions, [])
self.failUnlessEqual(self.module.name, 'module')
self.failUnlessEqual(len(self.module.sub_modules), 1)
def test_add_function(self):
function = DajaxiceFunction('my_function', 'module.submodule.foo.ajax')
self.failUnlessEqual(len(self.module.functions), 0)
self.module.add_function(function)
self.failUnlessEqual(len(self.module.functions), 1)
def test_has_sub_modules(self):
self.failUnlessEqual(self.module.has_sub_modules(), True)
def test_exist_submodule(self):
self.failUnlessEqual(self.module.exist_submodule('submodule'), 0)
self.assertFalse(self.module.exist_submodule('other'))
self.module.add_submodule('other.foo'.split('.'))
self.failUnlessEqual(self.module.exist_submodule('other'), 1)
def test_add_submodule(self):
self.failUnlessEqual(len(self.module.sub_modules), 1)
self.module.add_submodule('other.foo'.split('.'))
self.failUnlessEqual(len(self.module.sub_modules), 2)
self.assertTrue(type(self.module.sub_modules[1]), DajaxiceModule)

61
dajaxice/tests/ajax.py Normal file
View file

@ -0,0 +1,61 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
from django.utils import simplejson
from dajaxice.core import dajaxice_functions
def test_registered_function(request):
return ""
dajaxice_functions.register(test_registered_function)
def test_string(request):
return simplejson.dumps({'string': 'hello world'})
dajaxice_functions.register(test_string)
def test_ajax_exception(request):
raise Exception()
return
dajaxice_functions.register(test_ajax_exception)
def test_foo(request):
return ""
dajaxice_functions.register(test_foo)
def test_foo_with_params(request, param1):
return simplejson.dumps(param1)
dajaxice_functions.register(test_foo_with_params)

View file

@ -0,0 +1 @@
Django

View file

View file

@ -0,0 +1,40 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
from dajaxice.core import dajaxice_functions
def test_submodule_registered_function(request):
return ""
dajaxice_functions.register(test_submodule_registered_function)

44
dajaxice/tests/urls.py Normal file
View file

@ -0,0 +1,44 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
from django.conf.urls.defaults import *
from django.conf import settings
from dajaxice.core import dajaxice_autodiscover
dajaxice_autodiscover()
urlpatterns = patterns('',
#Dajaxice URLS
(r'^%s/' % settings.DAJAXICE_MEDIA_PREFIX, include('dajaxice.urls')),
)

39
dajaxice/urls.py Normal file
View file

@ -0,0 +1,39 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
from django.conf.urls.defaults import *
urlpatterns = patterns('',
url(r'^dajaxice.core.js$', 'dajaxice.views.js_core'),
url(r'^(.*)/$', 'dajaxice.views.dajaxice_request'),)

50
dajaxice/utils.py Normal file
View file

@ -0,0 +1,50 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
def deserialize_form(data):
"""
Create a new QueryDict from a serialized form.
"""
from django.http import QueryDict
data = QueryDict(query_string=unicode(data).encode('utf-8'))
return data
def simple_import_module(name):
"""
Reduced version of import_module
"""
import sys
__import__(name)
return sys.modules[name]

62
dajaxice/views.py Normal file
View file

@ -0,0 +1,62 @@
#----------------------------------------------------------------------
# Copyright (c) 2009-2011 Benito Jorge Bastida
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# o Redistributions of source code must retain the above copyright
# notice, this list of conditions, and the disclaimer that follows.
#
# o Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# o Neither the name of Digital Creations nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#----------------------------------------------------------------------
from django.shortcuts import render_to_response
from django.views.decorators.cache import cache_control
from dajaxice.core import DajaxiceRequest
def dajaxice_request(request, call):
"""
dajaxice_request
Uses DajaxRequest to handle dajax request.
Return the apropiate json according app_name and method.
"""
return DajaxiceRequest(request, call).process()
@cache_control(max_age=DajaxiceRequest.get_cache_control())
def js_core(request):
"""
Return the dajax JS code according settings.DAJAXICE_FUNCTIONS
registered functions.
"""
data = {'dajaxice_js_functions': DajaxiceRequest.get_js_functions(),
'DAJAXICE_URL_PREFIX': DajaxiceRequest.get_media_prefix(),
'DAJAXICE_XMLHTTPREQUEST_JS_IMPORT': DajaxiceRequest.get_xmlhttprequest_js_import(),
'DAJAXICE_JSON2_JS_IMPORT': DajaxiceRequest.get_json2_js_import(),
'DAJAXICE_EXCEPTION': DajaxiceRequest.get_exception_message(),
'DAJAXICE_JS_DOCSTRINGS': DajaxiceRequest.get_js_docstrings()}
return render_to_response('dajaxice/dajaxice.core.js', data, mimetype="text/javascript")

View file

@ -87,6 +87,9 @@ MEDIA_URL = ''
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'
#DAJAXICE_MEDIA_PREFIX="dajaxice"
DAJAXICE_MEDIA_PREFIX=""
AUTH_PROFILE_MODULE = 'person.Person'
AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.RemoteUserBackend', )

View file

@ -21,6 +21,10 @@ from django.conf import settings
admin.autodiscover()
admin.site.disable_action('delete_selected')
from dajaxice.core import dajaxice_autodiscover
dajaxice_autodiscover()
feeds = {
'iesg-agenda': IESGAgenda,
'last-call': InLastCall,
@ -76,6 +80,7 @@ urlpatterns = patterns('',
# Google webmaster tools verification url
(r'^googlea30ad1dacffb5e5b.html', 'django.views.generic.simple.direct_to_template', { 'template': 'googlea30ad1dacffb5e5b.html' }),
(r'^%s/' % settings.DAJAXICE_MEDIA_PREFIX, include('dajaxice.urls')),
)
if settings.SERVER_MODE in ('development', 'test'):