def get_model_replacement(self, view):
     subclass_filter = get_subclass_filter(view)
     if subclass_filter:
         model_str = '|'.join([get_model_name(model) for model in subclass_filter.subclasses])
     else:
         model_str = get_model_name(view.model)
     return model_str
 def add_validation(self, model):
     rules = {}
     for field in model._meta.fields:
         if is_excluded(model, field.name) or is_readonly(model, field.name) or is_included(model, field.name):
             continue
         key = field.name
         if self.camelcase:
             key = underscore_to_camel_case(key)
         rules[key] = ApiFieldRule(field).rule
     if rules:
         self.models[get_model_name(model)]['rules'] = rules
         if not self.cord:
             self.models[get_model_name(model)]['validate'] = 'validate'
 def get_include_related(self, model):
     related_models = {}
     name = get_model_name(model)
     if hasattr(model, 'API') and hasattr(model.API, 'include_related'):
         include_related = model.API.include_related
         for field in model._meta.fields:
             if field.name in include_related:
                 if self.camelcase:
                     field_name = underscore_to_camel_case(field.name)
                 else:
                     field_name = field.name
                 related_models[field_name] = get_model_name(get_related_model(field))
     if related_models:
         self.include_related[name] = related_models
 def add_model(self, model, extra):
     # Add the model for any resource type
     name = get_model_name(model)
     if not self.models.has_key(name):
         self.models[name] = {}
         if self.renameid:
             self.models[name]['idAttribute'] = camel_case_to_underscore(name) + '_id'
             if self.camelcase:
                 self.models[name]['idAttribute'] = underscore_to_camel_case(self.models[name]['idAttribute'])
         self.add_parse(model)
         if self.choices:
             self.add_choices(model)
         if self.defaults:
             self.add_defaults(model)
         if self.descriptions:
             self.add_descriptions(model)
         if self.formats:
             self.add_instructions(model)
         if  self.titles:
             self.add_titles(model)
         if self.validation:
             self.add_validation(model)
         self.translate_properties(model)
         self.get_include_related(model)
         self.get_readonly_fields(model)
     self.models[name].update(extra)
 def add_titles(self, model):
     titles = {}
     for field in model._meta.fields:
         if is_excluded(model, field.name):
             continue
         key = field.name
         if self.camelcase:
             key = underscore_to_camel_case(key)
         titles[key] = field.verbose_name.title()
     if titles:
         self.models[get_model_name(model)]['titles'] = titles
 def add_descriptions(self, model):
     subtitles = {}
     for field in model._meta.fields:
         if is_excluded(model, field.name):
             continue
         if hasattr(field, 'help_text') and field.help_text:
             key = field.name
             if self.camelcase:
                 key = underscore_to_camel_case(key)
             subtitles[key] = force_unicode(field.help_text)
     if subtitles:
         self.models[get_model_name(model)]['subtitles'] = subtitles
 def enum_patterns(self, patterns):
     for pattern in patterns:
         if pattern.callback:
             if isinstance(pattern.callback, (api_view, BasicApiView)):
                 self.regex_stack.append(pattern._regex)
                 view = pattern.callback
                 url = format_regex_stack(self.regex_stack)
                 resource_type = get_resource_type(self.regex_stack, pattern)
                 model_extra = {}
                 if resource_type == 'Collection':
                     collection_name = get_collection_name(view)
                     if url.find('<object_id>') == -1 and url.find('<slug>') == -1:
                         # Unrelated
                         self.collections[collection_name] = {'url': url, 'model': 'model###' + self.get_model_replacement(view)}
                     else:
                         # Related
                         parent_name = get_model_name(view.parent_model)
                         if url.find('<object_id>') != -1:
                             if not self.related_collections.has_key(parent_name):
                                 self.related_collections[parent_name] = []
                             self.related_collections[parent_name].append({'collection': collection_name, 'url': url.replace('<object_id>', '" + this.id + "')})
                             # Generate a blank collection class for related items if needed
                             if not self.collections.has_key(collection_name):
                                 self.collections[collection_name] = {'model': 'model###' + get_model_name(view.model)}
                 elif resource_type == 'Object':
                     if url.find('<object_id>') != -1:
                         # Remove the last piece of the url path, should be <object_id>, don't look for <slug> because the idAttribute above only allows the object id
                         model_extra['urlRoot'] = '/' + '/'.join(url.strip('/').split('/')[:-1])
                 elif resource_type == 'Single Object':
                     self.singletons[get_model_name(view.model)] = '/' + url.strip('/')
                 # Add the model for any view without a subclass filter
                 if not get_subclass_filter(view):
                     self.add_model(view.model, model_extra)
                 self.regex_stack.pop()
         else:
             self.regex_stack.append(pattern._regex)
             self.enum_patterns(pattern.url_patterns)
     if self.regex_stack:
         self.regex_stack.pop()
 def add_parse(self, model):
     fields = []
     for field in model._meta.fields:
         if is_excluded(model, field.name):
             continue
         # Parse DateField and DateTimeFields, but not TimeFields
         if isinstance(field, DateField):
             if self.camelcase:
                 fields.append("'%s'" % underscore_to_camel_case(field.name))
             else:
                 fields.append("'%s'" % field.name)
     if fields:
         self.models[get_model_name(model)]['parse'] = ', '.join(fields)
 def add_defaults(self, model):
     name = get_model_name(model)
     for field in model._meta.fields:
         if is_excluded(model, field.name) or is_readonly(model, field.name):
             continue
         default = field.default
         if isinstance(default, type):
             default = default()
         if default is not NOT_PROVIDED and not callable(default):
             if not self.models[name].has_key('defaults'):
                 self.models[name]['defaults'] = {}
             key = field.name
             if self.camelcase:
                 key = underscore_to_camel_case(key)
             self.models[name]['defaults'][key] = default
 def add_choices(self, model):
     choices = {}
     for field in model._meta.fields:
         if is_excluded(model, field.name):
             continue
         if hasattr(field, 'choices') and field.choices:
             field_choices = {}
             for choice in field.choices:
                 field_choices[choice[0]] = choice[1]
             key = field.name
             if self.camelcase:
                 key = underscore_to_camel_case(key)
             choices[key] = field_choices
     if choices:
         self.models[get_model_name(model)]['choices'] = choices
 def get_readonly_fields(self, model):
     fields = []
     included_fields = []
     name = get_model_name(model)
     for field in model._meta.fields:
         if is_excluded(model, field.name):
             continue
         if is_readonly(model, field.name):
             key = field.name
             if self.camelcase:
                 key = underscore_to_camel_case(key)
             if is_included(model, field.name):
                 included_fields.append(key)
             fields.append(key)
     if field:
         self.readonly_fields[name] = fields
     if included_fields:
         self.readonly_included_fields[name] = included_fields
 def add_instructions(self, model):
     instructions = {}
     for field in model._meta.fields:
         if is_excluded(model, field.name):
             continue
         key = field.name
         if self.camelcase:
             key = underscore_to_camel_case(key)
         message = force_unicode(field.error_messages.get('invalid', field.error_messages.get('invalid_choice', '')))
         default_invalid = default_invalid_choice = None
         for cls in reversed([field.__class__] + get_base_classes(field.__class__)):
             if not hasattr(cls, 'default_error_messages'):
                 continue
             default_invalid = cls.default_error_messages.get('invalid', default_invalid)
             default_invalid_choice = cls.default_error_messages.get('invalid_choice', default_invalid_choice)
         if message and message != default_invalid and message != default_invalid_choice:
             instructions[key] = message
     if instructions:
         self.models[get_model_name(model)]['instructions'] = instructions
 def translate_properties(self, model):
     lang = 'es6' if self.es6 else 'js'
     model_properties = {}
     model_properties_args = {}
     for cls in [model] + get_base_classes(model):
         for name in cls.__dict__:
             attr = cls.__dict__[name]
             if type(attr) is property and attr.fget and hasattr(attr.fget, 'api_code'):
                 if self.camelcase:
                     name = underscore_to_camel_case(name)
                 if getattr(attr.fget, 'api_translations', None) and attr.fget.api_translations.has_key(lang):
                     model_properties[name] = attr.fget.api_translations[lang]
                 else:
                     model_properties[name] = translate_code(attr.fget.api_code, lang, BackboneAttributeTransformer(model))
     # If using Cord, then convert all references to other api properties to a get model call then to just arguments passed into the getter instead
     if self.cord:
         def replace_properties(m):
             prop = m.group(1)
             if prop in model_properties:
                 return 'this.get("%s")' % prop
             return m.group(0)
         def replace_attributes(args, m):
             attr = m.group(1)
             args.add(attr)
             return attr
         for name, code in model_properties.items():
             model_properties_args[name] = set()
             if code.find('this.id'):
                 model_properties_args[name].add('id')
             code = re.sub(r'this.([0-9a-zA-Z_]*)', replace_properties, code)
             model_properties[name] = re.sub(r'this.get\("([0-9a-zA-Z_]*)"\)', partial(replace_attributes, model_properties_args[name]), code)
     model_name = get_model_name(model)
     if model_properties:
         self.model_properties[model_name] = model_properties
     if model_properties_args:
         self.model_properties_args[model_name] = model_properties_args
    def get_context(self, app_label):
        context = {
            'name': app_label,
            'name_lower': app_label[0].lower() + app_label[1:]
        }
        if hasattr(self, 'extra_context'):
            context.update(self.extra_context())

        # Loop over the view mappings
        for mapping_name in self.mappings:
            mapping = self.mappings[mapping_name]
            lines = []
            for url_format, view in self.views.iteritems():
                for action in self.get_view_actions(self.urls[url_format],
                                                    view):
                    line = None
                    if mapping.has_key(action):
                        format_context = {
                            'url':
                            self.urls[url_format],
                            'url_format':
                            url_format,
                            'view':
                            view,
                            'app_name':
                            app_label,
                            'app_name_lower':
                            app_label[0].lower() + app_label[1:],
                            'model_name':
                            view.model.__name__,
                            'name':
                            view.model.__name__,
                            'name_lower':
                            view.model.__name__[0].lower() +
                            view.model.__name__[1:],
                            'name_plural':
                            view.model._meta.verbose_name_plural.title(
                            ).replace(' ', ''),
                            'name_plural_lower':
                            view.model._meta.verbose_name_plural[0].lower() +
                            view.model._meta.verbose_name_plural.title(
                            ).replace(' ', '')[1:],
                            'login':
                            ((view.requirements & ApiRequirement.LOGIN)
                             and not (action.startswith('READ') and
                                      (view.requirements
                                       & ApiRequirement.ANONYMOUS_READ))),
                            'https':
                            (view.requirements & ApiRequirement.HTTPS),
                            'hmac': (view.requirements & ApiRequirement.HMAC)
                        }
                        subclass_filter = get_subclass_filter(view)
                        if subclass_filter:
                            format_context['subclasses'] = [
                                (_ApiModel(model).id_field[1],
                                 get_model_name(model))
                                for model in subclass_filter.subclasses
                            ]
                        format_context.update(
                            self.get_param_context(self.urls[url_format],
                                                   action))
                        if hasattr(view, 'parent_model') and view.parent_model:
                            # Related and basic api views
                            format_context[
                                'parent_name'] = view.parent_model.__name__
                            format_context[
                                'parent_name_lower'] = view.parent_model.__name__[
                                    0].lower() + view.parent_model.__name__[1:]
                            format_context[
                                'parent_name_plural'] = view.parent_model._meta.verbose_name_plural.title(
                                ).replace(' ', '')
                            format_context[
                                'parent_name_plural_lower'] = view.parent_model._meta.verbose_name_plural[
                                    0].lower(
                                    ) + view.parent_model._meta.verbose_name_plural.title(
                                    ).replace(' ', '')[1:]
                        line = self.perform_mapping(mapping[action],
                                                    format_context)
                    if line is None:
                        raise CommandError("No such mapping for %s in %s." %
                                           (action, mapping_name))
                    elif line:
                        line = line.split('\n')
                        if not mapping.get('RemoveDuplicates',
                                           False) or not is_sublist(
                                               lines, line):
                            lines.extend(line)
            context[mapping_name] = lines
            if mapping.get('Sort', False):
                context[mapping_name].sort()

        return context