Skip to content
This repository was archived by the owner on Jul 14, 2020. It is now read-only.

fix a bug #191

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ build
dist
venv
.tmp
.idea/*
18 changes: 9 additions & 9 deletions mongokit/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@

class User(Document):
structure = {
"_id": unicode,
"_id": str,
"user": {
"login": unicode,
"password": unicode, # TODO validator
"email": unicode,
"login": str,
"password": str, # TODO validator
"email": str,
}
}
required_fields = ['user.password', 'user.email'] # what if openid ? password is None
Expand All @@ -56,11 +56,11 @@ def del_login(self):

def set_password(self, password):
""" Hash password on the fly """
if isinstance(password, unicode):
if isinstance(password, str):
password = password.encode('utf-8')
password_salt = hashlib.sha1(os.urandom(60)).hexdigest()
crypt = hashlib.sha1(password + password_salt).hexdigest()
self['user']['password'] = unicode(password_salt + crypt, 'utf-8')
crypt = hashlib.sha1(password + password_salt.encode()).hexdigest()
self['user']['password'] = password_salt + crypt

def get_password(self):
""" Return the password hashed """
Expand All @@ -73,10 +73,10 @@ def del_password(self):

def verify_password(self, password):
""" Check the password against existing credentials """
if isinstance(password, unicode):
if isinstance(password, str):
password = password.encode('utf-8')
password_salt = self['user']['password'][:40]
crypt_pass = hashlib.sha1(password + password_salt).hexdigest()
crypt_pass = hashlib.sha1(password + password_salt.encode()).hexdigest()
if crypt_pass == self['user']['password'][40:]:
return True
else:
Expand Down
31 changes: 16 additions & 15 deletions mongokit/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ def __init__(self, *args, **kwargs):
self._documents = {}
self._collections = {}
super(Collection, self).__init__(*args, **kwargs)
self._registered_documents = self.database.connection._registered_documents
# error: Infinite loop
self._registered_documents = self.database.client._registered_documents

def __getattr__(self, key):
if key in self._registered_documents:
Expand Down Expand Up @@ -75,17 +76,17 @@ def __call__(self, *args, **kwargs):
"register it to the connection." % (name, name))

def find(self, *args, **kwargs):
if not 'slave_okay' in kwargs and hasattr(self, 'slave_okay'):
kwargs['slave_okay'] = self.slave_okay
if not 'read_preference' in kwargs and hasattr(self, 'read_preference'):
kwargs['read_preference'] = self.read_preference
if not 'tag_sets' in kwargs and hasattr(self, 'tag_sets'):
kwargs['tag_sets'] = self.tag_sets
if not 'secondary_acceptable_latency_ms' in kwargs and\
hasattr(self, 'secondary_acceptable_latency_ms'):
kwargs['secondary_acceptable_latency_ms'] = (
self.secondary_acceptable_latency_ms
)
# if not 'slave_okay' in kwargs and hasattr(self, 'slave_okay'):
# kwargs['slave_okay'] = self.slave_okay
# if not 'read_preference' in kwargs and hasattr(self, 'read_preference'):
# kwargs['read_preference'] = self.read_preference
# if not 'tag_sets' in kwargs and hasattr(self, 'tag_sets'):
# kwargs['tag_sets'] = self.tag_sets
# if not 'secondary_acceptable_latency_ms' in kwargs and\
# hasattr(self, 'secondary_acceptable_latency_ms'):
# kwargs['secondary_acceptable_latency_ms'] = (
# self.secondary_acceptable_latency_ms
# )
return Cursor(self, *args, **kwargs)
find.__doc__ = PymongoCollection.find.__doc__ + """
added by mongokit::
Expand All @@ -95,11 +96,11 @@ def find(self, *args, **kwargs):

def find_and_modify(self, *args, **kwargs):
obj_class = kwargs.pop('wrap', None)
doc = super(Collection, self).find_and_modify(*args, **kwargs)
doc = super(Collection, self).find_one_and_update(*args, **kwargs)
if doc and obj_class:
return self.collection[obj_class.__name__](doc)
return doc
find_and_modify.__doc__ = PymongoCollection.find_and_modify.__doc__ + """
find_and_modify.__doc__ = PymongoCollection.find_one_and_update.__doc__ + """
added by mongokit::
- `wrap` (optional): a class object used to wrap
documents in the query result
Expand All @@ -124,7 +125,7 @@ def find_random(self):
return one random document from the collection
"""
import random
max = self.count()
max = self.count_documents()
if max:
num = random.randint(0, max-1)
return self.find().skip(num).next()
Expand Down
7 changes: 5 additions & 2 deletions mongokit/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ def register(self, obj_list):
# cleanup
for _, db in self._databases.items():
for __, col in db._collections.items():
for docname, ___ in col._documents.items():
for docname, ___ in list(col._documents.items()):
del col._documents[docname]
for obj_name in [obj.__name__ for obj in obj_list]:
for obj_name in list([obj.__name__ for obj in obj_list]):
if obj_name in col._registered_documents:
del col._registered_documents[obj_name]
# register
Expand Down Expand Up @@ -100,6 +100,9 @@ def __getattr__(self, key):
self._databases[key] = Database(self, key)
return self._databases[key]

def __getitem__(self, key):
return Database(self, key)


class Connection(MongoKitConnection, PymongoConnection):
def __init__(self, *args, **kwargs):
Expand Down
15 changes: 12 additions & 3 deletions mongokit/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,23 @@ def __init__(self, *args, **kwargs):
super(Database, self).__init__(*args, **kwargs)

def __getattr__(self, key):
if key in self.connection._registered_documents:
document = self.connection._registered_documents[key]
return getattr(self[document.__collection__], key)
if key in self.client._registered_documents:
document = self.client._registered_documents[key]
return document
else:
if not key in self._collections:
self._collections[key] = Collection(self, key)
return self._collections[key]

def __getitem__(self, key):
if key in self.client._registered_documents:
document = self.client._registered_documents[key]
return document
else:
if not key in self._collections:
self._collections[key] = Collection(self, key)
return self._collections[key]

def dereference(self, dbref, model=None):
if model is None:
return super(Database, self).dereference(dbref)
Expand Down
37 changes: 19 additions & 18 deletions mongokit/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ def _validate_descriptors(mcs, attrs):
if 'fields' not in index:
raise BadIndexError(
"'fields' key must be specify in indexes")
for key, value in index.iteritems():
for key, value in index.items():
if key == "fields":
if isinstance(value, basestring):
if isinstance(value, str):
if value not in attrs['_namespaces'] and value not in STRUCTURE_KEYWORDS:
raise ValueError(
"Error in indexes: can't find %s in structure" % value)
Expand All @@ -93,11 +93,11 @@ def _validate_descriptors(mcs, attrs):
raise BadIndexError(
"Error in indexes: a tuple must contain "
"only two value : the field name and the direction")
if not (isinstance(value[1], int) or isinstance(value[1], basestring)):
if not (isinstance(value[1], int) or isinstance(value[1], str)):
raise BadIndexError(
"Error in %s, the direction must be int or basestring "
"(got %s instead)" % (value[0], type(value[1])))
if not isinstance(value[0], basestring):
if not isinstance(value[0], str):
raise BadIndexError(
"Error in %s, the field name must be string "
"(got %s instead)" % (value[0], type(value[0])))
Expand Down Expand Up @@ -135,9 +135,7 @@ def _validate_descriptors(mcs, attrs):
assert isinstance(value, int)


class Document(SchemaDocument):

__metaclass__ = DocumentProperties
class Document(SchemaDocument, metaclass=DocumentProperties):

type_field = '_type'

Expand Down Expand Up @@ -166,12 +164,12 @@ def __init__(self, doc=None, gen_skel=True, collection=None, lang='en', fallback
super(Document, self).__init__(doc=doc, gen_skel=gen_skel, _gen_auth_types=False,
lang=lang, fallback_lang=fallback_lang)
if self.type_field in self:
self[self.type_field] = unicode(self.__class__.__name__)
self[self.type_field] = str(self.__class__.__name__)
# collection
self.collection = collection
if collection:
self.db = collection.database
self.connection = self.db.connection
self.connection = self.db.client
# indexing all embed doc if any (autorefs feature)
self._dbrefs = {}
if self.use_autorefs and collection:
Expand Down Expand Up @@ -236,11 +234,11 @@ def validate(self, auto_migrate=False):
error = None
try:
super(Document, self).validate()
except StructureError, e:
except StructureError as e:
error = e
except KeyError, e:
except KeyError as e:
error = e
except SchemaTypeError, e:
except SchemaTypeError as e:
error = e
if error:
if not self.migration_handler:
Expand Down Expand Up @@ -297,7 +295,7 @@ def find_one(self, *args, **kwargs):

See pymongo's documentation for more details on arguments.
"""
return self.collection.find_one(wrap=self._obj_class, *args, **kwargs)
return self(self.collection.find_one(wrap=self._obj_class, *args, **kwargs))

def one(self, *args, **kwargs):
"""
Expand Down Expand Up @@ -423,9 +421,12 @@ def save(self, uuid=False, validate=None, safe=True, *args, **kwargs):
self._make_reference(self, self.structure)
if '_id' not in self:
if uuid:
self['_id'] = unicode("%s-%s" % (self.__class__.__name__, uuid4()))
self['_id'] = str("%s-%s" % (self.__class__.__name__, uuid4()))
self._process_custom_type('bson', self, self.structure)
self.collection.save(self, safe=safe, *args, **kwargs)
if '_id' in self and self.collection.find_one({"_id": self["_id"]}):
self.collection.replace_one(self, {"_id": self["_id"]}, *args, **kwargs)
else:
self.collection.insert_one(self, *args, **kwargs)
self._process_custom_type('python', self, self.structure)

def delete(self):
Expand Down Expand Up @@ -453,12 +454,12 @@ def generate_index(cls, collection):

if isinstance(given_fields, tuple):
fields = [given_fields]
elif isinstance(given_fields, basestring):
elif isinstance(given_fields, str):
fields = [(given_fields, 1)]
else:
fields = []
for field in given_fields:
if isinstance(field, basestring):
if isinstance(field, str):
field = (field, 1)
fields.append(field)
log.debug('Creating index for {}'.format(str(given_fields)))
Expand Down Expand Up @@ -536,7 +537,7 @@ def _convert_to_python(doc, struct):
raise ImportError("can't import anyjson. Please install it before continuing.")
obj = self.to_json_type()
_convert_to_python(obj, self.structure)
return unicode(dumps(obj))
return str(dumps(obj))

def from_json(self, json):
"""
Expand Down
4 changes: 2 additions & 2 deletions mongokit/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def __init__(self, doc=None, warning=False):
self.__dotify_dict(self)

def __dotify_dict(self, doc):
for k, v in doc.iteritems():
for k, v in doc.items():
if isinstance(v, dict):
doc[k] = DotedDict(v)
self.__dotify_dict(v)
Expand Down Expand Up @@ -218,7 +218,7 @@ def __init__(self, passed_dict, remove_under_type=False, reference=None):
self.update(final_dict)

def _make_dotation(self, d, final_dict, key=""):
for k, v in d.iteritems():
for k, v in d.items():
if isinstance(k, type):
k = "$%s" % k.__name__
if isinstance(v, dict) and v != {}:
Expand Down
3 changes: 2 additions & 1 deletion mongokit/master_slave_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
(same license as Mongokit)
"""

from pymongo.master_slave_connection import MasterSlaveConnection as PymongoMasterSlaveConnection
# from pymongo.master_slave_connection import MasterSlaveConnection as PymongoMasterSlaveConnection
from pymongo.mongo_replica_set_client import MongoReplicaSetClient as PymongoMasterSlaveConnection
try:
from pymongo import MongoClient as PymongoConnection
except ImportError:
Expand Down
4 changes: 2 additions & 2 deletions mongokit/migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def clean(self):

def validate_update(self, update_query):
structure = DotCollapsedDict(self.doc_class.structure)
for op, fields in update_query.iteritems():
for op, fields in update_query.items():
for field in fields:
if op != '$unset' and op != '$rename':
if field not in structure:
Expand Down Expand Up @@ -85,7 +85,7 @@ def migrate_all(self, collection, safe=True):
collection.update(self.target, self.update, multi=True, safe=safe)
status = collection.database.last_status()
if not status.get('updatedExisting', 1):
print "%s : %s >>> deprecated" % (self.__class__.__name__, method_name)
print("%s : %s >>> deprecated" % (self.__class__.__name__, method_name))

def get_deprecated(self, collection):
method_names = sorted([i for i in dir(self) if i.startswith('migration') or i.startswith('allmigration')])
Expand Down
2 changes: 1 addition & 1 deletion mongokit/paginator.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def has_previous(self):

@property
def page_range(self):
return [p for p in xrange(1, self.num_pages+1)]
return [p for p in range(1, self.num_pages+1)]

@property
def num_pages(self):
Expand Down
Loading