Package Products :: Package ZenUtils :: Module Ext
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenUtils.Ext

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  # Functions to simplify form submission return values. 
 15   
 16  import transaction 
 17   
 18  from Products.ZenUtils.json import json, unjson 
 19  from Products.ZenUI3.utils.javascript import JavaScriptSnippet 
 20  from Products.Five.browser import BrowserView 
 21   
 22   
23 -class FormResponse(object):
24 """ 25 Builds a response for an Ext form. 26 """ 27 _errors = None 28 _redirect = None 29
30 - def has_errors(self):
31 return bool(self._errors)
32
33 - def redirect(self, url):
34 self._redirect = url
35
36 - def error(self, field_name, error_text):
37 if self._errors is None: 38 self._errors = {} 39 self._errors[field_name] = error_text
40 41 @json
42 - def get_response(self):
43 return { 44 'success': not self.has_errors(), 45 'redirect': self._redirect, 46 'errors': self._errors or {} 47 }
48 49
50 -def form_action(f):
51 """ 52 Decorator for methods that are the targets of Ext form submission. 53 54 Provides transaction rollback, so methods can be used as their own 55 validation without harm. 56 """ 57 def inner(*args, **kwargs): 58 savepoint = transaction.savepoint() 59 result = f(*args, **kwargs) 60 if isinstance(result, FormResponse): 61 if result.has_errors(): 62 savepoint.rollback() 63 return result.get_response() 64 return result
65 return inner 66 67
68 -class DirectRouter(BrowserView):
69 """ 70 Base class for Ext.Direct routers. 71 72 Ext.Direct allows one to create an API that communicates with a single URL, 73 which then routes requests to the appropriate method. The client-side API 74 object matches the server-side API object. 75 76 This base class parses an Ext.Direct request, which contains the name of 77 the method and any data that should be passed, and routes the data to the 78 approriate method. It then receives the output of that call and puts it 79 into the data structure expected by Ext.Direct. 80 81 @rtype JSON 82 """ 83 _asof = None 84
85 - def _set_asof(self, asof):
86 self._asof = asof
87
88 - def __call__(self):
89 body = self.request.get('BODY') 90 self.data = unjson(body) 91 method = self.data['method'] 92 data = self.data['data'] 93 if 'asof' in self.data: 94 self._set_asof(self.data['asof']) 95 if not data: 96 data = {} 97 else: 98 data = data[0] 99 100 # Cast all keys as strings in case of unicode problems 101 data = dict((str(k), v) for k,v in data.items()) 102 103 # Call the specified method 104 result = getattr(self, method)(**data) 105 106 self.request.response.setHeader('Content-Type', 'application/json') 107 return json({ 108 'type':'rpc', 109 'tid': self.data['tid'], 110 'action':self.data['action'], 111 'method':self.data['method'], 112 'result': result, 113 'asof': self._asof 114 })
115 116
117 -class DirectProviderDefinition(JavaScriptSnippet):
118 """ 119 Turns a L{DirectRouter} subclass into JavaScript object representing the 120 config of the client-side API. 121 122 Inspects the given subclass and retrieves the names of all public methods, 123 then defines those as actions on the Ext.Direct provider, and creates the 124 JS that adds the provider. 125 126 As this is a JavaScriptSnippet, the resulting code will be included in the 127 rendered template if the snippet is registered as a viewlet in ZCML and the 128 appropriate provider is referenced in the template. 129 130 See http://extjs.com/products/extjs/direct.php for a full explanation of 131 protocols and features of Ext.Direct. 132 """ 133 _router = None 134 _url = None
135 - def snippet(self):
136 attrs = [a for a in self._router.__dict__.keys() if not a.startswith('_')] 137 methodtpl = '{name:"%s", len:1}' 138 methods = ",".join([methodtpl % a for a in attrs]) 139 return """ 140 Ext.onReady(function(){ 141 Ext.Direct.addProvider( 142 { 143 type: 'remoting', 144 url: '%(url)s', 145 actions: { 146 "%(clsname)s":[ 147 %(methods)s 148 ] 149 }, 150 namespace: 'Zenoss.remote' 151 } 152 ); 153 }); 154 """ % dict(url=self._url, clsname=self._router.__name__, methods=methods)
155