def expand_definition(pre_expand_definition): definition = [] for item in pre_expand_definition['fields']: field = {} field['name'] = item['name'] field['fullkey'] = strip_stars(item['name']) field['keyprefix'], field['key'] = split_prefix(field['fullkey']) field['starkey'] = item['name'] field['title'] = item.get('title') field['description'] = item.get('description') field['type'] = item.get('type','String') if 'default' in item: field['default'] = item['default'] field['attr'] = item.get('attr') if item.get('required') is True: field['validator'] = validator.Required() else: field['validator'] = None field['widget'] = item.get('widget') definition.append(field) return definition
def get_views(models_definition, views_definition): views = {} views_by_viewname = {} views_by_uses = {} viewnames_by_attribute = {} attributes_by_viewname = {} for view in views_definition: get_view(view, views, views_by_viewname) for model_type, definition in models_definition.items(): for view in definition.get('views',[]): get_view(view, views, views_by_viewname, model_type=model_type) parents = [] field_to_view = {} for model_type, definition in models_definition.items(): for field in definition['fields']: # some uses need to know whether the attr is composed of any sequences field['key'] = strip_stars(field['name']) if field.get('type','').startswith('Sequence'): fieldname = '%s.*'%field['name'] else: fieldname = field['name'] # If we have any references, build the appropriate lookups if 'attr' in field: refersto, uses = get_reference(field['attr']) if refersto: view = views_by_viewname[refersto] if not uses: uses = view['uses'] # Build the reference views dynamically if not explicit if isinstance(uses, basestring): views_by_uses.setdefault(view['url']+'-rev',{}).setdefault(model_type,[]).append( fieldname ) viewnames_by_attribute.setdefault(uses, set()).add(refersto) attributes_by_viewname.setdefault(refersto, {}).setdefault(model_type,set()).add( fieldname.replace('.*','*') ) else: views_by_uses.setdefault(view['url']+'-rev',{}).setdefault(model_type,[]).append( fieldname ) attributes_by_viewname.setdefault(refersto, {}).setdefault(model_type,set()).add( fieldname.replace('.*','*') ) for use in uses: viewnames_by_attribute.setdefault(use, set()).add(refersto) # Create any 'viewby' views if 'viewby' in field: if '*' in fieldname: raise Exception('Can\'t generate viewby views on attributes in sequences') if field['viewby'] == True: url = '%s/by_%s'%(model_type,fieldname) else: url = field['viewby'] views[url] = ("function(doc) { if (doc.model_type=='%s') { emit(doc.%s, null ); } }"%(model_type,field['name']),None) if 'viewby_count' in field: if field['viewby_count'] == True: url = '%s/by_%s_count'%(model_type,fieldname) else: url = field['viewby_count'] views[url] = ("function(doc) { if (doc.model_type == '%s') { emit(doc._id, 1); } }"%model_type, "function(keys, values) { return sum(values); }") # Generate dynamic views for reference reverse lookups for url, view in views_by_uses.items(): views[url] = buildview(view) out = {'views': views,'views_by_viewname': views_by_viewname, 'viewnames_by_attribute': viewnames_by_attribute, 'attributes_by_viewname':attributes_by_viewname,'views_by_uses':views_by_uses} return out