{ "info": { "author": "Rohith Asrk", "author_email": "rohith.asrk@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.4", "Topic :: Internet :: WWW/HTTP", "Topic :: System :: Networking" ], "description": "openwisp-utils\n==============\n\n.. image:: https://travis-ci.org/openwisp/openwisp-utils.svg?branch=master\n :target: https://travis-ci.org/openwisp/openwisp-utils\n\n.. image:: https://coveralls.io/repos/github/openwisp/openwisp-utils/badge.svg\n :target: https://coveralls.io/github/openwisp/openwisp-utils\n\n.. image:: https://requires.io/github/openwisp/openwisp-utils/requirements.svg?branch=master\n :target: https://requires.io/github/openwisp/openwisp-utils/requirements/?branch=master\n :alt: Requirements Status\n\n.. image:: https://badge.fury.io/py/openwisp-utils.svg\n :target: http://badge.fury.io/py/openwisp-utils\n\n------------\n\nPython and Django utilities shared between different OpenWISP modules.\n\n------------\n\n.. contents:: **Table of Contents**:\n :backlinks: none\n :depth: 3\n\n------------\n\nCurrent features\n----------------\n\n* **Customized admin theme** for OpenWISP modules\n* **Multitenant** admin interface and testing mixins\n* **TimeStamped** models and mixins which add self-updating ``created`` and ``modified`` fields.\n* **DependencyLoader**: template loader which looks in the templates dir of all django-apps\n listed in ``EXTENDED_APPS``\n* **DependencyFinder**: finds static files of django-apps listed in ``EXTENDED_APPS``\n\nProject goals\n-------------\n\n* Minimize code duplication among OpenWISP modules\n\nInstall stable version from pypi\n--------------------------------\n\nInstall from pypi:\n\n.. code-block:: shell\n\n pip install openwisp-utils\n # install optional dependencies for openwisp-users too\n pip install openwisp-utils[users]\n\nInstall development version\n---------------------------\n\nInstall tarball:\n\n.. code-block:: shell\n\n pip install https://github.com/openwisp/openwisp-utils/tarball/master\n\nAlternatively you can install via pip using git:\n\n.. code-block:: shell\n\n pip install -e git+git://github.com/openwisp/openwisp-utils#egg=openwisp-utils\n\nIf you want to contribute, install your cloned fork:\n\n.. code-block:: shell\n\n git clone git@github.com:/openwisp-utils.git\n cd openwisp-utils\n python setup.py develop\n\nUsing the utilities in OpenWISP modules\n---------------------------------------\n\n``INSTALLED_APPS`` in ``settings.py`` should look like the following if you want to use all the utilities\n\n.. code-block:: python\n\n INSTALLED_APPS = [\n 'django.contrib.auth',\n 'django.contrib.contenttypes',\n 'django.contrib.sessions',\n 'django.contrib.messages',\n 'django.contrib.staticfiles',\n # customized admin theme\n 'openwisp_utils.admin_theme',\n # all-auth\n 'django.contrib.sites',\n 'allauth',\n 'allauth.account',\n 'allauth.socialaccount',\n 'django_extensions',\n # openwisp2 modules\n 'openwisp_users',\n # admin\n 'django.contrib.admin',\n ]\n\nUsing the ``admin_theme``\n^^^^^^^^^^^^^^^^^^^^^^^^^\n\nFor using the customized admin theme,\n\n* Make sure you've added ``openwisp_utils.admin_theme`` to ``INSTALLED_APPS`` in ``settings.py``\n\n* Add the following into your ``urls.py`` file which contains ``admin`` urls.\n\n.. code-block:: python\n\n from django.conf.urls import include, url\n\n from openwisp_utils.admin_theme.admin import admin, openwisp_admin\n\n openwisp_admin()\n\n urlpatterns = [\n # other url patterns\n url(r'^admin/', include(admin.site.urls)),\n ]\n\nAdmin mixins\n^^^^^^^^^^^^\n\nThese are mixins which make a ModelAdmin class multitenant: users will see only the objects related to the\norganizations they are associated with.\n\n* **MultitenantAdminMixin**: adding this mixin to a ``ModelAdmin`` class will make it multitenant.\n Set ``multitenant_shared_relations`` to the list of parameters you wish to have only organization\n specific options.\n\n* **MultitenantOrgFilter**: admin filter that shows only organizations the current user is associated with in its available choices.\n\n* **MultitenantRelatedOrgFilter**: similar ``MultitenantOrgFilter`` but shows only objects which have a relation with\n one of the organizations the current user is associated with.\n\n* **TimeReadonlyAdminMixin**: Admin mixin which adds two readonly fields ``created`` and ``modified``. This is an admin mixin for models inheriting ``TimeStampedEditableModel`` which adds the fields ``created`` and ``modified`` to the database.\n\nExample usage:\n\n.. code-block:: python\n\n from django.contrib import admin\n\n from openwisp_utils.admin import (MultitenantAdminMixin,\n MultitenantObjectFilter,\n MultitenantOrgFilter,\n TimeReadonlyAdminMixin)\n\n from .models import Book, Shelf\n\n\n class BaseAdmin(MultitenantAdminMixin, TimeReadonlyAdminMixin, admin.ModelAdmin):\n pass\n\n\n class ShelfAdmin(BaseAdmin):\n list_display = ['name', 'organization']\n list_filter = [('organization', MultitenantOrgFilter)]\n fields = ['name', 'organization', 'created', 'modified']\n\n\n class BookAdmin(BaseAdmin):\n list_display = ['name', 'author', 'organization', 'shelf']\n list_filter = [('organization', MultitenantOrgFilter),\n ('shelf', MultitenantObjectFilter)]\n fields = ['name', 'author', 'organization', 'shelf', 'created', 'modified']\n multitenant_shared_relations = ['shelf']\n\nUsing ``DependencyLoader`` and ``DependencyFinder``\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAdd the list of all packages extended to ``EXTENDED_APPS`` in ``settings.py``.\nIf you've extended ``django_netjsonconfig`` and ``django_x509``:\n\n.. code-block:: python\n\n EXTENDED_APPS = ['django_netjsonconfig', 'django_x509']\n\n``DependencyFinder``\n~~~~~~~~~~~~~~~~~~~~\n\nAdd ``openwisp_utils.staticfiles.DependencyFinder`` to ``STATICFILES_FINDERS`` in ``settings.py``.\n\n.. code-block:: python\n\n STATICFILES_FINDERS = [\n 'django.contrib.staticfiles.finders.FileSystemFinder',\n 'django.contrib.staticfiles.finders.AppDirectoriesFinder',\n 'openwisp_utils.staticfiles.DependencyFinder',\n ]\n\n``DependencyLoader``\n~~~~~~~~~~~~~~~~~~~~\n\nAdd ``openwisp_utils.staticfiles.DependencyFinder`` to ``TEMPLATES_LOADERS`` in ``settings.py`` or as shown below.\n\n.. code-block:: python\n\n TEMPLATES = [\n {\n 'BACKEND': 'django.template.backends.django.DjangoTemplates',\n 'DIRS': [],\n 'OPTIONS': {\n 'loaders': [\n 'django.template.loaders.filesystem.Loader',\n 'django.template.loaders.app_directories.Loader',\n 'openwisp_utils.loaders.DependencyLoader',\n ],\n 'context_processors': [\n 'django.template.context_processors.debug',\n 'django.template.context_processors.request',\n 'django.contrib.auth.context_processors.auth',\n 'django.contrib.messages.context_processors.messages',\n ],\n },\n },\n ]\n\nQuality Assurance checks\n^^^^^^^^^^^^^^^^^^^^^^^^\n\nThis package contains some common QA checks that are used the\nautomated builds of different OpenWISP modules.\n\n``checkmigrations``\n~~~~~~~~~~~~~~~~~~~\n\nEnsures the latest migrations created have a human readable name.\n\nWe want to avoid having many migrations named like ``0003_auto_20150410_3242.py``.\n\nThis way we can reconstruct the evolution of our database schemas faster, with\nless efforts and hence less costs.\n\nUsage example::\n\n checkmigrations --migration-path ./django_freeradius/migrations/\n\n``checkcommit``\n~~~~~~~~~~~~~~~\n\nEnsures the last commit message follows our `commit message style guidelines\n`_.\n\nWe want to keep the commit log readable, consistent and easy to scan in order\nto make it easy to analyze the history of our modules, which is also a very\nimportant activity when performing maintenance.\n\nUsage example::\n\n checkcommit --message \"$(git log --format=%B -n 1)\"\n\nInstalling for development\n--------------------------\n\nInstall sqlite:\n\n.. code-block:: shell\n\n sudo apt-get install sqlite3 libsqlite3-dev\n\nInstall your forked repo:\n\n.. code-block:: shell\n\n git clone git://github.com//openwisp-utils\n cd openwisp-utils/\n python setup.py develop\n\nInstall test requirements:\n\n.. code-block:: shell\n\n pip install -r requirements-test.txt\n\nCreate database:\n\n.. code-block:: shell\n\n cd tests/\n ./manage.py migrate\n ./manage.py createsuperuser\n\nSet ``EMAIL_PORT`` in ``settings.py`` to a port number (eg: ``1025``):\n\n.. code-block:: python\n\n EMAIL_PORT = '1025'\n\nLaunch development server and SMTP deubgging server:\n\n.. code-block:: shell\n\n ./manage.py runserver\n # open another session and run\n python -m smtpd -n -c DebuggingServer localhost:1025\n\nYou can access the admin interface of the test project at http://127.0.0.1:8000/admin/.\n\nRun tests with:\n\n.. code-block:: shell\n\n ./runtests.py\n\nContributing\n------------\n\n1. Announce your intentions in the `OpenWISP Mailing List `_\n and open relavant issues using the `issue tracker `_\n2. Fork this repo and install the project following the\n `instructions `_\n3. Follow `PEP8, Style Guide for Python Code`_\n4. Write code and corresponding tests\n5. Ensure that all tests pass and the test coverage does not decrease\n6. Document your changes\n7. Send a pull request\n\n.. _PEP8, Style Guide for Python Code: http://www.python.org/dev/peps/pep-0008/\n\nChangelog\n---------\n\nSee `CHANGES `_.\n\nLicense\n-------\n\nSee `LICENSE `_.\n\nSupport\n-------\n\nSee `OpenWISP Support Channels `_.\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "https://github.com/openwisp/openwisp-utils/releases", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://openwisp.org", "keywords": "django,netjson,openwrt,networking,openwisp", "license": "BSD-3-Clause", "maintainer": "", "maintainer_email": "", "name": "openwisp-utils", "package_url": "https://pypi.org/project/openwisp-utils/", "platform": "Platform Independent", "project_url": "https://pypi.org/project/openwisp-utils/", "project_urls": { "Download": "https://github.com/openwisp/openwisp-utils/releases", "Homepage": "http://openwisp.org" }, "release_url": "https://pypi.org/project/openwisp-utils/0.2.2/", "requires_dist": [ "django-model-utils (<3.3.0,>=3.1.2)", "flake8 (<=3.6.0); extra == 'qa'", "isort (<=4.3.4); extra == 'qa'", "openwisp-users (<0.2); extra == 'users'" ], "requires_python": "", "summary": "OpenWISP 2 Utilities", "version": "0.2.2" }, "last_serial": 4552273, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "80580c6769c872325bb2771fd922bef3", "sha256": "47c25287e22bdf94bfab641354233dfa1630e880a221ebaab7e2c1b39b7cfaa8" }, "downloads": -1, "filename": "openwisp_utils-0.1.0-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "80580c6769c872325bb2771fd922bef3", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 56652, "upload_time": "2017-06-28T08:05:47", "url": "https://files.pythonhosted.org/packages/4a/52/87dafd79f0542aaedf80f846c8c76695eeac48e93d08ebdd74c0c7243688/openwisp_utils-0.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c328772877e49ce4b09ac22d150d9662", "sha256": "310fd199c1895f878fb3f8dab2e0b84967f21a6eaac81efdf536bd61ca5ed692" }, "downloads": -1, "filename": "openwisp-utils-0.1.0.tar.gz", "has_sig": true, "md5_digest": "c328772877e49ce4b09ac22d150d9662", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 54024, "upload_time": "2017-06-28T08:05:50", "url": "https://files.pythonhosted.org/packages/20/63/076237db286ca63baa4dc6a00d31ec7de2114a0a3df2ca4461e5147bc05f/openwisp-utils-0.1.0.tar.gz" } ], "0.1.0a0": [ { "comment_text": "", "digests": { "md5": "b35669f48470451398431448fe3d9a38", "sha256": "9838390169a8d26f89a17a8d1f899f20ea3999dc8bf6e89d4a30cab4b35e7873" }, "downloads": -1, "filename": "openwisp_utils-0.1.0a0-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "b35669f48470451398431448fe3d9a38", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 56686, "upload_time": "2017-06-27T19:14:48", "url": "https://files.pythonhosted.org/packages/03/f0/422ddf5b0ae09c6fd7e07cf05079234b42bf040544112be4a2c876f5446a/openwisp_utils-0.1.0a0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2b17dba55ee5328890dae66dc076394e", "sha256": "41f3f6f2f2a45546b809f418211681c8845f342eed800630bf3aec04c17760cc" }, "downloads": -1, "filename": "openwisp-utils-0.1.0a0.tar.gz", "has_sig": true, "md5_digest": "2b17dba55ee5328890dae66dc076394e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 52090, "upload_time": "2017-06-27T19:14:25", "url": "https://files.pythonhosted.org/packages/02/fe/5b571c19d5c7b1251b696c59e23f79076fdc4027cb617adb706ee8002a3c/openwisp-utils-0.1.0a0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "b0d7701380f2b8fa54624f79ae8103e3", "sha256": "38b19f522533853c6b1672ef3f57364ea744af01131ae50e234ff44877955e0d" }, "downloads": -1, "filename": "openwisp_utils-0.1.1-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "b0d7701380f2b8fa54624f79ae8103e3", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 57115, "upload_time": "2017-06-28T16:02:08", "url": "https://files.pythonhosted.org/packages/dd/10/95e5fc140fceb3aed5c74ea0d7ade85e08b84372a53c0301ea1ef6219276/openwisp_utils-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ef3eecd637b99403d9eb078379a519de", "sha256": "b42afd21332ec77d2229af8cb7f304c82f233d3e02de8319f173c1d75279c1d2" }, "downloads": -1, "filename": "openwisp-utils-0.1.1.tar.gz", "has_sig": true, "md5_digest": "ef3eecd637b99403d9eb078379a519de", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 52432, "upload_time": "2017-06-28T16:02:05", "url": "https://files.pythonhosted.org/packages/46/34/dbf73483aed02e1f2b0f9e2f08d77e7d8b9bf794b9f1a7e35856c7a2f27d/openwisp-utils-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "05551a0a2d2083015b1aec000295e7ec", "sha256": "ff29db23d523cf068a955ba3e61d9254ad735a89541a17d97bfbcdb157ef375e" }, "downloads": -1, "filename": "openwisp_utils-0.1.2-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "05551a0a2d2083015b1aec000295e7ec", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 58012, "upload_time": "2017-07-10T13:33:27", "url": "https://files.pythonhosted.org/packages/86/34/a2fbb1d84707a5b2024276eeb38a34bfa37e744e76ac1b71eed407762352/openwisp_utils-0.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f9b74dce0c8a2552d48f0edb6282bd8e", "sha256": "18b158196abafe11321eb965ee476885d5ac7eecff5aa1b2e4e628defb387f21" }, "downloads": -1, "filename": "openwisp-utils-0.1.2.tar.gz", "has_sig": true, "md5_digest": "f9b74dce0c8a2552d48f0edb6282bd8e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 53178, "upload_time": "2017-07-10T13:33:25", "url": "https://files.pythonhosted.org/packages/30/4e/1b1af60bd2b56dfb732e9e8b6d78012080d4f2f636e7386ef7326938045d/openwisp-utils-0.1.2.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "7ea7914f9146efe2d512bc0430a99b3c", "sha256": "bc57554d3f55a86e0dcb8cdbf52f5fdbd3d76075c9682962eb0c5fcc700445fb" }, "downloads": -1, "filename": "openwisp_utils-0.2-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "7ea7914f9146efe2d512bc0430a99b3c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 58069, "upload_time": "2018-02-06T12:01:36", "url": "https://files.pythonhosted.org/packages/8f/95/5c27e082133411efa7ed3a8e2d5faed5921568ac029aa66700b249fef793/openwisp_utils-0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a9741cea98e4a79684e60e44ca281b82", "sha256": "e5861f9f4d352b309900b9d32d41d68710cf41dbda8a4b5b696041fc9e072600" }, "downloads": -1, "filename": "openwisp-utils-0.2.tar.gz", "has_sig": true, "md5_digest": "a9741cea98e4a79684e60e44ca281b82", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55450, "upload_time": "2018-02-06T12:01:43", "url": "https://files.pythonhosted.org/packages/74/ef/662aab2575a6841f2a6f36c1676ed5a54f65ef7ae7a1a61b8e6d6ef505be/openwisp-utils-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "b4e4f06ea6a77908dc4a3573037ce419", "sha256": "6572ee1dd70ae89cec11e370575c88181081726d18bcbb5bbb456a1a874033b6" }, "downloads": -1, "filename": "openwisp_utils-0.2.1-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "b4e4f06ea6a77908dc4a3573037ce419", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 59258, "upload_time": "2018-11-04T12:02:45", "url": "https://files.pythonhosted.org/packages/d0/96/85a2ed498779ddc052ed7c16430d8bca985ea4706899c8fcc46d218203ba/openwisp_utils-0.2.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "17cc5e7cf2758113dbfe3d568ddf81a2", "sha256": "7cee59b45f4d732814a0074b6ac9204f6ecfbc9b0d2f87c9cf04d5d7fe4238cd" }, "downloads": -1, "filename": "openwisp-utils-0.2.1.tar.gz", "has_sig": true, "md5_digest": "17cc5e7cf2758113dbfe3d568ddf81a2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55955, "upload_time": "2018-11-04T12:02:47", "url": "https://files.pythonhosted.org/packages/fe/59/eaab787ea3b6d29c602f7220db3d9a8043d91e3e7cfc5b57566dc9ed6404/openwisp-utils-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "d05847f1b894c863739c16a34ca5229b", "sha256": "ddd950640e99ebb63c917cf03f080d1ed6a9528af0836c8f47879f599cffa674" }, "downloads": -1, "filename": "openwisp_utils-0.2.2-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "d05847f1b894c863739c16a34ca5229b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 61427, "upload_time": "2018-12-02T11:17:34", "url": "https://files.pythonhosted.org/packages/1c/0a/289d889ee0f6c974fb8d4345ec82ca6e68e5e659e5a5405a73cf588cce10/openwisp_utils-0.2.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ecd642bb974801c39c118850ff6ce261", "sha256": "d067540666779e8bbeb2d9a3fee5673f0d98318d262ac293fc42225ef96b7961" }, "downloads": -1, "filename": "openwisp-utils-0.2.2.tar.gz", "has_sig": true, "md5_digest": "ecd642bb974801c39c118850ff6ce261", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 58378, "upload_time": "2018-12-02T11:17:36", "url": "https://files.pythonhosted.org/packages/d5/1c/96f7c04c1647ba29a92281fa55c4b7031751bef75dd71c9db274993c7aa2/openwisp-utils-0.2.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d05847f1b894c863739c16a34ca5229b", "sha256": "ddd950640e99ebb63c917cf03f080d1ed6a9528af0836c8f47879f599cffa674" }, "downloads": -1, "filename": "openwisp_utils-0.2.2-py2.py3-none-any.whl", "has_sig": true, "md5_digest": "d05847f1b894c863739c16a34ca5229b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 61427, "upload_time": "2018-12-02T11:17:34", "url": "https://files.pythonhosted.org/packages/1c/0a/289d889ee0f6c974fb8d4345ec82ca6e68e5e659e5a5405a73cf588cce10/openwisp_utils-0.2.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ecd642bb974801c39c118850ff6ce261", "sha256": "d067540666779e8bbeb2d9a3fee5673f0d98318d262ac293fc42225ef96b7961" }, "downloads": -1, "filename": "openwisp-utils-0.2.2.tar.gz", "has_sig": true, "md5_digest": "ecd642bb974801c39c118850ff6ce261", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 58378, "upload_time": "2018-12-02T11:17:36", "url": "https://files.pythonhosted.org/packages/d5/1c/96f7c04c1647ba29a92281fa55c4b7031751bef75dd71c9db274993c7aa2/openwisp-utils-0.2.2.tar.gz" } ] }