class ScaffoldinglEntryPoint(ext.MultiAdapter): """ generate a index html. This html site will than load extjs framework with css and run the application. """ ext.name('scaffolding') ext.adapts(IApplicationContext, IRequest) def __init__(self, context, request): self.context = context self.request = request def __call__(self): match = REGEX_URL.match(self.request.path_info) if match is None: raise HTTPNotFound() recipename, descname = match.groups() recipename, descname = recipename.lower(), descname.lower() descriptive = queryUtility(IRecipeDescriptive, descname) if descriptive is None: raise HTTPNotFound('No scaffolding for %s' % descname) recipe = queryMultiAdapter((self.context, descriptive, self.request,), IScaffoldingRecipe, recipename) if recipe is None: raise Exception('Missing Recipe to generate Exjs %s' % recipename) self.request.response.content_type = 'application/javascript' self.request.response.write(recipe())
class ChoiceField(BuilderBaseForm): ext.adapts(IScaffoldingRecipeForm, schema.interfaces.IChoice) def __call__(self): # Get the corresponding vocabulary vr = getVocabularyRegistry() vocabular = vr.get(None, self.field.vocabularyName) # Get the data to construct the store fields = ['value', 'title'] data = list() for term in vocabular: entry = dict() entry['value'] = term.token entry['title'] = term.title data.append(entry) # Attributes for the combobox self.name = self.field.getName() self.fieldLabel = translate(self.field.title, context=self.recipe.request) self.emptyText = self.field.default self.allowBlank = not self.field.required self.valueField = 'value' self.displayField = 'title' self.queryMode = 'local' self.store = "Ext.create('Ext.data.Store', {fields: %s, data: %s})" % (json.dumps(fields, indent=' ' * 4), json.dumps(data, indent=' ' * 4)) # Render the template tmpl = loader.load('combobox.json.tpl', cls=NewTextTemplate) stream = tmpl.generate(view=self) return stream.render()
class FloatField(DefaultField): ext.adapts(IScaffoldingRecipeGrid, schema.interfaces.IFloat) def __call__(self): di = json.loads(super(FloatField, self).__call__()) di.update(dict(xtype='numbercolumn')) return json.dumps(di, indent=' ' * 4)
class BaseForm(BaseRecipe): ext.baseclass() ext.adapts(IApplicationContext, interfaces.IRecipeDescriptive, IRequest) aliasprefix = 'Form' def __call__(self): return self.render_template('form.json.tpl') @property def title(self): return self.descriptive.title @property def items(self): items = list() for name, zfield in getFieldsInOrder(self.descriptive.interface): items.append( getMultiAdapter(( self, zfield, ), interfaces.IFieldBuilder)()) return items @property def name(self): return self.classname(CLASS_NAMESPACE, self.aliasprefix.lower(), self.descriptive.classname)
class IntField(BuilderBaseForm): ext.adapts(IScaffoldingRecipeForm, schema.interfaces.IInt) def __call__(self): di = self.default() di.update(dict(xtype='numberfield')) return json.dumps(di, indent=' ' * 4)
class PasswordField(DefaultField): ext.adapts(IScaffoldingRecipeEditGrid, schema.interfaces.IPassword) def __call__(self): di = json.loads(super(PasswordField, self).__call__()) di.update(dict(inputType='password')) return json.dumps(di, indent=' ' * 4)
class TimeField(DefaultField): ext.adapts(IScaffoldingRecipeGrid, schema.interfaces.ITime) def __call__(self): di = json.loads(super(DateField, self).__call__()) di.update(dict(xtype='timecolumn', dateFormat='H:i:s.u')) return json.dumps(di, indent=' ' * 4)
class DefaultField(BuilderBase): ext.adapts(IScaffoldingRecipeGrid, schema.interfaces.IField) def __call__(self): di = dict(dataIndex=self.field.getName(), text=translate(self.field.title, context=self.recipe.request) ) return json.dumps(di, indent=' ' * 4)
class BuilderDefaultForm(BuilderBase): ext.adapts(IScaffoldingRecipeDisplay, schema.interfaces.IField) def __call__(self): di = dict(xtype='displayfield', name=self.field.getName(), fieldLabel=translate(self.field.title, context=self.recipe.request)) return json.dumps(di, indent=' ' * 4)
class PasswordField(StringField): ext.adapts(IScaffoldingRecipeForm, schema.interfaces.IPassword) def __call__(self): di = super(PasswordField, self).__call__() # super class returns a json string di = json.loads(di) di.update(dict(inputType='password')) return json.dumps(di, indent=' ' * 4)
class DateField(DefaultField): ext.adapts(IScaffoldingRecipeEditGrid, schema.interfaces.IDate) def __call__(self): di = json.loads(super(DateField, self).__call__()) di.update( dict(dict(field=dict(xtype='datefield')), dateFormat='Y-m-d H:i:s.u')) return json.dumps(di, indent=' ' * 4)
class StringField(BuilderBaseForm): ext.adapts(IScaffoldingRecipeForm, schema.interfaces.IField) def __call__(self): di = self.default() di.update(dict(xtype='textfield')) if self.field.max_length is not None: di['maxLength'] = self.field.max_length if self.field.min_length is not None: di['minLength'] = self.field.min_length return json.dumps(di, indent=' ' * 4)
class EditGrid(Grid): ext.name('editgrid') ext.provides(interfaces.IScaffoldingRecipeEditGrid) ext.adapts(IApplicationContext, interfaces.IRecipeDescriptive, IRequest) def __call__(self): return self.render_template('editgrid.json.tpl') @property def alias(self): return 'widget.EditGrid%s' % self.descriptive.classname @property def name(self): return self.classname(CLASS_NAMESPACE, 'editgrid', self.descriptive.classname)
class Model(BaseRecipe): ext.name('model') ext.adapts(IApplicationContext, interfaces.IRecipeDescriptive, IRequest) def __call__(self): fields = list() for name, zfield in getFieldsInOrder(self.descriptive.interface): fields.append( getMultiAdapter(( self, zfield, ), interfaces.IFieldBuilder)()) model = dict(extend='Ext.data.Model', fields=fields) classname = self.classname(CLASS_NAMESPACE, 'model', self.descriptive.classname) return self.buildclass(classname, model)
class ChoiceField(BuilderDefaultForm): ext.adapts(IScaffoldingRecipeDisplay, schema.interfaces.IChoice) def __call__(self): di = json.loads(super(ChoiceField, self).__call__()) di['renderer'] = '%renderer%' di = json.dumps(di, indent=' ' * 4) # Render the template tmpl = loader.load('combobox_renderer.json.tpl', cls=NewTextTemplate) stream = tmpl.generate(view=self) di = di.replace('"%renderer%"', stream.render()) return di @property def terms(self): vr = getVocabularyRegistry() return vr.get(None, self.field.vocabularyName)
class DataManagerEntryPoint(ext.MultiAdapter): """ manager all ajax request with CRUD options. """ ext.name('data') ext.adapts(IApplicationContext, IRequest) def __init__(self, context, request): self.context = context self.request = request def __call__(self): self.request.response.content_type = 'application/javascript' try: self.request.path_info_pop() entity = self.request.path_info_pop() transformer = getUtility(IModelTransformer, entity) batch = transformer.model(self.request) results = list() total = 0 for model in batch: handler = getMultiAdapter(( model, self.request, ), IModelHandler) result, subtotal = handler(model, batch) results += result total += subtotal data = transformer.json(results) self.successresponse('Data loaded from class %s' % model, data, total) except Exception as e: exceptionhandler = IJSONExceptionHandler(e) exceptionhandler(self.request) def successresponse(self, message, data, total): self.request.response.write( json.dumps(dict(success=True, message=message, total=total, data=data), indent=' ' * 4))
class Grid(BaseRecipe): ext.name('grid') ext.adapts(IApplicationContext, interfaces.IRecipeDescriptive, IRequest) def __call__(self): return self.render_template('grid.json.tpl') @property def title(self): return self.descriptive.title @property def name(self): return self.classname(CLASS_NAMESPACE, 'grid', self.descriptive.classname) @property def columns(self): columns = list() for name, zfield in getFieldsInOrder(self.descriptive.interface): columns.append( getMultiAdapter(( self, zfield, ), interfaces.IFieldBuilder)()) return columns @property def alias(self): return 'widget.Grid%s' % self.descriptive.classname @property def requires(self): return self.classname(CLASS_NAMESPACE, 'bufferedstore', self.descriptive.classname) @property def store(self): name = self.classname(CLASS_NAMESPACE, 'bufferedstore', self.descriptive.classname) return 'Ext.create("%s")' % name
class BaseRecipe(ext.MultiAdapter): ext.baseclass() ext.adapts() def __init__(self, context, descriptive, request): self.context = context self.descriptive = descriptive self.request = request def buildclass(self, name, extclass): return EXT_DEFINE_CLASS % ( name, json.dumps(extclass, indent=' ' * 4), ) def classname(self, namespace, type, name): return '%s.%s.%s' % (namespace, type, name) def render_template(self, tpl_name): tmpl = loader.load(tpl_name, cls=NewTextTemplate) stream = tmpl.generate(view=self) return stream.render()
class BufferedStore(BaseStore): ext.name('bufferedstore') ext.adapts(IApplicationContext, interfaces.IRecipeDescriptive, IRequest) def __call__(self): return self.render_template('store.json.tpl') @property def name(self): return 'Buffered%s' % self.descriptive.classname @property def cname(self): return self.classname(CLASS_NAMESPACE, 'bufferedstore', self.descriptive.classname) @property def buffered(self): return True @property def autoSync(self): return False
class BaseStore(BaseRecipe): ext.baseclass() ext.adapts(IApplicationContext, interfaces.IRecipeDescriptive, IRequest) def __init__(self, context, descriptive, request): super(BaseStore, self).__init__(context, descriptive, request) def __call__(self): return self.render_template('store.json.tpl') @property def url(self): return IBaseUrl(self.request).url('data/%s' % self.descriptive.classname) @property def name(self): return self.descriptive.classname @property def cname(self): return self.classname(CLASS_NAMESPACE, 'store', self.descriptive.classname) @property def model(self): return self.classname(CLASS_NAMESPACE, 'model', self.descriptive.classname) @property def buffered(self): return False @property def autoSync(self): return True
class CredentialsHandler(ext.AbstractModelHandler): """ This handler will just push the credential to request. After that a credential-plugin will create the information for the auth-plugin. """ ext.adapts(Credentials, ext.IRequest) def get(self, model, batch): """ just return a empty list """ return [model], 1 def create(self, model): raise NotImplementedError('not possible...') def delete(self, model): raise NotImplementedError('not possible...') def update(self, model, batch): self.request.GET.add(FORM_LOGIN, model.login) self.request.GET.add(FORM_PASSWORD, model.password) principal = getUtility(IAuthentication).authenticate(self.request) model.success = principal is not None return [model], 1
class ChoiceField(DefaultField): ext.adapts(IScaffoldingRecipeEditGrid, schema.interfaces.IChoice) def __call__(self): di = json.loads(super(ChoiceField, self).__call__()) # Create a combobox (same as form recipe) combobox = form.ChoiceField(self.recipe, self.field)() # But with empty fieldLabel combobox = combobox.replace(self.field.title, '') di.update(field="%combobox%") di['renderer'] = '%renderer%' di = json.dumps(di, indent=' ' * 4) di = di.replace('"%combobox%"', combobox) # Render the template tmpl = loader.load('combobox_renderer.json.tpl', cls=NewTextTemplate) stream = tmpl.generate(view=self) di = di.replace('"%renderer%"', stream.render()) return di @property def terms(self): vr = getVocabularyRegistry() return vr.get(None, self.field.vocabularyName)
class CardHandler(ext.AbstractModelHandler): ext.adapts(model.Card, IRequest) def get(self, model, batch): start, limit = self.slice() property, direction = self.sort() return cardIndexer.search_index(start, limit, property, direction) def create(self, model, batch): model.id = cardIndexer.get_next_id() cardIndexer.extend_index(model) return [model], 1 def update(self, model, batch): cardIndexer.update_index(model) return [model], 1 def delete(self, model, batch): cardIndexer.reduce_index(model) return [model], 1
class IdField(IntField): ext.adapts(IScaffoldingRecipeForm, schema.interfaces.IId)
class Display(BaseForm): ext.name('display') ext.adapts(IApplicationContext, interfaces.IRecipeDescriptive, IRequest) aliasprefix = 'Display'
class Form(BaseForm): ext.name('form') ext.adapts(IApplicationContext, interfaces.IRecipeDescriptive, IRequest)
class Store(BaseStore): ext.name('store') ext.adapts(IApplicationContext, interfaces.IRecipeDescriptive, IRequest)
class BoolField(ModelBuilderBase): ext.adapts(IScaffoldingRecipeModel, schema.interfaces.IBool) def __call__(self): return self.base(dict(type='boolean'))
class TimeField(ModelBuilderBase): ext.adapts(IScaffoldingRecipeModel, schema.interfaces.ITime) def __call__(self): return self.base(dict(type='date', dateFormat='H:i:s.u'))
class IntField(ModelBuilderBase): ext.adapts(IScaffoldingRecipeModel, schema.interfaces.IInt) def __call__(self): return self.base(dict(type='int'))