diff --git a/.gitignore b/.gitignore index 83f560f..cab8b8e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ git-push.bat .python-version .coverage /.idea/ +docs/_build/ diff --git a/README.md b/README.md index 87c1e4b..a20f8e4 100644 --- a/README.md +++ b/README.md @@ -8,187 +8,12 @@ ## About -Generic invitations solution with adaptable backend and support for django-allauth. All emails and messages are fully customisable. - -Originally written as an invitations solution for the excellent [django-allauth](https://github.com/pennersr/django-allauth), this app has been refactored to remove the allauth dependency whilst retaining 100% backwards compatibility. +Generic invitations solution with adaptable backend and support for django-allauth. ## Contributing As we are members of a [JazzBand project](https://jazzband.co/projects), `django-invitations` contributors should adhere to the [Contributor Code of Conduct](https://jazzband.co/about/conduct). -## Installation - -1. Install with pip -``` -pip install django-invitations -``` - -2. Add django.contrib.sites" and 'invitations to INSTALLED_APPS - -``` -INSTALLED_APPS = [ - ... - "django.contrib.sites", - "invitations", - ... -] -``` - -2. Make sure you have SITE_ID defined in settings -``` -SITE_ID = 1 -``` - -3. Append to urls.py - -``` -urlpatterns = [ - ... - path("invitations/", include('invitations.urls', namespace='invitations')), - ... -] -``` - -4. Run migrations - -``` -python manage.py migrate -``` - -## Usage - -There are two primary ways to use `django-invitations` described below. - -Generic Invitation flow: - -* Priviledged user invites prospective user by email (via either Django admin, form post, JSON post or programmatically) -* User receives invitation email with confirmation link -* User clicks link and is redirected to a preconfigured url (default is accounts/signup) - -Allauth Invitation flow: - -* As above but.. -* User clicks link, their email is confirmed and they are redirected to signup -* The signup URL has the email prefilled and upon signing up the user is logged into the site - -Further details can be found in the following sections. - -### Allauth Integration - -As above but note that invitations must come after allauth in the INSTALLED_APPS - -``` -# Add to settings.py -ACCOUNT_ADAPTER = 'invitations.models.InvitationsAdapter' -``` - -### Sending Invites - -First import the model: - -``` -from invitations.utils import get_invitation_model -``` - -Make an instance of the model: - -``` -Invitation = get_invitation_model() -``` - -Then finally pass the recipient to the model and send. - -``` -# inviter argument is optional -invite = Invitation.create('email@example.com', inviter=request.user) -invite.send_invitation(request) -``` - -To send invites via django admin, just add an invite and save. - - -### Bulk Invites - -Bulk invites are supported via JSON. Post a list of comma separated emails to the dedicated URL and Invitations will return a data object containing a list of valid and invalid invitations. - - -### Testing - -`python manage.py test` or `tox` - -### Additional Configuration - -* `INVITATIONS_INVITATION_EXPIRY` (default=`3`) - - Integer. How many days before the invitation expires. - -* `INVITATIONS_INVITATION_ONLY` (default=`False`) - - Boolean. If the site is invite only, or open to all (only relevant when using allauth). - -* `INVITATIONS_CONFIRM_INVITE_ON_GET` (default=`True`) - - Boolean. If confirmations can be accepted via a `GET` request. - -* `INVITATIONS_ACCEPT_INVITE_AFTER_SIGNUP` (default=`False`) - - Boolean. If `True`, invitations will be accepted after users finish signup. - If `False`, invitations will be accepted right after the invitation link is clicked. - Note that this only works with Allauth for now, which means `ACCOUNT_ADAPTER` has to be - `'invitations.models.InvitationsAdapter'`. - -* `INVITATIONS_GONE_ON_ACCEPT_ERROR` (default=`True`) - - Boolean. If `True`, return an HTTP 410 GONE response if the invitation key - is invalid, or the invitation is expired or previously accepted when - accepting an invite. If `False`, display an error message and redirect on - errors: - - * Redirects to `INVITATIONS_SIGNUP_REDIRECT` on an expired key - * Otherwise, redirects to `INVITATIONS_LOGIN_REDIRECT` on other errors. - -* `INVITATIONS_ALLOW_JSON_INVITES` (default=`False`) - - Expose a URL for authenticated posting of invitees - -* `INVITATIONS_SIGNUP_REDIRECT` (default=`'account_signup'`) - - URL name of your signup URL. - -* `INVITATIONS_LOGIN_REDIRECT` (default=`LOGIN_URL` from Django settings) - - URL name of your login URL. - -* `INVITATIONS_ADAPTER` (default=`'invitations.adapters.BaseInvitationsAdapter'`) - - Used for custom integrations. Set this to `ACCOUNT_ADAPTER` if using django-allauth. - -* `INVITATIONS_EMAIL_MAX_LENGTH` (default=`254`) - - If set to `None` (the default), invitation email max length will be set up to 254. Set this to an integer value to set up a custome email max length value. - -* `INVITATIONS_EMAIL_SUBJECT_PREFIX` (default=`None`) - - If set to `None` (the default), invitation email subjects will be prefixed with the name of the current Site in brackets (such as `[example.com]`). Set this to a string to for a custom email subject prefix, or an empty string for no prefix. - -* `INVITATIONS_INVITATION_MODEL` (default=`invitations.Invitation`) - - App registry path of the invitation model used in the current project, for customization purposes. - -* `CONFIRMATION_URL_NAME` (default=`invitations:accept-invite`) - - String. Invitation confirmation URL - -### Signals - -The following signals are emitted: - -* `invite_url_sent` -* `invite_accepted` - - -### Management Commands - -Expired and accepted invites can be cleared as so: +### Documentation -`python manage.py clear_expired_invitations` +Documentation can be found at https://django-invitations.readthedocs.io/ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d5ca222 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= "-W" +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 0000000..396204c --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1,329 @@ +Changelog +========= + +1.9 (2017-02-11) +---------------- + +- Added get_signup_redirect to allow custom implementations by subclasses + +- Fixed invitation form displaying "None" when first displayed + +- Fixed deprecation warnings + +- Added get_signup_redirect to allow custom implementations by subclasses + +- Fixed flake8 errors + +- Import reverse from django.urls if available, otherwise fall back to old import + +- Set ForeignKey field to explicitly cascade on deletion + +- flake8 styling formatting + +- Add email max length setting + + +1.8 (2016-10-19) +---------------- + +Not available + + +1.7 (2016-02-10) +------------------------ + +- 1.7. [bee-keeper] + +- Merge pull request #34 from percipient/dont-404. [bee-keeper] + + Display a message on expired/erroneous/accepted keys. + +- Fix flake8 issues. [Patrick Cloke] + +- Fix a formatting mistake in the README. [Patrick Cloke] + +- Display a message on expired/erroneous/accepted keys. Related to #25. + [Patrick Cloke] + +- Merge pull request #33 from percipient/readme-settings. [bee-keeper] + + Fix-up the settings in the README + +- Update the INVITATIONS_ADAPTER setting. [Patrick Cloke] + +- Update the readme with all the settings. [Patrick Cloke] + +- Removed uneeded check on send invite. [bee_keeper] + +- Test new url spec. [bee_keeper] + +- Merge pull request #32 from mjnaderi/patch-1. [bee-keeper] + +- Remove RemovedInDjango110Warning warnings in Django 1.9. [Mohammad + Javad Naderi] + +1.6 (2016-01-10) +---------------- + +- V1.6. [bee_keeper] + +- Dont override inviter from create step. [bee_keeper] + +- Merge pull request #30 from percipient/allauth-with-custom-adapter. + [bee-keeper] + + Allow using custom allauth backends. + +- Make flake8 happy. [Patrick Cloke] + +- Don't return None from get_invitations_adapter. [Patrick Cloke] + +- Merge pull request #31 from percipient/set-inviter. [bee-keeper] + + Set the inviter in the SendInvite view. + +- Set the inviter in the SendInvite view. [Patrick Cloke] + +- Update README.md. [bee-keeper] + +1.5 (2015-12-07) +---------------- + +- Update README.md. [bee-keeper] + +- Merge pull request #24 from bee-keeper/devel. [bee-keeper] + + Refactor as generic invite app + +- Removed the dependancy on django-allauth, this package is now a + generic invite app. [bee_keeper] + +1.4 (2015-11-27) +---------------- + +- 1.4. [bee_keeper] + +- Merge pull request #23 from bee-keeper/devel. [bee-keeper] + + Coverage and exposing inviter in admin + +- Coverage and exposing inviter in admin. [bee_keeper] + +1.3 (2015-11-26) +---------------- + +- Merge pull request #22 from bee-keeper/devel. [bee-keeper] + + Added inviter to invitation + +- Added inviter to invitation. [bee_keeper] + +- Merge pull request #21 from bee-keeper/devel. [bee-keeper] + + Support for django1.9 + +- Testing for django1.9 and python 3.5. [bee_keeper] + +- Merge pull request #20 from bee-keeper/devel. [bee-keeper] + + Added json endpoint for invites + +- Added json endpoint for invites. [bee_keeper] + +- Merge pull request #19 from bee-keeper/devel. [bee-keeper] + + Made accept trailing slash optional + +- Made trailing slash optional and added flake8 to CI. [bee_keeper] + + Bumped to version 1.3 + +- Update models.py. [bee-keeper] + +- Roadmap. [bee_keeper] + +1.2 (2015-08-29) +---------------- + +- Test coverage done, ready for 1.2 release. [bee_keeper] + +- Dropping support for python 3.2. [bee_keeper] + +- Dropping support for python 3.2. [bee_keeper] + +- Signal test coverage, tweaking tox. [bee_keeper] + +- Coverage. [bee-keeper] + +- Tox+travis. [bee-keeper] + +- Tox. [bee-keeper] + +- Tox+travis. [bee-keeper] + +- Testing tox+travis. [bee-keeper] + +- Testing tox+travis. [bee-keeper] + +- Tox file. [bee_keeper] + +- Py3 fix. [bee_keeper] + +- Test for signup redirect. [bee_keeper] + +- Update README.md. [bee-keeper] + +- Py 3.2. [bee_keeper] + +- Py 3.2. [bee-keeper] + +- Print. [bee-keeper] + +- Tests and bug fixes. [bee-keeper] + +1.1 (2015-08-05) +---------------- + +- V 1.1. [bee_keeper] + +- Readme. [bee_keeper] + +- Modified PR (15) + editorconfig. [bee_keeper] + +- Merge branch 'nwaxiomatic-master' [bee_keeper] + +- Admin invitations. [Nic] + + sends invitations from admin on save + +1.0 (2015-07-26) +---------------- + +- Release 1.0. [bee_keeper] + +- Requirements. [bee_keeper] + +- Changing travis supported versions. [bee_keeper] + +- Travis. [bee_keeper] + +- Travis. [bee_keeper] + +- Remove 2.6 from testing. [bee_keeper] + +- Requirements and changelog. [bee_keeper] + +- Test settings. [bee_keeper] + +- Requirements.txt. [bee_keeper] + +- Travis. [bee_keeper] + +- Removing uneeded imports. [bee_keeper] + +- Removed ALLOWED_GROUPS setting. [bee_keeper] + +- Merge pull request #12 from tbarbugli/patch-1. [bee-keeper] + + fix invite form + +- Fix invite form. [Tommaso Barbugli] + +- Update views.py. [bee-keeper] + +- Teavis. [bee_keeper] + +- Travis. [bee_keeper] + +- Travis. [bee_keeper] + +- Travis. [bee_keeper] + +- Travis. [bee_keeper] + +- Travis. [bee_keeper] + +- App settings. [bee_keeper] + +- Merge pull request #6 from simonv3/master. [bee-keeper] + + # Redo pull request of adding inviter to signal. + +- Add reference to inviter in signal. [Simon] + +- .travis.yml. [bee_keeper] + +- .travis.yml. [bee_keeper] + +- Readme. [bee_keeper] + +- Fixing py3.2 import issues. [bee_keeper] + +- Invitations/app_settings.py. [bee_keeper] + +- Py3.2 issue. [bee_keeper] + +- Typo with import. [bee_keeper] + +- Module object has no attribute issue with 3.2. [bee_keeper] + +- Fixes import issue. [bee_keeper] + +- Py 3.2 unicode issue. [bee_keeper] + +- Travis. [bee_keeper] + +- Travis config. [bee_keeper] + +- Py3.2 format. [bee_keeper] + +- .travis.yml. [bee_keeper] + +- .travis.yml. [bee_keeper] + +- .travis.yml. [bee_keeper] + +- .travs.yml. [bee_keeper] + +- .travis.yml. [bee_keeper] + +- .travis.yml. [bee_keeper] + +- Test settings and more test coverage. [bee_keeper] + +- Tests and refactoring. [bee_keeper] + +- New style migrations. [bee_keeper] + +- 1.7 style migrations. [bee_keeper] + +0.12 (2014-11-30) +----------------- + +- Release. [bee_keeper] + +0.11 (2014-11-30) +----------------- + +- Template paths. [bee_keeper] + +- Setup.py. [bee_keeper] + +- Packaging. [bee_keeper] + +- Versions. [bee_keeper] + +0.1 (2014-11-30) +---------------- + +- Packaging. [bee_keeper] + +- Include templates in package. [bee_keeper] + +- Packaging. [bee_keeper] + +- Template path. [bee_keeper] + +- Template path. [bee_keeper] + +- Name changes. [bee_keeper] diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..bb169dc --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,85 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html +from __future__ import annotations + +import sys +from pathlib import Path + +import tomlkit + +# -- Path setup -------------------------------------------------------------- + +here = Path(__file__).parent.resolve() +sys.path.insert(0, str(here / "..")) + +# -- Project information ----------------------------------------------------- + + +def _get_project_meta(): + with open("../pyproject.toml") as pyproject: + file_contents = pyproject.read() + + return tomlkit.parse(file_contents)["tool"]["poetry"] + + +pkg_meta = _get_project_meta() +project = str(pkg_meta["name"]) +copyright = "-" +author = "-" + +# The short X.Y version +version = str(pkg_meta["version"]) +# The full version, including alpha/beta/rc tags +release = version + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", +] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [ + "_build", + "venv", +] + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "furo" + +# -- Options for LaTeX output ------------------------------------------ + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass +# [howto/manual]). +latex_documents = [ + ( + "index", + "django-invitations.tex", + "django-invitations Documentation", + "Jazzband", + "manual", + ), +] + +# -- Options for Intersphinx ------------------------------------------- + +intersphinx_mapping = { + "django": ( + "https://docs.djangoproject.com/en/stable/", + "https://docs.djangoproject.com/en/stable/_objects/", + ), +} diff --git a/docs/configuration.rst b/docs/configuration.rst new file mode 100644 index 0000000..221c639 --- /dev/null +++ b/docs/configuration.rst @@ -0,0 +1,182 @@ +Configuration +============= + + +General settings +---------------- + +INVITATION_EXPIRY +***************** + +Setting name: ``INVITATIONS_INVITATION_EXPIRY`` + +Type: Integer + +Default: 3 + +How many days before the invitation expires. + +---- + +CONFIRM_INVITE_ON_GET +********************* + +Setting name: ``INVITATIONS_CONFIRM_INVITE_ON_GET`` + +Type: Boolean + +Default: True + +If confirmations can be accepted via a `GET` request. + +---- + +ACCEPT_INVITE_AFTER_SIGNUP +************************** + +Setting name: ``INVITATIONS_ACCEPT_INVITE_AFTER_SIGNUP`` + +Type: Boolean + +Default: False + +If ``True``, invitations will be accepted after users finish signup. +If ``False``, invitations will be accepted right after the invitation link is clicked. +Note that this only works with Allauth for now, which means `ACCOUNT_ADAPTER` has to be +``invitations.models.InvitationsAdapter``. + +---- + +GONE_ON_ACCEPT_ERROR +******************** + +Setting name: ``INVITATIONS_GONE_ON_ACCEPT_ERROR`` + +Type: Boolean + +Default: True + +If `True`, return an HTTP 410 GONE response if the invitation key +is invalid, or the invitation is expired or previously accepted when +accepting an invite. If `False`, display an error message and redirect on +errors: + +* Redirects to `INVITATIONS_SIGNUP_REDIRECT` on an expired key +* Otherwise, redirects to `INVITATIONS_LOGIN_REDIRECT` on other errors. + +---- + +ALLOW_JSON_INVITES +****************** + +Setting name: ``INVITATIONS_ALLOW_JSON_INVITES`` + +Type: Boolean + +Default: False + +Expose a URL for authenticated posting of invitees + +---- + +SIGNUP_REDIRECT +*************** + +Setting name: ``INVITATIONS_SIGNUP_REDIRECT`` + +Type: String + +Default: "account_signup" + +URL name of your signup URL. + +---- + +LOGIN_REDIRECT +************** + +Setting name: ``INVITATIONS_LOGIN_REDIRECT`` + +Type: String + +Default: ``LOGIN_URL`` from Django settings + +URL name of your login URL. + +---- + +ADAPTER +******* + +Setting name: ``INVITATIONS_ADAPTER`` + +Type: String + +Default: "invitations.adapters.BaseInvitationsAdapter" + +Used for custom integrations. Set this to `ACCOUNT_ADAPTER` if using django-allauth. + +---- + +EMAIL_MAX_LENGTH +**************** + +Setting name: ``INVITATIONS_EMAIL_MAX_LENGTH`` + +Type: Integer + +Default: 254 + +If set to `None` (the default), invitation email max length will be set up to 254. Set this to an integer value to set up a custome email max length value. + +---- + +EMAIL_SUBJECT_PREFIX +******************** + +Setting name: ``INVITATIONS_EMAIL_SUBJECT_PREFIX`` + +Type: String or None + +Default: None + +If set to `None` (the default), invitation email subjects will be prefixed with the name of the current Site in brackets (such as `[example.com]`). Set this to a string to for a custom email subject prefix, or an empty string for no prefix. + +---- + +INVITATION_MODEL +**************** + +Setting name: ``INVITATIONS_INVITATION_MODEL`` + +Type: String + +Default: ``invitations.Invitation`` + +App registry path of the invitation model used in the current project, for customization purposes. + +---- + +CONFIRMATION_URL_NAME +********************* +Setting name: ``INVITATIONS_CONFIRMATION_URL_NAME`` + +Type: String + +Default: "invitations:accept-invite" + +Invitation confirmation URL + +Allauth related settings +------------------------ + +INVITATION_ONLY +*************** + +Setting name: ``INVITATIONS_INVITATION_ONLY`` + +Type: Boolean + +Default: False + +If the site is invite only, or open to all (only relevant when using allauth). diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 0000000..43a735b --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1,35 @@ +Contributing +============ + +JazzBand project +---------------- +As we are members of a [JazzBand project](https://jazzband.co/projects), `django-invitations` contributors should adhere to the [Contributor Code of Conduct](https://jazzband.co/about/conduct). + + +Testing +------- + +It's important that any new code is tested before submission. To quickly test code in your active development environment, you should first install all of the requirements by running: + +.. code-block:: bash + + source .venv/bin/activate + pip install -e '.[testing]' -U + +Then, run the following command to execute tests: + +.. code-block:: bash + + pytest --cov-report term --cov=invitations --ignore=tests/allauth/ --ds=tests.settings tests + +To test the integration with django-allauth, first make sure you have it installed. Then run: + +.. code-block:: bash + + pytest --cov-report term --cov=invitations --ignore=tests/basic/ --ds=tests.settings_allauth tests + +Testing in a single environment is a quick and easy way to identify obvious issues with your code. However, it's important to test changes in other environments too, before they are submitted. In order to help with this, django-invitations is configured to use tox for multi-environment tests. They take longer to complete, but can be triggered with a simple command: + +.. code-block:: bash + + tox diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..a507958 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,24 @@ +django-invitations documentation +================================ + +Generic invitations solution with adaptable backend and support for django-allauth. All emails and messages are fully customisable. + +Originally written as an invitations solution for the excellent `django-allauth `_, this app has been refactored to remove the allauth dependency whilst retaining 100% backwards compatibility. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + installation + usage + configuration + contributing + changelog + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..665d7a3 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,58 @@ +Installation +============ + +Requirements +------------ + +Python 3.7 to 3.10 supported. + +Django 3.2 to 4.0 supported. + +Installation +------------ + +1. Install with **pip**: + + .. code-block:: sh + + python -m pip install django-invitations + +2. Add "django.contrib.sites" and "invitations" to INSTALLED_APPS + + .. code-block:: python + + INSTALLED_APPS = [ + ... + "django.contrib.sites", + "invitations", + ... + ] + +.. note:: **Allauth support** + + For allauth support ``invitations`` must come after ``allauth`` in the INSTALLED_APPS + + +3. Make sure you have SITE_ID defined in settings: + + .. code-block:: python + + ... + SITE_ID = 1 + ... + +3. Add invitations urls to your urlpatterns: + + .. code-block:: python + + urlpatterns = [ + ... + path("invitations/", include('invitations.urls', namespace='invitations')), + ... + ] + +4. Run migrations + + .. code-block:: sh + + python manage.py migrate diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..5c9dd8e --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,4 @@ +django +furo +sphinx +tomlkit diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000..9d2e3a8 --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,78 @@ +Usage +===== + +There are two primary ways to use `django-invitations` described below. + +Generic Invitation flow: + +* Priviledged user invites prospective user by email (via either Django admin, form post, JSON post or programmatically) +* User receives invitation email with confirmation link +* User clicks link and is redirected to a preconfigured url (default is accounts/signup) + +Allauth Invitation flow: + +* As above but.. +* User clicks link, their email is confirmed and they are redirected to signup +* The signup URL has the email prefilled and upon signing up the user is logged into the site + +Further details can be found in the following sections. + +Allauth Integration +------------------- + +As above but note that invitations must come after allauth in the INSTALLED_APPS + +Set the allauth ``ACCOUNT_ADAPTER`` setting + +.. code-block:: python + + ACCOUNT_ADAPTER = 'invitations.models.InvitationsAdapter' + +Sending Invites +--------------- + +First import the model: + +.. code-block:: python + + from invitations.utils import get_invitation_model + +Make an instance of the model: + +.. code-block:: python + + Invitation = get_invitation_model() + +Then finally pass the recipient to the model and send. + +.. code-block:: python + + # inviter argument is optional + invite = Invitation.create('email@example.com', inviter=request.user) + invite.send_invitation(request) + +To send invites via django admin, just add an invite and save. + + +Bulk Invites +------------ + +Bulk invites are supported via JSON. Post a list of comma separated emails to the dedicated URL and Invitations will return a data object containing a list of valid and invalid invitations. + +Signals +------- + +The following signals are emitted: + +* ``invite_url_sent`` +* ``invite_accepted`` + + +Management Commands +------------------- + +Expired and accepted invites can be cleared with the ``clear_expired_invitations`` management command: + +.. code-block:: sh + + python manage.py clear_expired_invitations diff --git a/setup.cfg b/setup.cfg index b88034e..b4aafb4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,40 @@ [metadata] -description-file = README.md +name = django-invitations +version = 1.9.3 +description = Generic invitations app with support for django-allauth +long_description = file: README.md +author = https://github.com/bee-keeper +author_email = none@none.com +url = https://github.com/jazzband/django-invitations.git +keywords = django invitation django-allauth invite +license = GPL-3.0-only +classifiers = + Development Status :: 4 - Beta + Intended Audience :: Developers + Topic :: Software Development :: Libraries :: Python Modules + Environment :: Web Environment + Topic :: Internet + Framework :: Django + Framework :: Django:: 3.2 + Framework :: Django:: 4.0 + Programming Language :: Python + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + License :: OSI Approved :: GPL-3.0-only +license_file = LICENSE + +[options] +package_dir= + =invitations +packages = find: +include_package_data = True +python_requires = >=3.7 +zip_safe = False + +[options.package_data] +invitations = "templates/*.*" + +[options.packages.find] +where = invitations