def test_signal(): class Model(object): pass class SubModel(Model): pass @reg.dispatch(reg.match_instance('model'), reg.match_key('signal', lambda model, signal: signal)) def event(model, signal): raise NotImplementedError @event.subscribe(model=Model, signal='event') def one(model, signal): return 1 @event.subscribe(model=Model, signal='event') def two(model, signal): return 2 @event.subscribe(model=SubModel, signal='event') def three(model, signal): return 3 mobj = Model() smobj = SubModel() assert list(sorted(event.publish(model=mobj, signal='event'))) == [1, 2] assert list(sorted(event.publish(model=smobj, signal='event'))) == [1, 2, 3]
class CellApp(morepath.App): cell = dectate.directive(CellAction) @morepath.dispatch_method(reg.match_instance('model'), reg.match_key('name')) def get_cell_class(self, model, name): return None def get_cell(self, model, request, name): return self.get_cell_class(model, name)(model, request)
class App(ChameleonApp, morpfw.SQLApp, DefaultAuthzPolicy): request_class = WebAppRequest portlet = dectate.directive(directive.PortletFactoryAction) portletprovider = dectate.directive(directive.PortletProviderFactoryAction) structure_column = dectate.directive(directive.StructureColumnAction) @reg.dispatch_method(reg.match_instance('model'), reg.match_instance('request'), reg.match_key('name')) def get_structure_column(self, model, request, name): raise NotImplementedError('Get structure columns for %s structure:%s' % (model, name)) def get_portletprovider(self, name): return self.config.portletprovider_registry.get_provider(name) @reg.dispatch_method(reg.match_class('schema')) def get_schemaextender(self, schema): return None
class SignalApp(dectate.App): jslcrud_subscribe = dectate.directive(Connect) @reg.dispatch_method( reg.match_instance('model', lambda self, request, obj, signal: obj), reg.match_key('signal', lambda self, request, obj, signal: signal)) def _events(self, request, obj, signal): raise NotImplementedError def jslcrud_publish(self, request, obj, signal): return self._events.publish(self, request, obj, signal)
for context in subobjects: context.__parent__ = self if acl: self.__acl__ = acl def __getitem__(self, key): return self.subobjects[key] ACL_READABLE = [(Allow, R_SYSADMIN, ALL_PERMISSIONS), (Allow, Everyone, P_READ), DENY_ALL] ACL_RESTRICTIVE = [(Allow, R_SYSADMIN, ALL_PERMISSIONS), DENY_ALL] @reg.dispatch( reg.match_instance('inst_ctx', lambda inst_ctx, ctx: inst_ctx._instance), reg.match_key('ctx', lambda inst_ctx, ctx: ctx.collection.qual_name())) def collection_creation_side_effects(inst_ctx, ctx): """Multiple dispatch adapter for collection-related side effects""" return () class AppRoot(DictContext): """The root context. Anything not defined by a root comes here.""" def __init__(self, request=None, user_id=None): self.request = request self.user_id = user_id self._permissions = None self._user_cache = None super(AppRoot, self).__init__('', ACL_READABLE, [ Api2Context(self, ACL_RESTRICTIVE),
class App(object): @reg.dispatch_method(reg.match_instance('model'), reg.match_key('signal', lambda self, model, signal: signal)) def event(self, model, signal): raise NotImplementedError
from functools import partial from .errors import ValidationError, FormValidationError, FieldValidationError from jsonschema import Draft4Validator from .util import jsl_to_jsonobject, dataclass_to_jsl, dataclass_get_type import reg from morepath.publish import resolve_model import urllib import re @reg.dispatch(reg.match_instance('model'), reg.match_instance('request')) def get_data(model, request): raise NotImplementedError def regex_validator(pattern, name): p = re.compile(pattern) def _regex_validator(value): if not p.match(value): raise FieldValidationError('%s does not match %s pattern' % (value, name)) return _regex_validator def load(validator, schema, request): newreq = request.app.request_class(request.environ.copy(), request.app.root, path_info=urllib.parse.unquote( request.path))
class App(JsonSchemaApp, signals.SignalApp): dataprovider = dectate.directive(actions.DataProviderAction) jsonprovider = dectate.directive(actions.JSONProviderAction) formvalidators = dectate.directive(actions.FormValidatorAction) identifierfields = dectate.directive(actions.IdentifierFieldsAction) default_identifier = dectate.directive(actions.DefaultIdentifierAction) rulesprovider = dectate.directive(actions.RulesProviderAction) uuidfield = dectate.directive(actions.UUIDFieldAction) statemachine = dectate.directive(actions.StateMachineAction) searchprovider = dectate.directive(actions.SearchProviderAction) aggregateprovider = dectate.directive(actions.AggregateProviderAction) xattrprovider = dectate.directive(actions.XattrProviderAction) storage = dectate.directive(actions.StorageAction) blobstorage = dectate.directive(actions.BlobStorageAction) typeinfo = dectate.directive(actions.TypeInfoFactoryAction) def get_storage(self, model, request): blobstorage = self.get_blobstorage(model, request) return self._get_storage(model, request, blobstorage) def get_blobstorage(self, model, request): return self._get_blobstorage(model, request) @reg.dispatch_method(reg.match_class('model'), reg.match_instance('request'), reg.match_instance('blobstorage')) def _get_storage(self, model, request, blobstorage): raise NotImplementedError @reg.dispatch_method(reg.match_class('model'), reg.match_instance('request')) def _get_blobstorage(self, model, request): return NullBlobStorage() @reg.dispatch_method( reg.match_class('schema', lambda self, schema, obj, storage: schema), reg.match_instance('obj'), reg.match_instance('storage')) def get_dataprovider(self, schema, obj, storage): raise NotImplementedError('Dataprovider for %s/%s' % (storage.__class__, obj.__class__)) @reg.dispatch_method(reg.match_instance('obj')) def get_jsonprovider(self, obj): raise NotImplementedError('JSONProvider for %s' % obj.__class__) @reg.dispatch_method(reg.match_class('schema', lambda self, schema: schema)) def get_formvalidators(self, schema): return [] @reg.dispatch_method(reg.match_class('schema', lambda self, schema: schema)) def get_identifierfields(self, schema): raise NotImplementedError('IdentifierFields for %s' % schema) @reg.dispatch_method(reg.match_class('schema', lambda self, schema: schema)) def get_uuidfield(self, schema): return 'uuid' @reg.dispatch_method( reg.match_class('schema', lambda self, schema, obj, request: schema)) def get_default_identifier(self, schema, obj, request): return None @reg.dispatch_method( reg.match_instance('model', lambda self, context: context)) def get_rulesprovider(self, context): raise NotImplementedError @reg.dispatch_method( reg.match_instance('model', lambda self, context: context)) def get_statemachine(self, context): raise NotImplementedError @reg.dispatch_method( reg.match_instance('model', lambda self, context: context)) def get_searchprovider(self, context): raise NotImplementedError @reg.dispatch_method( reg.match_instance('model', lambda self, context: context)) def get_aggregateprovider(self, context): raise NotImplementedError @reg.dispatch_method( reg.match_instance('model', lambda self, context: context)) def get_xattrprovider(self, context): raise NotImplementedError @reg.dispatch_method(reg.match_key('name')) def get_typeinfo_factory(self, name): raise NotImplementedError def get_compositekey_separator(self): morp_settings = self.settings.application return morp_settings.compositekey_separator def join_identifier(self, *args): separator = self.get_compositekey_separator() return separator.join(args) def permits(self, request: morepath.Request, context: Model, permission: str): identity = request.identity return self._permits(identity, context, permission)
class App(ChameleonApp, morpfw.SQLApp, MorpCCAuthzPolicy): request_class = WebAppRequest portlet = dectate.directive(directive.PortletFactoryAction) portletprovider = dectate.directive(directive.PortletProviderFactoryAction) contextportletprovider = dectate.directive( directive.ContextPortletProviderFactoryAction) structure_column = dectate.directive(directive.StructureColumnAction) schemaextender = dectate.directive(directive.SchemaExtenderAction) messagingprovider = dectate.directive(directive.MessagingProviderAction) vocabulary = dectate.directive(directive.VocabularyAction) indexer = dectate.directive(directive.IndexerAction) indexresolver = dectate.directive(directive.IndexResolverAction) behavior = dectate.directive(directive.BehaviorAction) application_behavior = dectate.directive( directive.ApplicationBehaviorAction) default_factory = dectate.directive(directive.DefaultFactoryAction) restricted_module = dectate.directive(directive.RestrictedModuleAction) breadcrumb = dectate.directive(directive.BreadcrumbAction) setting_page = dectate.directive(directive.SettingPageAction) setting_modules = dectate.directive(directive.SettingModuleAction) license_cert = dectate.directive(directive.LicenseCertAction) license_key = dectate.directive(directive.LicenseKeyAction) copyright_notice = dectate.directive(directive.CopyrightNoticeAction) datasource = dectate.directive(directive.DataSourceAction) permission_resolver = dectate.directive(directive.PermissionResolverAction) @reg.dispatch_method(reg.match_instance("model"), reg.match_key("name")) def get_indexer(self, model, name): return None @reg.dispatch_method( reg.match_instance("model"), reg.match_instance("request"), reg.match_key("name"), ) def get_structure_column(self, model, request, name): raise NotImplementedError("Get structure columns for %s structure:%s" % (model, name)) def get_portletprovider(self, name): return self.config.portletprovider_registry.get_provider(name) @reg.dispatch_method(reg.match_instance("model"), reg.match_key("name")) def get_contextportletprovider(self, model, name): return None @reg.dispatch_method(reg.match_class("schema")) def get_schemaextender(self, schema): return schema @reg.dispatch_method(reg.match_instance("request"), reg.match_key("name")) def get_messagingprovider(self, request, name): raise NotImplementedError("Messaging provider %s is not available" % name) @reg.dispatch_method(reg.match_instance("request"), reg.match_key("name")) def get_vocabulary(self, request, name): return None @reg.dispatch_method(reg.match_key("name")) def get_behavior_factory(self, name): raise NotImplementedError @reg.dispatch_method(reg.match_key("name")) def get_application_behavior_factory(self, name): raise NotImplementedError @reg.dispatch_method(reg.match_key("name")) def get_default_factory(self, name): raise NotImplementedError @reg.dispatch_method(reg.match_key("name")) def get_index_resolver(self, name): raise NotImplementedError @reg.dispatch_method(reg.match_key("name")) def get_restricted_module(self, name): raise ImportError( "Module {} is not allowed to be imported in this context".format( name)) @reg.dispatch_method( reg.match_instance("model"), reg.match_instance("request"), ) def get_breadcrumb(self, model, request): return [] @reg.dispatch_method(reg.match_instance("request")) def get_license_cert(self, request): return None @reg.dispatch_method(reg.match_instance("request")) def get_license_key(self, request): return None @reg.dispatch_method(reg.match_instance("request")) def get_copyright_notice(self, request): dt = date.today() return ( "Morp Control Center. © 2018-%s Mohd Izhar Firdaus Bin Ismail" % dt.year) @reg.dispatch_method(reg.match_key("name")) def get_datasource_factory(self, name): raise NotImplementedError() def get_datasource(self, name, request): return self.config.datasource_registry.get(name=name, request=request) def resolve_permissionassignment(self, request, model, permission, identity): return self.config.permissionresolver_registry.resolve( request, model, permission, identity) def render_view(self, context, request, name=""): lookup = self.get_view.by_predicates(model=context.__class__, name=name) if lookup and lookup.component: try: return lookup.component(obj=context, request=request, app=self) except HTTPException as e: return None return None
val = getattr(obj, key) # TODO Probably should treat Python types elsewhere! if for_json and (isinstance(val, datetime) or isinstance(val, date)): amap[key] = val.isoformat() elif for_json and isinstance(val, Decimal): amap[key] = float(str(val)) elif for_json and not isinstance( val, (str, int, float, list, dict, bool, type(None))): continue else: amap[key] = val return amap @reg.dispatch( # Dispatch on type of *obj* and value of *flavor*. reg.match_instance('obj'), reg.match_key('flavor', lambda obj, flavor, **kw: flavor)) # Cannot type-annotate this function, Reg 0.11 does not support it def to_dict(obj, flavor='', **kw): """Overloadable version of our function ``reuse_dict``. You can register your own implementations depending on *obj* and *flavor*. """ return reuse_dict(obj, **kw) ''' Ideas ----- - Use a JSON serializer without tree traversal, but support Python data types such as datetime
class App(JsonSchemaApp, signals.SignalApp): jslcrud_dataprovider = dectate.directive(actions.DataProviderAction) jslcrud_jsonprovider = dectate.directive(actions.JSONProviderAction) jslcrud_jsontransfrom = dectate.directive(actions.JSONTransformAction) jslcrud_formvalidators = dectate.directive(actions.FormValidatorAction) jslcrud_identifierfields = dectate.directive( actions.IdentifierFieldsAction) jslcrud_default_identifier = dectate.directive( actions.DefaultIdentifierAction) jslcrud_rulesadapter = dectate.directive(actions.RulesAdapterAction) jslcrud_uuidfield = dectate.directive(actions.UUIDFieldAction) jslcrud_statemachine = dectate.directive(actions.StateMachineAction) @reg.dispatch_method( reg.match_class('schema', lambda self, schema, obj, storage: schema), reg.match_instance('obj'), reg.match_instance('storage')) def get_jslcrud_dataprovider(self, schema, obj, storage): raise NotImplementedError('Dataprovider for %s/%s' % (storage.__class__, obj.__class__)) @reg.dispatch_method(reg.match_instance('obj')) def get_jslcrud_jsonprovider(self, obj): raise NotImplementedError('JSONProvider for %s' % obj.__class__) @reg.dispatch_method(reg.match_class('schema', lambda self, schema: schema)) def get_jslcrud_jsontransform(self, schema): raise NotImplementedError('JSONTransform for %s' % schema) @reg.dispatch_method(reg.match_class('schema', lambda self, schema: schema)) def get_jslcrud_formvalidators(self, schema): return [] @reg.dispatch_method(reg.match_class('schema', lambda self, schema: schema)) def get_jslcrud_identifierfields(self, schema): raise NotImplementedError('IdentifierFields for %s' % schema) @reg.dispatch_method(reg.match_class('schema', lambda self, schema: schema)) def get_jslcrud_uuidfield(self, schema): return 'uuid' @reg.dispatch_method( reg.match_class('schema', lambda self, schema, obj, request: schema)) def get_jslcrud_default_identifier(self, schema, obj, request): return None @reg.dispatch_method(reg.match_instance('model', lambda self, obj: obj)) def _jslcrud_rulesadapter(self, obj): raise NotImplementedError @reg.dispatch_method( reg.match_instance('model', lambda self, context: context)) def _jslcrud_statemachine(self, context): raise NotImplementedError def get_jslcrud_compositekey_separator(self): morp_settings = getattr(self.settings, 'jslcrud', {}) return morp_settings.get('compositekey_separator', '!!!') def jslcrud_join_identifier(self, *args): separator = self.get_jslcrud_compositekey_separator() return separator.join(args)
val = getattr(obj, key) # TODO Probably should treat Python types elsewhere! if for_json and (isinstance(val, datetime) or isinstance(val, date)): amap[key] = val.isoformat() elif for_json and isinstance(val, Decimal): amap[key] = float(str(val)) elif for_json and not isinstance( val, (str, int, float, list, dict, bool, type(None))): continue else: amap[key] = val return amap @reg.dispatch( # Dispatch on type of *obj* and value of *flavor*. reg.match_instance("obj"), reg.match_key("flavor", lambda obj, flavor, **kw: flavor), ) # Cannot type-annotate this function, Reg 0.11 does not support it def to_dict(obj, flavor="", **kw): """Overloadable version of our function ``reuse_dict``. You can register your own implementations depending on *obj* and *flavor*. """ return reuse_dict(obj, **kw) """ Ideas -----
class App(morepath.App): _cors = dectate.directive(action.CORSAction) @classmethod def cors(cls, *args, **kwargs): cls._cors(*args, **kwargs)(None) @reg.dispatch_method( reg.match_instance('model'), reg.match_key( 'view_name', lambda self, model, request, requested_origin: request.view_name)) def get_cors_allowed_origin(self, model, request, requested_origin): return self.settings.cors.allowed_origin @reg.dispatch_method( reg.match_instance('model'), reg.match_key( 'view_name', lambda self, model, request, requested_method: request.view_name)) def get_cors_allowed_methods(self, model, request, requested_method): if model is None: return self.settings.cors.allowed_verbs res = [] for m in self.settings.cors.allowed_verbs: f = self.get_view.by_predicates(model=model.__class__, name=request.view_name, request_method=m) if f and f.component: res.append(m) return res @reg.dispatch_method( reg.match_instance('model'), reg.match_key( 'view_name', lambda self, model, request, requested_headers: request.view_name)) def get_cors_allowed_headers(self, model, request, requested_headers): return self.settings.cors.allowed_headers @reg.dispatch_method(reg.match_instance('model'), reg.match_key( 'view_name', lambda self, model, request: request.view_name)) def get_cors_expose_headers(self, model, request): return self.settings.cors.expose_headers @reg.dispatch_method(reg.match_instance('model'), reg.match_key( 'view_name', lambda self, model, request: request.view_name)) def get_cors_allow_credentials(self, model, request): return self.settings.cors.allow_credentials @reg.dispatch_method(reg.match_instance('model'), reg.match_key( 'view_name', lambda self, model, request: request.view_name)) def get_cors_max_age(self, model, request): return self.settings.cors.max_age
class App(ChameleonApp, morpfw.SQLApp, DefaultAuthzPolicy): request_class = WebAppRequest portlet = dectate.directive(directive.PortletFactoryAction) portletprovider = dectate.directive(directive.PortletProviderFactoryAction) structure_column = dectate.directive(directive.StructureColumnAction) schemaextender = dectate.directive(directive.SchemaExtenderAction) messagingprovider = dectate.directive(directive.MessagingProviderAction) vocabulary = dectate.directive(directive.VocabularyAction) indexer = dectate.directive(directive.IndexerAction) indexresolver = dectate.directive(directive.IndexResolverAction) behavior = dectate.directive(directive.BehaviorAction) application_behavior = dectate.directive( directive.ApplicationBehaviorAction) default_factory = dectate.directive(directive.DefaultFactoryAction) restricted_module = dectate.directive(directive.RestrictedModuleAction) @reg.dispatch_method(reg.match_instance("model"), reg.match_key("name")) def get_indexer(self, model, name): return None @reg.dispatch_method( reg.match_instance("model"), reg.match_instance("request"), reg.match_key("name"), ) def get_structure_column(self, model, request, name): raise NotImplementedError("Get structure columns for %s structure:%s" % (model, name)) def get_portletprovider(self, name): return self.config.portletprovider_registry.get_provider(name) @reg.dispatch_method(reg.match_class("schema")) def get_schemaextender(self, schema): return schema @reg.dispatch_method(reg.match_instance("request"), reg.match_key("name")) def get_messagingprovider(self, request, name): raise NotImplementedError("Messaging provider %s is not available" % name) @reg.dispatch_method(reg.match_instance("request"), reg.match_key("name")) def get_vocabulary(self, request, name): return None @reg.dispatch_method(reg.match_key("name")) def get_behavior_factory(self, name): raise NotImplementedError @reg.dispatch_method(reg.match_key("name")) def get_application_behavior_factory(self, name): raise NotImplementedError @reg.dispatch_method(reg.match_key("name")) def get_default_factory(self, name): raise NotImplementedError @reg.dispatch_method(reg.match_key("name")) def get_index_resolver(self, name): raise NotImplementedError @reg.dispatch_method(reg.match_key("name")) def get_restricted_module(self, name): raise ImportError( "Module {} is not allowed to be imported in this context".format( name)) def render_view(self, context, request, name=""): lookup = self.get_view.by_predicates(model=context.__class__, name=name) if lookup and lookup.component: try: return lookup.component(obj=context, request=request, app=self) except HTTPException as e: return None return None