diff --git a/.travis.yml b/.travis.yml index 7c7868b..791db49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,25 +1,49 @@ language: python services: mongodb python: + - "3.5" + - "3.4" - "3.3" - "3.2" - "2.7" - "2.6" - - "2.5" - "pypy" env: - - DJANGO="Django>=1.4,<1.5" - - DJANGO="Django>=1.5" + - DJANGO="Django>=1.6,<1.7" + - DJANGO="Django>=1.7,<1.8" + - DJANGO="Django>=1.8,<1.9" + - DJANGO="Django>=1.9,<1.10" + - DJANGO="Django>=1.10,<1.11" matrix: exclude: - - python: "3.3" - env: DJANGO="Django>=1.4,<1.5" - - python: "3.2" - env: DJANGO="Django>=1.4,<1.5" - python: "2.6" - env: DJANGO="Django>=1.5" - - python: "2.5" - env: DJANGO="Django>=1.5" + env: DJANGO="Django>=1.7,<1.8" + - python: "2.6" + env: DJANGO="Django>=1.8,<1.9" + - python: "2.6" + env: DJANGO="Django>=1.9,<1.10" + - python: "2.6" + env: DJANGO="Django>=1.10,<1.11" + + - python: "3.2" + env: DJANGO="Django>=1.9,<1.10" + - python: "3.2" + env: DJANGO="Django>=1.10,<1.11" + + - python: "3.3" + env: DJANGO="Django>=1.7,<1.8" + - python: "3.3" + env: DJANGO="Django>=1.9,<1.10" + - python: "3.3" + env: DJANGO="Django>=1.10,<1.11" + + - python: "3.4" + env: DJANGO="Django>=1.6,<1.7" + + - python: "3.5" + env: DJANGO="Django>=1.6,<1.7" + - python: "3.5" + env: DJANGO="Django>=1.7,<1.8" install: - pip install $DJANGO --use-mirrors script: python setup.py nosetests diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..f250bef --- /dev/null +++ b/AUTHORS @@ -0,0 +1,6 @@ +django-mongo-session is written and maintained by ``hellysmile`` and following contributors: + +Patches and Suggestions +``````````````````````` + +- Andrew Lytvyn (``litwisha``) diff --git a/README.rst b/README.rst index b866c5f..a21ecaf 100644 --- a/README.rst +++ b/README.rst @@ -24,10 +24,10 @@ set ``mongo_sessions.session`` as session engine:: settings -------- -there is two ways to setup mongodb connection at ``settings.py`` +there are two ways to setup mongodb connection at ``settings.py`` -first, if already have mongo connection, like:: +first, if already have mongo connection as ``pymongo.database.Database`` instance:: import pymongo from pymongo import MongoClient @@ -35,6 +35,26 @@ first, if already have mongo connection, like:: MONGO_CLIENT = connection.your_database MONGO_SESSIONS_COLLECTION = 'mongo_sessions' # default option +or as ``pymongo.MongoClient`` instance:: + + import pymongo + from pymongo import MongoClient + connection = MongoClient() + MONGO_CLIENT = connection + MONGO_DB_NAME = 'test' # default option + MONGO_SESSIONS_COLLECTION = 'mongo_sessions' # default option + + + +Also, ``MONGO_CLIENT`` setting can be a dotted path string to ``pymongo.MongoClient`` or ``pymongo.database.Database`` instances:: + + MONGO_CLIENT = 'project.main.client' # MongoClient instance + MONGO_DB_NAME = 'test' # default option + +or:: + + MONGO_CLIENT = 'project.main.db' # pymongo.database.Database instance + second, if you need to connect to mongodb, like:: MONGO_PORT = 27017 diff --git a/mongo_sessions/settings.py b/mongo_sessions/settings.py index 2235790..f3e44ae 100644 --- a/mongo_sessions/settings.py +++ b/mongo_sessions/settings.py @@ -1,9 +1,19 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured +from django.utils import six +from pymongo import MongoClient +from pymongo.database import Database +try: + from django.utils.module_loading import import_string +except ImportError: + # Django 1.5 <= version <= 1.6 + from django.utils.module_loading import import_by_path as import_string MONGO_CLIENT = getattr(settings, 'MONGO_CLIENT', False) +MONGO_DB_NAME = getattr(settings, 'MONGO_DB_NAME', 'test') + MONGO_SESSIONS_COLLECTION = getattr( settings, 'MONGO_SESSIONS_COLLECTION', 'mongo_sessions' ) @@ -14,30 +24,44 @@ settings, 'MONGO_SESSIONS_TTL', settings.SESSION_COOKIE_AGE ) -if not MONGO_CLIENT: +if MONGO_CLIENT: + if isinstance(MONGO_CLIENT, six.string_types): + MONGO_CLIENT = import_string(MONGO_CLIENT) + + if isinstance(MONGO_CLIENT, MongoClient): + MONGO_DB = MONGO_CLIENT[MONGO_DB_NAME] + + elif isinstance(MONGO_CLIENT, Database): + MONGO_DB = MONGO_CLIENT + + else: + raise ImproperlyConfigured( + ''' + Incorrect MONGO_CLIENT settings. + Must be MongoClient or Database instance + ''' + ) +else: MONGO_PORT = int(getattr(settings, 'MONGO_PORT', 27017)) MONGO_HOST = getattr(settings, 'MONGO_HOST', 'localhost') - MONGO_DB_NAME = getattr(settings, 'MONGO_DB_NAME', 'test') MONGO_DB_USER = getattr(settings, 'MONGO_DB_USER', False) MONGO_DB_PASSWORD = getattr(settings, 'MONGO_DB_PASSWORD', False) - from pymongo import MongoClient - MONGO_CLIENT = MongoClient( host=MONGO_HOST, port=MONGO_PORT, ) - MONGO_CLIENT = MONGO_CLIENT[MONGO_DB_NAME] + MONGO_DB = MONGO_CLIENT[MONGO_DB_NAME] if MONGO_DB_USER and MONGO_DB_PASSWORD: - MONGO_CLIENT.authenticate(MONGO_DB_USER, MONGO_DB_PASSWORD) + MONGO_DB.authenticate(MONGO_DB_USER, MONGO_DB_PASSWORD) try: - MONGO_DB_VERSION = MONGO_CLIENT.connection.server_info()['version'] + MONGO_DB_VERSION = MONGO_DB.connection.server_info()['version'] except TypeError: # for pymongo >= 3 - MONGO_DB_VERSION = MONGO_CLIENT.client.server_info()['version'] + MONGO_DB_VERSION = MONGO_DB.client.server_info()['version'] if not float('.'.join(MONGO_DB_VERSION.split('.')[:-1])) >= 2.2: raise ImproperlyConfigured( @@ -47,7 +71,7 @@ ''' ) -DB_COLLECTION = MONGO_CLIENT[MONGO_SESSIONS_COLLECTION] +DB_COLLECTION = MONGO_DB[MONGO_SESSIONS_COLLECTION] MONGO_SESSIONS_INDEXES = DB_COLLECTION.index_information() @@ -55,7 +79,7 @@ if len(MONGO_SESSIONS_INDEXES) <= 1: DB_COLLECTION.ensure_index( 'session_key', - unique=True + unique=True, ) DB_COLLECTION.ensure_index( @@ -72,7 +96,7 @@ DB_COLLECTION.ensure_index( 'creation_date', - expireAfterSeconds=MONGO_SESSIONS_TTL + expireAfterSeconds=MONGO_SESSIONS_TTL, ) MONGO_SESSIONS_INDEXES = DB_COLLECTION.index_information() diff --git a/setup.py b/setup.py index 373a446..1d45deb 100644 --- a/setup.py +++ b/setup.py @@ -49,8 +49,8 @@ def long_description(): url='https://github.com/hellysmile/django-mongo-sessions', zip_safe=False, install_requires=[ - 'django >= 1.4', - 'pymongo >= 2.4.2' + 'django >= 1.6', + 'pymongo >= 2.4.2', ], license='http://www.apache.org/licenses/LICENSE-2.0', classifiers=filter(None, classifiers.split('\n')), diff --git a/tests/__init__.py b/tests/__init__.py index eea09e6..7f8c64d 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -3,5 +3,5 @@ settings.configure( SESSION_ENGINE='mongo_sessions.session', - SESSION_COOKIE_AGE=10 + SESSION_COOKIE_AGE=10, ) diff --git a/tests/tests.py b/tests/tests.py index 50a7325..0deb336 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1,4 +1,14 @@ # tests stolen from https://github.com/martinrusev/django-redis-sessions +import time +from imp import reload + +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured +from django.test.utils import override_settings + +from mongo_sessions import settings as mongo_session_settings +from nose.tools import assert_raises, eq_ + try: # For Django versions < 1.9 from django.utils.importlib import import_module @@ -6,12 +16,35 @@ # For Django versions >= 1.9 from django.utils.module_loading import import_module -from django.conf import settings -import time -from nose.tools import eq_ +session_engine = import_module(settings.SESSION_ENGINE).SessionStore() +incorrect_db = object() -session_engine = import_module(settings.SESSION_ENGINE).SessionStore() + +def test_incorrect_mongo_client_setting(): + def _test_connection(settings, exc): + with override_settings(**settings): + # because older versions has no support as contextmanager + assert_raises(exc, reload, mongo_session_settings) + + # test non-existent mongoDB instance + settings = { + 'MONGO_CLIENT': 'wrong.conn.string', + } + # different exceptions in different django versions + _test_connection(settings, (ImportError, ImproperlyConfigured)) + + # test invalid mongoDB instance + settings = { + 'MONGO_CLIENT': object(), + } + _test_connection(settings, ImproperlyConfigured) + + # test invalid mongoDB instance as str + settings = { + 'MONGO_CLIENT': 'tests.tests.incorrect_db', + } + _test_connection(settings, ImproperlyConfigured) def test_modify_and_keys(): diff --git a/tox.ini b/tox.ini index 7caf3ac..1d7ee1d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,21 @@ [tox] envlist = - py25-dj14, - py26-dj14, - py27-dj14, - py27-dj15, - py32-dj15, - py33-dj15, - pypy19-dj14, - pypy19-dj15 + py26-dj16, + py27-dj16, + py32-dj16, + py33-dj16, + py27-dj17, + py32-dj17, + py33-dj17, + py34-dj17, + py27-dj18, + py32-dj18, + py33-dj18, + py34-dj18, + py35-dj18, + py27-dj19, + py34-dj19, + py35-dj19, [base] deps = @@ -17,50 +25,121 @@ deps = commands = {envpython} setup.py nosetests -[testenv:py25-dj14] -basepython=python2.5 +# django 1.6 on python versions: 2.6, 2.7, 3.2, 3.3 +[testenv:py26-dj16] +basepython=python2.6 deps = - Django>=1.4,<1.5 + Django>=1.6,<1.7 {[base]deps} -[testenv:py26-dj14] -basepython=python2.6 +[testenv:py27-dj16] +basepython=python2.7 +deps = + Django>=1.6,<1.7 + {[base]deps} + +[testenv:py32-dj16] +basepython=python3.2 +deps = + Django>=1.6,<1.7 + {[base]deps} + +[testenv:py33-dj16] +basepython=python3.3 deps = - Django>=1.4,<1.5 + Django>=1.6,<1.7 {[base]deps} -[testenv:py27-dj14] +# django 1.7 on python versions: 2.7, 3.2, 3.4 +[testenv:py27-dj17] basepython=python2.7 deps = - Django>=1.4,<1.5 + Django>=1.7,<1.8 + {[base]deps} + +[testenv:py32-dj17] +basepython=python3.2 +deps = + Django>=1.7,<1.8 + {[base]deps} + +[testenv:py33-dj17] +basepython=python3.3 +deps = + Django>=1.7,<1.8 + {[base]deps} + +[testenv:py34-dj17] +basepython=python3.4 +deps = + Django>=1.7,<1.8 {[base]deps} -[testenv:py27-dj15] +# django 1.8 on python versions: 2.7, 3.2, 3.3, 3.4, 3.5 +[testenv:py27-dj18] basepython=python2.7 deps = - Django>=1.5 + Django>=1.8,<1.9 {[base]deps} -[testenv:py32-dj15] +[testenv:py32-dj18] basepython=python3.2 deps = - Django>=1.5 + Django>=1.8,<1.9 {[base]deps} -[testenv:py33-dj15] +[testenv:py33-dj18] basepython=python3.3 deps = - Django>=1.5 + Django>=1.8,<1.9 + {[base]deps} + +[testenv:py34-dj18] +basepython=python3.4 +deps = + Django>=1.8,<1.9 + {[base]deps} + +[testenv:py35-dj18] +basepython=python3.5 +deps = + Django>=1.8,<1.9 + {[base]deps} + +# django 1.9 on python versions: 2.7, 3.4, 3.5 +[testenv:py27-dj19] +basepython=python2.7 +deps = + Django>=1.9,<1.10 + {[base]deps} + +[testenv:py34-dj19] +basepython=python3.4 +deps = + Django>=1.9,<1.10 + {[base]deps} + +[testenv:py35-dj19] +basepython=python3.5 +deps = + Django>=1.9,<1.10 + {[base]deps} + +# django 1.10 on python versions: 2.7, 3.4, 3.5 +[testenv:py27-dj110] +basepython=python2.7 +deps = + Django>=1.10,<1.11 {[base]deps} -[testenv:pypy19-dj14] -basepython=pypy +[testenv:py34-dj110] +basepython=python3.4 deps = - Django>=1.4,<1.5 + Django>=1.10,<1.11 {[base]deps} -[testenv:pypy19-dj15] -basepython=pypy +[testenv:py35-dj110] +basepython=python3.5 deps = - Django>=1.5 + Django>=1.10,<1.11 {[base]deps}