Commit c0673ea2 authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Better tuning of Aptana to remove automatically trailing spaces.

parent 9d2a15ec
......@@ -7,8 +7,8 @@ import pprint
class BaseSvc:
"""Base class to build service.
"""
"""
def __init__(self):
self.debug = False
......
......@@ -9,16 +9,16 @@ from gluon import current
def INHIBIT_DELETE_UNDEF(set):
"""Delete the row containing undefined value is not allowed
:type set: gluon.dal.Set
:param set:
:returns: bool
"""
db, T = current.globalenv['db'], current.T
field = set.query.first
# protection
# the query of the set should be "table.id == 1"
if field._db._adapter.EQ != set.query.op:
......@@ -29,22 +29,22 @@ def INHIBIT_DELETE_UNDEF(set):
field._table[CALLBACK_ERRORS] = \
T("You can not delete the row containing the undefined value.")
return True
return False
def INHIBIT_UPDATE_UNDEF(set, values):
"""Update the row containing undefined value is not allowed
:type set: gluon.dal.Set
:param set:
:returns: bool
"""
db, T = current.globalenv['db'], current.T
field = set.query.first
# protection
# the query of the set should be "table.id == 1"
if set.query.op != field._db._adapter.EQ:
......@@ -55,5 +55,5 @@ def INHIBIT_UPDATE_UNDEF(set, values):
field._table[CALLBACK_ERRORS] = \
T("You can not update the row containing the undefined value.")
return True
return False
......@@ -5,4 +5,4 @@
INLINE_ALERT = "<script>Ext.Msg.alert('%s', '%s');</script>"
UNDEF = 'undefined'
UNDEF_ID = 1
UNKNOWN = '???'
\ No newline at end of file
UNKNOWN = '???'
This diff is collapsed.
This diff is collapsed.
......@@ -20,56 +20,56 @@ PROC_KEY = '%s.%s'
class MyJsonEncoder(json.JSONEncoder):
"""Add date, datetime and time to the standard JSON encoder.
"""
def default(self, obj):
if isinstance(obj, (datetime.date,
datetime.datetime,
datetime.time)):
return obj.isoformat().replace('T', ' ')
return json.JSONEncoder.default(self, obj)
class DirectSvc(BaseSvc):
"""Generic service to implement the
"""Generic service to implement the
`Ext.Direct <http://www.sencha.com/products/extjs/extdirect/>`_ protocol
on the server-side.
This implementation is based on the
This implementation is based on the
`web2py service <http://www.web2py.com/book/default/chapter/09>`_
using a simplified version of the class ``gluon.tools.Service``.
To register functions and make them available on the client-side
use decorator::
service = DirectSvc()
@service.register
def myfunction(a, b):
The same technique can be used with methods.
On the client-side:
* the API definition can be retrieved using the
URL: ``/myapplication/plugin_dbui/call/get_api``
* the URL to send requests is
* the URL to send requests is
``/myapplication/plugin_dbui/call``
* remote functions and methods can be call in the
* remote functions and methods can be call in the
following way ``Dbui.myfunction(a, b, callback)``
and ``MyClass.mymethod(c, d, callback)`` respectively.
In this implementation requests and response are JSON encoded.
"""
def __init__(self):
BaseSvc.__init__(self)
self.procedures = {}
......@@ -79,19 +79,19 @@ class DirectSvc(BaseSvc):
def __call__(self):
"""Check the client request and launch the execution
of the function / method on the server.
:rtype: str
:returns:
str
* the response of the function / method run
on the server side
* the response is encoded as a JSON string.
:raise gluon.http.HTTP:
:raise gluon.http.HTTP:
when the request has no arguments
or when the function / method crashed.
"""
self.dbg('Start directSvc.call')
myrequest = current.request
......@@ -99,48 +99,48 @@ class DirectSvc(BaseSvc):
# no arguments in a Json-encoded raw HTPP request
if len(myrequest.args) == 0:
return self.route()
self.error(404, 'Object does not exist.')
def echo(self, x):
"""Return the input arguments to run echo tests.
"""
return x
def error(self, code, message):
"""Build and raise the gluon.http.HTTP exception
:type code: int
:param code: code of the HTTP error
:type message: str
:param message: explanation for the HTTP error
:raise gluon.http.HTTP:
"""
raise HTTP(code, message)
def register(self, f):
""" Register a function/method.
Example::
service = DirectSvc()
@service.register
def myfunction(a, b):
:type f: function
:param f:
:returns:
function -- the input argument
"""
# a procedure is registered as 'action.method'
# The action is equal to Dbui for a function
......@@ -151,32 +151,32 @@ class DirectSvc(BaseSvc):
k = PROC_KEY % (action, f.__name__)
self.procedures[k] = f
self.dbg("Procedure %s registered" % k)
return f
def route(self):
"""Route the request to the appropriate function / method,
"""Route the request to the appropriate function / method,
pass the proper arguments and return the results.
:returns:
str -- the response of the function / method
:returns:
str -- the response of the function / method
encoded as a JSON string.
:raise gluon.http.HTTP:
with the code 500 when the execution of the
:raise gluon.http.HTTP:
with the code 500 when the execution of the
function / method crash. The python trace back is stored
in the web2py ticket system.
"""
self.dbg('Start directSvc.route')
# decode transactions, a list of Json-encoded raw HTPP requests:
# {action: "x", method: "y", data: [], type:"rpc", tid:z}
myrequest = current.request
myrequest = current.request
transactions = as_list(json.loads(myrequest.body.read()))
# process each transactions and encode each result as a dict
# {action: "x", method: "y", result: [], type:"rpc", tid:z}
li = []
......@@ -191,7 +191,7 @@ class DirectSvc(BaseSvc):
di['result'] = self.procedures[k]()
# catch exceptions and log them in the ticker system
# inform the user that something went wrong in the server
# inform the user that something went wrong in the server
except:
r = RestrictedError(layer='directsvc.py',
code='route',
......@@ -199,9 +199,9 @@ class DirectSvc(BaseSvc):
environment=current.globalenv)
r.log(myrequest)
self.error(500, 'Internal server error.')
del di['data']
li.append(di)
self.dbg('End directSvc.call', li)
return json.dumps(li, cls=MyJsonEncoder)
""" configurators for the Ext JS components.
""" configurators for the Ext JS components.
"""
......@@ -14,26 +14,26 @@ class ExtJSException(BaseException): pass
class Base(Storage):
"""Base class for Ext JS configurator.
The base class comes with two methods ``append_items``
The base class comes with two methods ``append_items``
and ``append_plugins``. They are required to append ``items``
and ``plugins``.
.. note::
.. note::
A protection is set to avoid changing the ``xtype`` of the element.
"""
xtype = None
def __init__(self, **kwargs):
"""
:type kwargs: dict
:keyword kwargs: any Ext JS configuration parameter of the target class
:raise ExtJSException:
:raise ExtJSException:
if the keyword ``xtype`` is in the keyword arguments.
"""
if 'xtype' in kwargs:
raise ExtJSException(MSG_XTYPE)
......@@ -43,11 +43,11 @@ class Base(Storage):
items = kwargs.pop('items', None)
if items:
self._append('items', items)
plugins = kwargs.pop('plugins', None)
if plugins:
self._append('plugins', plugins)
self.update(kwargs)
......@@ -62,14 +62,14 @@ class Base(Storage):
def append_items(self, *args):
self._append('items', args)
def append_plugins(self, *args):
self._append('plugins', args)
class ArrayStore(Base):
"""Configurator for the ``Ext.data.ArrayStore``."""
xtype='arraystore'
xtype = 'arraystore'
class CheckBox(Base):
......@@ -94,7 +94,7 @@ class Field(Base):
class FieldAceEditor(Base):
"""Configurator for the ``App.form.field.AceEditor``."""
xtype='xaceeditorfield'
xtype = 'xaceeditorfield'
class FieldContainer(Base):
......@@ -125,27 +125,27 @@ class FieldNumber(Base):
class FieldSet(Base):
"""Configurator for ``Ext.form.FieldSet``."""
xtype = 'fieldset'
class FieldText(Base):
"""Configurator for ``Ext.form.field.Text``.
:note: Regular expression for the validation can be written as a string.
"""
xtype = 'textfield'
def __init__(self, **kwargs):
self['plugins'] = ['pRegExp']
Base.__init__(self, **kwargs)
class FieldTextArea(Base):
"""Configurator for ``Ext.form.field.TextArea``.
.. note::
.. note::
Regular expression for the validation can be written as a string.
"""
xtype = 'textarea'
......@@ -153,7 +153,7 @@ class FieldTextArea(Base):
self['plugins'] = ['pRegExp']
Base.__init__(self, **kwargs)
class FieldTime(Base):
"""Configurator for ``Ext.form.field.Time``."""
xtype = 'timefield'
......@@ -170,10 +170,10 @@ class GridColumn(dict):
class GridColumnModel(list):
"""Configurator for ``Ext.grid.ColumnModel``.
.. note::
.. note::
It is implemented as a ``list`` of :class:`GridColumn`.
"""
......@@ -204,15 +204,15 @@ class GridWithFilter(Base):
class JsonStore(Base):
"""Configurator for the ``Ext.data.JsonStore``."""
xtype='jsonstore'
xtype = 'jsonstore'
class Model(dict):
"""Configurator for the ``Ext.data.Model``. """
def __init__(self, **kwargs):
dict.__init__(self, **kwargs)
self['extend'] = 'Ext.data.Model'
self['extend'] = 'Ext.data.Model'
class Panel(Base):
......@@ -227,7 +227,7 @@ class PanelWithUrlSelector(Base):
class Store(Base):
"""Configurator for the ``Ext.data.Store``."""
xtype='store'
xtype = 'store'
class TabPanel(Base):
......@@ -247,5 +247,4 @@ class Window(Base):
class XmlStore(Base):
"""Configurator for the ``Ext.data.XmlStore``."""
xtype='xmlstore'
\ No newline at end of file
xtype = 'xmlstore'
......@@ -11,44 +11,44 @@ MODIFIER_FIELDS = 'modifier_fields'
class FieldsModifier(Modifier):
"""Modifier to customise the field widgets associated to a database table.
"""
def __init__(self, tablename):
"""Initialize the fields modifier associated to the database
table ``tablename``.
The data structure of the fields modifier can be access
The data structure of the fields modifier can be access
outside the class::
p = PluginManager('dbui')
modifier = p.dbui['modifier_fields'][tablename]
or internally via the attribute ``data``.
The keys of the ``data`` structure are:
* ``extjs_fields`` (dict) Ext JS configuration options
* ``extjs_fields`` (dict) Ext JS configuration options
for individual ``field``.
* ``composite_fields.main`` (list) the first field
* ``composite_fields.main`` (list) the first field
of the ``FieldContainer``.
* ``composite_fields.others`` (list of list) the others field of
the ``FieldContainer``.
* There is one to one correspondence between the ``composite_fields.main``
and the ``composite_fields.others`` lists.
:type tablename: str
:param tablename: name of the database table
"""
Modifier.__init__(self, MODIFIER_FIELDS, tablename)
if 'extjs_fields' not in self.data:
self.data.extjs_fields = {}
self.data.composite_fields = Storage()
self.data.composite_fields.main = []
self.data.composite_fields.others = []
......@@ -57,68 +57,68 @@ class FieldsModifier(Modifier):
def append_plugins(self, *plugins):
"""Overwrite the method of the base class since it make
no sense for this modifier.
"""
def configure(self, **extjs):
"""Overwrite the method of the base class since it make
no sense for this modifier.
"""
def configure_field(self, field, **kwargs):
"""Update the configuration options of the Ext JS widget
associated to the ``field``.
Existing value of the configuration options are replace by those
"""Update the configuration options of the Ext JS widget
associated to the ``field``.
Existing value of the configuration options are replace by those
defined by the keyword arguments.
:type field: str
:param field:
name of the database field.
:param field:
name of the database field.
It should belong to the database table defined in the constructor.
"""
self.data.extjs_fields[field] = kwargs
def merge_fields(self, *fields, **kwargs):
"""Merge fields in a ``FieldContainer``.
The default configuration is with an horizontal layout with a unique
label defined by the keyword parameter ``fieldLabel``. More precisely,
the following Ext JS configuration parameters are set::
combineLabels = True,
defaults = {'flex': 1},
layout = 'hbox'
They can be super seed by the keyword arguments.
.. note::
* Each ``field`` is identified by its database field name.
* ``field`` should belong to the database table defined in the constructor.
* The first ``field`` is the main field of the ``FieldContainer``.
* The keyword arguments contains the configuration options of
the ``Ext.form.FieldContainer`` widget.
"""
# configuration of the FieldContainer
cfg = dict(combineLabels=True,
defaults={'flex': 1},
layout='hbox')
cfg.update(kwargs)
# define the main field as the first field in the list
main_field = fields[0]
other_fields = fields[1:]
# In order to simplify the processing keep a list of
# the main field and a list of the other fields.
self.data.composite_fields.main.append(main_field)
self.data.composite_fields.others.extend(other_fields)
di = Storage(fields=fields, extjs=cfg)
self.data.composite_fields[main_field] = di
......@@ -8,36 +8,36 @@ REG_COMMA = re.compile(r'( *, *)+$')
def CLEAN_COMMA(value):
"""Remove trailing comma(s).
Search patterns are: ',' or ', ' or ' ,, ' ...
:type value: str or unicode
:param value: