def show_dbs():
    """return a list of all dbs and related collections.
    Return an empty list on error.
    """

    collection_list = []
    mc = client_connector()
    if not mc:
        # The client couldn't connect
        return ()

    dbs = mc.database_names()
    for d in dbs:
        dbc = mc[d]
        collections = dbc.collection_names()
        collections = remove_values_from_list(collections, "system.indexes")
        collection_list.append({"name": d, "collections": collections})
    return tuple(collection_list) def mongodb_drop_collection(database_name, collection_name):
    """Drop Collection"""
    try:
        mc = MongoClient(getattr(settings, 'MONGODB_CLIENT',
                                 'mongodb://localhost:27017/'))
        dbs = mc[database_name]
        dbs.drop_collection(collection_name)
        # print "success"
        return ""
    except Exception:
        # error connecting to mongodb
        return str(sys.exc_info()) def mongodb_drop_database(database_name):
    """Drop Database"""
    try:
        mc = MongoClient(getattr(settings, 'MONGODB_CLIENT',
                                 'mongodb://localhost:27017/'))
        mc.drop_database(database_name)
        return ""

    except Exception:
        # error connecting to mongodb
        # print str(sys.exc_info())
        return str(sys.exc_info()) def mongo_delete_json_util(database_name, collection_name, query={},
                           just_one=False):

    response_dict = {}
    valid_json = True
    try:
        query = json.loads(query, object_pairs_hook=OrderedDict)
        if not isinstance(query, type(OrderedDict())):
            valid_json = False
    except ValueError:
        valid_json = False

    if not valid_json:
        response_dict['code'] = 400
        response_dict['type'] = "Error"
        response_dict['message'] = "Your query was not valid" \
                                   " JSON or not a dictionary (i.e.{})."
    else:
        # valid json so run the delete
        response_dict = delete_mongo(
            query,
            database_name=database_name,
            collection_name=collection_name,
            just_one=False)

    return response_dict def mongo_create_json_util(document, database_name,
                           collection_name):

    response_dict = {}
    valid_json = True

    try:
        document = json.loads(document, object_pairs_hook=OrderedDict)
        if not isinstance(document, type(OrderedDict())):
            valid_json = False
    except ValueError:
        valid_json = False

    if not valid_json:
        response_dict['code'] = 400
        response_dict['type'] = "Error"
        response_dict[
            'message'] = "Your query was not valid JSON" \
                         " or not a JSON object (i.e.{})."
    else:
        # valid json so run the delete
        response_dict = write_mongo(document,
                                    database_name=database_name,
                                    collection_name=collection_name)
    return response_dict class EnsureIndexForm(forms.Form):
    key = forms.CharField(label=_("Key"))
    database_name = forms.CharField()
    collection_name = forms.CharField()
    required_css_class = 'required'

    def save(self, database_name, collection_name):
        key = self.cleaned_data["key"]
        result = mongodb_ensure_index(database_name, collection_name, key)
        return result class DeleteForm(forms.Form):
    query = forms.CharField(widget=forms.Textarea, initial="{}")
    just_one = forms.BooleanField(required=False)
    database_name = forms.CharField()
    collection_name = forms.CharField()

    required_css_class = 'required'

    def clean_query(self):

        query = self.cleaned_data.get('query', '')

        try:
            djson = json.loads(query)
            if not isinstance(djson, type({})):
                raise forms.ValidationError("""Not a JSON
                                            object (i.e. {} )""")

        except ValueError:
            raise forms.ValidationError('Invalid JSON.')

        return query class DocumentForm(forms.Form):
    document = forms.CharField(widget=forms.Textarea)
    database_name = forms.CharField()
    collection_name = forms.CharField()

    required_css_class = 'required'

    def clean_document(self):

        document = self.cleaned_data.get('document', '')

        try:
            djson = json.loads(document)
            if not isinstance(djson, type({})):
                raise forms.ValidationError('Not a JSON object (i.e. {} )')

        except ValueError:
            raise forms.ValidationError('Invalid JSON.')

        return document class CreateDatabaseForm(forms.Form):

    database_name = forms.CharField()
    collection_name = forms.CharField()
    initial_document = forms.CharField(
        widget=forms.Textarea,
        help_text="""You must create a document in order to
                     create a new database and collection""")
    required_css_class = 'required'

    def clean_initial_document(self):

        initial_document = self.cleaned_data.get('initial_document', '')

        try:
            djson = json.loads(initial_document)
            if not isinstance(djson, type({})):
                raise forms.ValidationError('Not a JSON object (i.e. {} )')

        except ValueError:
            raise forms.ValidationError('Invalid JSON.')

        return initial_document

    def save(self):

        result = create_mongo_db(self.cleaned_data["database_name"],
                                 self.cleaned_data["collection_name"],
                                 self.cleaned_data["initial_document"])
        return result class ConfirmDropForm(forms.Form):
    name = forms.CharField(max_length=256)
    required_css_class = 'required' class APIWizardForm(forms.Form):
    auth_type = forms.ChoiceField(choices=AUTH_TYPE_CHOICES,
                                  widget=forms.RadioSelect)
    http_method = forms.ChoiceField(choices=HTTP_METHOD_CHOICES,
                                    widget=forms.RadioSelect)
    api_type = forms.ChoiceField(choices=API_TYPE_CHOICES,
                                 widget=forms.RadioSelect, help_text='''A simple API that accepts get parameters and no special query (choose this option if you're unsure), Setup a read API with a custom query parameters that feed into a custom MongoDB query that you define.''')

    database_name = forms.CharField()
    collection_name = forms.CharField() class WriteAPIHTTPAuth(models.Model):
    created_by = models.ForeignKey(
        get_user_model(), blank=True, null=True, on_delete=models.CASCADE)
    groups = models.ManyToManyField(
        Group,
        blank=True,
        related_name="djmongo_write_httpauth_groups",
        help_text=_(
            "Use ctrl to select multiple "
            "groups. If no groups are "
            "selected blank, any user may "
            "access the API."))
    slug = models.SlugField(max_length=100, unique=True, help_text=_(
        "The slug is the unique part of the URL for your API."))

    http_post = models.BooleanField(default=True, blank=True)
    http_put = models.BooleanField(default=True, blank=True)
    database_name = models.CharField(max_length=100)
    collection_name = models.CharField(max_length=100)
    json_schema = models.TextField(
        max_length=20480,
        default="{}",
        verbose_name="JSON Schema",
        help_text="""Default "{}", means no JSON Schema.""")
    readme_md = models.TextField(max_length=4096, default="", blank=True)
    creation_date = models.DateField(auto_now_add=True)

    class Meta:
        get_latest_by = "creation_date"
        ordering = ('-creation_date',)
        verbose_name_plural = _("Write APIs with HTTPAuth")
        verbose_name = _("Write API with HTTPAuth")

    def url(self):
        return reverse('djmongo_api_write_to_collection_with_httpauth', args=(self.slug,))

    def __str__(self):
        return "%s" % (self.slug)

    def allgroups(self):
        groups = []
        for g in self.groups.all():
            groups.append(g.name)
        return json.dumps(groups)

    def http_methods(self):
        l = []
        if self.http_post:
            l.append("POST")
        if self.http_put:
            l.append("PUT")
        return l

    def auth_method(self):
        return 'httpauth'

    def http_get_response(self):
        od = OrderedDict()
        od['http_methods'] = self.http_methods()
        od['auth_method'] = self.auth_method()
        od['json_schema'] = self.json_schema
        od['readme'] = self.readme_md
        return od class WriteAPIIP(models.Model):
    created_by = models.ForeignKey(
        get_user_model(), blank=True, null=True, on_delete=models.CASCADE)
    slug = models.SlugField(max_length=100, unique=True)
    http_post = models.BooleanField(default=True, blank=True)
    http_put = models.BooleanField(default=True, blank=True)
    database_name = models.CharField(max_length=100)
    collection_name = models.CharField(max_length=100)
    json_schema = models.TextField(
        max_length=20480,
        default="{}",
        verbose_name="JSON Schema",
        help_text="""Default "{}", means no JSON Schema.""")
    from_ip = models.TextField(max_length=2048, default="127.0.0.1",
                               verbose_name=_("From IPs"),
                               help_text=_("Only accept requests from a IP in "
                                           "this list separated by whitespace "
                                           ". 0.0.0.0 means all."))
    readme_md = models.TextField(max_length=4096, default="", blank=True)
    creation_date = models.DateField(auto_now_add=True)

    class Meta:
        get_latest_by = "creation_date"
        ordering = ('-creation_date',)
        verbose_name_plural = _("Write APIs with IP Address Auth")
        verbose_name = _("Write API with IP Address Auth")

    def allowable_ips(self):
        allowable_ips = self.from_ip.split(" ")
        return allowable_ips

    def __str__(self):
        return "%s" % (self.slug)

    def url(self):
        return reverse('djmongo_api_write_to_collection_with_ip', args=(self.slug,))

    def http_methods(self):
        l = []
        if self.http_post:
            l.append("POST")
        if self.http_put:
            l.append("PUT")
        return l

    def auth_method(self):
        return 'ip'

    def http_get_response(self):
        od = OrderedDict()
        od['http_methods'] = self.http_methods()
        od['auth_method'] = self.auth_method()
        od['json_schema'] = self.json_schema
        od['readme'] = self.readme_md
        return od class WriteAPIOAuth2(models.Model):

    created_by = models.ForeignKey(
        get_user_model(), blank=True, null=True, on_delete=models.CASCADE)
    scopes = models.CharField(max_length=1024, default="*", blank=True,
                              help_text="Space delimited list of scopes required. * means no scope is required.")
    http_post = models.BooleanField(default=True, blank=True)
    http_put = models.BooleanField(default=True, blank=True)
    slug = models.SlugField(max_length=100, unique=True)
    database_name = models.CharField(max_length=100)
    collection_name = models.CharField(max_length=100)
    json_schema = models.TextField(
        max_length=20480,
        default="{}",
        verbose_name="JSON Schema",
        help_text="""Default "{}", means no JSON Schema.""")
    readme_md = models.TextField(max_length=4096, default="", blank=True)
    creation_date = models.DateField(auto_now_add=True)

    class Meta:
        get_latest_by = "creation_date"
        ordering = ('-creation_date',)
        verbose_name_plural = "Write APIs with OAuth2 Auth"
        verbose_name = "Write API with OAuth2 Auth"

    def __str__(self):
        return "%s" % (self.slug)

    def http_methods(self):
        l = []
        if self.http_post:
            l.append("POST")
        if self.http_put:
            l.append("PUT")
        return l

    def auth_method(self):
        return 'oauth2'

    def http_get_response(self):
        od = OrderedDict()
        od['http_methods'] = self.http_methods()
        od['auth_method'] = self.auth_method()
        od['json_schema'] = self.json_schema
        od['readme'] = self.readme_md
        return od class CustomHTTPAuthReadAPI(models.Model):

    group = models.ForeignKey(
        Group, blank=True, null=True, on_delete=models.CASCADE)
    output_format = models.CharField(max_length=6,
                                     choices=OUTPUT_CHOICES,
                                     default="json")
    slug = models.SlugField(max_length=100,
                            help_text="Give your API a unique name")
    query = models.TextField(max_length=2048, default="{}",
                             verbose_name="JSON Query")
    type_mapper = models.TextField(
        max_length=2048,
        default="{}",
        verbose_name=_("Map non-string variables to numbers or Boolean"))
    sort = models.TextField(
        max_length=2048,
        default="",
        blank=True,
        verbose_name="Sort Dict",
        help_text="""e.g. [["somefield", 1], ["someotherfield", -1] ]""")

    return_keys = models.TextField(max_length=2048, default="", blank=True,
                                   help_text=_("Default is blank which "
                                               "returns all keys. Separate "
                                               "keys by white space to limit"
                                               "the keys that are returned."))

    default_limit = models.IntegerField(
        default=getattr(
            settings,
            'MONGO_LIMIT',
            200),
        help_text="Limit results to this number unless specified otherwise.",
    )
    database_name = models.CharField(max_length=100)
    collection_name = models.CharField(max_length=100)
    creation_date = models.DateField(auto_now_add=True)
    readme_md = models.TextField(max_length=4096, default="", blank=True)

    class Meta:
        get_latest_by = "creation_date"
        ordering = ('-creation_date',)

    def __str__(self):
        return "%s" % (self.slug)

    def url(self):
        return reverse('djmongo_run_custom_httpauth_read_api_by_slug', args=(self.slug,))

    def auth_method(self):
        return 'httpauth'

    def http_methods(self):
        return ['GET', ] class CustomPublicReadAPI(models.Model):

    output_format = models.CharField(max_length=6,
                                     choices=OUTPUT_CHOICES,
                                     default="json")
    slug = models.SlugField(max_length=100,
                            help_text="Give your API a unique name")
    query = models.TextField(max_length=2048, default="{}",
                             verbose_name="JSON Query")
    type_mapper = models.TextField(
        max_length=2048,
        default="{}",
        verbose_name=_("Map non-string variables to numbers or Boolean"))
    sort = models.TextField(
        max_length=2048,
        default="",
        blank=True,
        verbose_name="Sort Dict",
        help_text="""e.g. [["somefield", 1], ["someotherfield", -1] ]""")

    return_keys = models.TextField(max_length=2048, default="", blank=True,
                                   help_text=_("Default is blank which "
                                               "returns all keys. Separate "
                                               "keys by white space to limit"
                                               "the keys that are returned."))
    default_limit = models.IntegerField(
        default=getattr(
            settings,
            'MONGO_LIMIT',
            200),
        help_text="Limit results to this number unless specified otherwise.",
    )
    database_name = models.CharField(max_length=100)
    collection_name = models.CharField(max_length=100)
    readme_md = models.TextField(max_length=4096, default="", blank=True)
    creation_date = models.DateField(auto_now_add=True)

    class Meta:
        get_latest_by = "creation_date"
        ordering = ('-creation_date',)

    def __str__(self):
        return "%s/%s/%s" % (self.database_name, self.collection_name, self.slug)

    @property
    def url(self):
        return reverse('djmongo_run_custom_public_read_api_by_slug', args=(self.slug,))

    def http_methods(self):
        return ['GET', ]

    def auth_method(self):
        return 'public'

    def query_type(self):
        return 'macro'

    def edit_url(self):
        return reverse('djmongo_edit_custom_public_read_api',
                       args=(self.database_name, self.collection_name, self.slug))

    def delete_url(self):
        return reverse('djmongo_delete_custom_public_read_api',
                       args=(self.database_name, self.collection_name, self.slug)) class CustomOAuth2ReadAPI(models.Model):
    output_format = models.CharField(max_length=6,
                                     choices=OUTPUT_CHOICES,
                                     default="json")
    slug = models.SlugField(max_length=100,
                            help_text="Give your API a unique name")

    scopes = models.CharField(max_length=1024, default="*", blank=True,
                              help_text="Space delimited list of scopes required. * means no scope is required.")
    query = models.TextField(max_length=2048, default="{}",
                             verbose_name="JSON Query")
    type_mapper = models.TextField(
        max_length=2048,
        default="{}",
        verbose_name=_("Map non-string variables to numbers or Boolean"))
    sort = models.TextField(
        max_length=2048,
        default="",
        blank=True,
        verbose_name="Sort Dictionary",
        help_text="""e.g. [["somefield", 1], ["someotherfield", -1] ]""")

    return_keys = models.TextField(max_length=2048, default="", blank=True,
                                   help_text=_("Default is blank which "
                                               "returns all keys. Separate "
                                               "keys by white space to limit"
                                               "the keys that are returned."))

    default_limit = models.IntegerField(
        default=getattr(
            settings,
            'MONGO_LIMIT',
            200),
        help_text="Limit results to this number unless specified otherwise.",
    )
    database_name = models.CharField(max_length=100)
    collection_name = models.CharField(max_length=100)
    creation_date = models.DateField(auto_now_add=True)
    readme_md = models.TextField(max_length=4096, default="", blank=True)

    class Meta:
        get_latest_by = "creation_date"
        ordering = ('-creation_date',)
        unique_together = (('database_name', 'collection_name', 'slug'), )

    def __str__(self):
        return "%s/%s/%s" % (self.database_name, self.collection_name, self.slug)

    def auth_method(self):
        return 'oauth2'

    def http_method(self):
        return 'GET'

    @property
    def url(self):
        return reverse('run_custom_public_read_api_by_slug', args=(self.slug, ))

    def edit_url(self):
        return reverse('djmongo_edit_simple_oauth2_read_api',
                       args=(self.database_name, self.collection_name, self.slug))

    def delete_url(self):
        return reverse('djmongo_delete_simple_oauth2_read_api',
                       args=(self.database_name, self.collection_name, self.slug)) class CustomIPAuthReadAPI(models.Model):

    output_format = models.CharField(max_length=6,
                                     choices=OUTPUT_CHOICES,
                                     default="json")
    slug = models.SlugField(max_length=100,
                            help_text="Give your API a unique name")
    query = models.TextField(max_length=2048, default="{}",
                             verbose_name="JSON Query")
    type_mapper = models.TextField(
        max_length=2048,
        default="{}",
        verbose_name=_("Map non-string variables to numbers or Boolean"))
    sort = models.TextField(
        max_length=2048,
        default="",
        blank=True,
        verbose_name="Sort Dict",
        help_text="""e.g. [["somefield", 1], ["someotherfield", -1] ]""")

    return_keys = models.TextField(max_length=2048, default="", blank=True,
                                   help_text=_("Default is blank which "
                                               "returns all keys. Separate "
                                               "keys by white space to limit"
                                               "the keys that are returned."))
    default_limit = models.IntegerField(
        default=getattr(
            settings,
            'MONGO_LIMIT',
            200),
        help_text="Limit results to this number unless specified otherwise.",
    )
    from_ip = models.TextField(max_length=2048, default="127.0.0.1",
                               verbose_name=_("From IPs"),
                               help_text=_("Only accept requests from a IP in "
                                           "this list separated by whitespace "
                                           ". 0.0.0.0 means all."))
    database_name = models.CharField(max_length=100)
    collection_name = models.CharField(max_length=100)
    readme_md = models.TextField(max_length=4096, default="", blank=True)
    creation_date = models.DateField(auto_now_add=True)

    class Meta:
        get_latest_by = "creation_date"
        ordering = ('-creation_date',)

    def allowable_ips(self):
        allowable_ips = self.from_ip.split(" ")
        return allowable_ips

    def __str__(self):
        return "%s" % (self.slug)

    def url(self):
        return reverse('djmongo_run_custom_ipauth_read_api_by_slug', args=(self.slug,))

    def http_methods(self):
        return ['GET', ]

    def auth_method(self):
        return 'ipauth' class HTTPAuthReadAPI(models.Model):

    database_name = models.CharField(max_length=256)
    collection_name = models.CharField(max_length=256)
    slug = models.SlugField(max_length=100,
                            help_text="Give your API a unique name")
    search_keys = models.TextField(max_length=4096, default="", blank=True,
                                   help_text="""The default, blank, returns
                                                all keys. Providing a list of
                                                keys, separated by whitespace,
                                                limits the API search to only
                                                these keys.""")
    groups = models.ManyToManyField(
        Group, blank=True, related_name="djmongo_http_auth_read_api")
    readme_md = models.TextField(max_length=4096, default="", blank=True)
    creation_date = models.DateField(auto_now_add=True)

    class Meta:
        # get_latest_by = "creation_date"
        # ordering = ('-creation_date',)
        unique_together = (('database_name', 'collection_name', 'slug'), )

    def __str__(self):
        return "%s/%s" % (self.database_name, self.collection_name)

    def url(self):
        return reverse('djmongo_api_httpauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'json'))

    def json_url(self):
        return reverse('djmongo_api_httpauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'json'))

    def csv_url(self):
        return reverse('djmongo_api_httpauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'csv'))

    def html_url(self):
        return reverse('djmongo_api_httpauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'html'))

    def http_method(self):
        return 'GET'

    def auth_method(self):
        return 'httpauth'

    def query_type(self):
        return 'simple'

    def edit_url(self):
        return reverse('djmongo_edit_simple_httpauth_read_api',
                       args=(self.database_name, self.collection_name, self.slug))

    def delete_url(self):
        return reverse('djmongo_delete_simple_httpauth_read_api',
                       args=(self.database_name, self.collection_name, self.slug)) class PublicReadAPI(models.Model):

    database_name = models.CharField(max_length=256)
    collection_name = models.CharField(max_length=256)
    slug = models.SlugField(max_length=100,
                            help_text="Give your API a unique name")
    search_keys = models.TextField(max_length=4096, default="", blank=True,
                                   help_text="""The default, blank, returns
                                                all keys. Providing a list of
                                                keys, separated by whitespace,
                                                limits the API search to only
                                                these keys.""")
    readme_md = models.TextField(max_length=4096, default="", blank=True)
    creation_date = models.DateField(auto_now_add=True)

    class Meta:
        # get_latest_by = "creation_date"
        # ordering = ('-creation_date',)
        unique_together = (('database_name', 'collection_name', 'slug'), )

    def __str__(self):
        return "%s/%s/%s" % (self.database_name, self.collection_name, self.slug)

    def url(self):
        return reverse('djmongo_api_public_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'json'))

    def json_url(self):
        return reverse('djmongo_api_public_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'json'))

    def td_url(self):
        return reverse('djmongo_api_public_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'txt'))

    def ndjson_url(self):
        return reverse('djmongo_api_public_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'ndjson'))

    def csv_url(self):
        return reverse('djmongo_api_public_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'csv'))

    def html_url(self):
        return reverse('djmongo_api_public_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'html'))

    def edit_url(self):
        return reverse('djmongo_edit_simple_public_read_api',
                       args=(self.database_name, self.collection_name, self.slug))

    def delete_url(self):
        return reverse('djmongo_delete_simple_public_read_api',
                       args=(self.database_name, self.collection_name, self.slug))

    def http_method(self):
        return 'GET'

    def auth_method(self):
        return 'public'

    def query_type(self):
        return 'simple' class OAuth2ReadAPI(models.Model):

    database_name = models.CharField(max_length=256)
    collection_name = models.CharField(max_length=256)
    slug = models.SlugField(max_length=100,
                            help_text="Give your API a unique name")
    scopes = models.CharField(max_length=1024, default="*", blank=True,
                              help_text="Space delimited list of scopes required. * means no scope is required.")
    search_keys = models.TextField(max_length=4096, default="", blank=True,
                                   help_text="""The default, blank, returns
                                                all keys. Providing a list of
                                                keys, separated by whitespace,
                                                limits the API search to only
                                                these keys.""")
    readme_md = models.TextField(max_length=4096, default="", blank=True)
    creation_date = models.DateField(auto_now_add=True)

    class Meta:
        # get_latest_by = "creation_date"
        # ordering = ('-creation_date',)
        unique_together = (('database_name', 'collection_name', 'slug'), )

    def __str__(self):
        return "%s/%s/%s" % (self.database_name, self.collection_name, self.slug)

    def url(self):
        return reverse('djmongo_api_oauth2_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'json'))

    def json_url(self):
        return reverse('djmongo_api_oauth2_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'json'))

    def csv_url(self):
        return reverse('djmongo_api_oauth2_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'csv'))

    def html_url(self):
        return reverse('djmongo_api_oauth2_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'html'))

    def http_method(self):
        return 'GET'

    def auth_method(self):
        return 'oauth2'

    def query_type(self):
        return 'simple'

    def edit_url(self):
        return reverse('djmongo_edit_simple_oauth2_read_api',
                       args=(self.database_name, self.collection_name, self.slug))

    def delete_url(self):
        return reverse('djmongo_delete_simple_oauth2_read_api',
                       args=(self.database_name, self.collection_name, self.slug)) class IPAuthReadAPI(models.Model):

    database_name = models.CharField(max_length=256)
    collection_name = models.CharField(max_length=256)
    slug = models.SlugField(max_length=100,
                            help_text="Give your API a unique name")
    from_ip = models.TextField(max_length=2048, default="127.0.0.1",
                               verbose_name=_("From IPs"),
                               help_text=_("Only accept requests from a IP in "
                                           "this list separated by whitespace "
                                           ". 0.0.0.0 means all."))
    search_keys = models.TextField(max_length=4096, default="", blank=True,
                                   help_text="""The default, blank, returns
                                                all keys. Providing a list of
                                                keys, separated by whitespace,
                                                limits the API search to only
                                                these keys.""")
    readme_md = models.TextField(max_length=4096, default="", blank=True)
    creation_date = models.DateField(auto_now_add=True)

    class Meta:
        # get_latest_by = "creation_date"
        # ordering = ('-creation_date',)
        unique_together = (('database_name', 'collection_name', 'slug'), )

    def allowable_ips(self):
        allowable_ips = self.from_ip.split(" ")
        return allowable_ips

    def __str__(self):
        return "%s/%s/%s" % (self.database_name, self.collection_name, self.slug)

    def url(self):
        return reverse('djmongo_api_ipauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'json'))

    def json_url(self):
        return reverse('djmongo_api_ipauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'json'))

    def td_url(self):
        return reverse('djmongo_api_ipauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'txt'))

    def ndjson_url(self):
        return reverse('djmongo_api_ipauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'ndjson'))

    def csv_url(self):
        return reverse('djmongo_api_ipauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'csv'))

    def html_url(self):
        return reverse('djmongo_api_ipauth_simple_search',
                       args=(self.database_name, self.collection_name, self.slug, 'html'))

    def http_method(self):
        return 'GET'

    def auth_method(self):
        return 'ipauth'

    def query_type(self):
        return 'simple'

    def edit_url(self):
        return reverse('djmongo_edit_simple_ipauth_read_api',
                       args=(self.database_name, self.collection_name, self.slug))

    def delete_url(self):
        return reverse('djmongo_delete_simple_ipauth_read_api',
                       args=(self.database_name, self.collection_name, self.slug))
import json
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib import messages
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from .utils import (show_dbs, mongodb_drop_collection, mongodb_drop_database,
                    mongo_delete_json_util, mongo_create_json_util)
from .forms import (EnsureIndexForm, DeleteForm, DocumentForm,
                    CreateDatabaseForm, ConfirmDropForm, APIWizardForm)
from bson.objectid import ObjectId
from collections import OrderedDict
from ..write.models import WriteAPIHTTPAuth, WriteAPIIP, WriteAPIOAuth2
from ..read.models import (CustomHTTPAuthReadAPI, CustomPublicReadAPI,
                           CustomOAuth2ReadAPI, CustomIPAuthReadAPI,
                           HTTPAuthReadAPI, PublicReadAPI,
                           OAuth2ReadAPI, IPAuthReadAPI)
from django.conf import settings
from django.contrib.auth.models import Group
        form = EnsureIndexForm(request.POST)

        if form.is_valid():
            result = form.save(database_name, collection_name)
            messages.success(request,
                             _("Index for %s created successfully" % result))
            return HttpResponseRedirect(reverse('djmongo_show_dbs'))
        else:
            # The form is invalid
            messages.error(
                request, _("Please correct the errors in the form."))
            return render(request,
                          'djmongo/console/generic/bootstrapform.html',
                          {'form': form, 'name': name})

    else:
        # this is a GET
        context = {'name': name,
                   'form': EnsureIndexForm(
                       initial={"database_name": database_name,
                                "collection_name": collection_name})
                   }
        return render(request, 'djmongo/console/generic/bootstrapform.html',
                      context)


def create_new_database(request):
    """Create a New Mongo Database by adding a single document."""
    name = "Create a New MongoDB Database"

    if request.method == 'POST':
        form = CreateDatabaseForm(request.POST)

        if form.is_valid():
            result = form.save()
            if "error" in result:
                messages.error(
                    request, "The database creation operation failed.")
                messages.error(request, result["error"])
            else:
                messages.success(request, "Database %s created." %
                                 (form.cleaned_data['database_name']))

                if getattr(settings, 'DJMONGO_DB_GROUPS', True):
                    group, created = Group.objects.get_or_create(
                        name=form.cleaned_data['database_name'])
                    request.user.groups.add(group)
                    if created:
                        messages.success(request, "Group %s created." % (
                            form.cleaned_data['database_name']))
                        messages.success(request, "User %s added to group %s." % (request.user,
                                                                                  form.cleaned_data['database_name']))

            return HttpResponseRedirect(reverse('djmongo_show_dbs'))
        else:
            # The form is invalid
            messages.error(
                request, _("Please correct the errors in the form."))
            return render(request,
                          'djmongo/console/generic/bootstrapform.html',
                          {'form': form,
                           'name': name})

    else:
        # this is a GET
        context = {'name': name,
                   'form': CreateDatabaseForm(
                       initial={"initial_document": '{ "foo" : "bar" }'
                                })}
        return render(request, 'djmongo/console/generic/bootstrapform.html',
                      context)


def create_collection(request, database_name):
    """Create a new MongoDB collection by adding a single document."""
    name = "Create a New Collection"

    if request.method == 'POST':
        form = CreateDatabaseForm(request.POST)

        if form.is_valid():
            result = form.save()
            if "error" in result:
                messages.error(
                    request, _("The database creation operation failed."))
                messages.error(request, result["error"])
            else:
                messages.success(request, "Collection created.")
            return HttpResponseRedirect(reverse('djmongo_show_dbs'))
        else:
            # The form is invalid
            messages.error(
                request, _("Please correct the errors in the form."))
            return render(request,
                          'djmongo/console/generic/bootstrapform.html',
                          {'form': form, 'name': name})

    else:
        # this is a GET
        context = {'name': name,
                   'form': CreateDatabaseForm(
                       initial={"initial_document": '{ "foo" : "bar" }',
                                "database_name": database_name})
                   }
        return render(request, 'djmongo/console/generic/bootstrapform.html',
                      context)


def remove_data_from_collection(request, database_name, collection_name):

    name = _("""Delete select information from a MongoDB Collection
             based on a query""")

    if request.method == 'POST':
        form = DeleteForm(request.POST)
        if form.is_valid():
            query = form.cleaned_data['query']
            just_one = form.cleaned_data['just_one']

            # run the delete

            results = mongo_delete_json_util(