Permalink
Browse files

Merge branch 'release-0.12.0' into feature/bulk-messaging-api

Conflicts:
	rapidsms/contrib/registration/tests.py
	setup.py
  • Loading branch information...
2 parents a422240 + f6ac3a6 commit c73dad38f8d1d174b9d5927394332357094cf0de @copelco copelco committed Mar 18, 2013
View
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+. ~/VE/rapidsms/bin/activate
+
+coverage run run_tests.py --settings=tests.default
+coverage html
View
@@ -66,7 +66,8 @@ Release: v\ |release|. (:doc:`Installation <intro/install/index>`, :doc:`Release
messages sent and received by RapidSMS.
* :doc:`messaging <topics/contrib/messaging>` - Provides a web interface
through which you can send messages to Contacts.
-* registration
+* :doc:`registration <topics/contrib/registration>` - Provides a web interface
+ for creating, updating, and deleting RapidSMS contacts.
**The RapidSMS open-source project**
@@ -0,0 +1,110 @@
+=============================
+rapidsms.contrib.registration
+=============================
+
+.. module:: rapidsms.contrib.registration
+
+The `registration` app provides a nice interface for creating, updating,
+and deleting RapidSMS contacts, both on the web and via SMS messages. It is
+deliberately minimal, and outside
+of the core, so other apps can extend or replace it where necessary.
+
+Installation
+============
+
+1. `registration` depends on :doc:`handlers <handlers>`, so first install
+`handlers`.
+
+2. Add ``"rapidsms.contrib.registration"`` to
+:setting:`INSTALLED_APPS` in your settings file:
+
+.. code-block:: python
+ :emphasize-lines: 3
+
+ INSTALLED_APPS = [
+ ...
+ "rapidsms.contrib.registration",
+ ...
+ ]
+
+3. Add URLs for `registration` to your urlconf:
+
+.. code-block:: python
+ :emphasize-lines: 3
+
+ urlpatterns = ("",
+ ...
+ (r"^registration/", include("rapidsms.contrib.urls")),
+ ...
+ )
+
+4. (Optional) add `registration` link to the nav bar:
+
+
+.. code-block:: html
+ :emphasize-lines: 2
+
+ {% load url from future %}
+ <li><a href="{% url 'registration' %}">Registration</a></li>
+
+.. _registration-usage:
+
+Usage
+=====
+
+The `registration` app provides both web and SMS interfaces.
+
+Web
+---
+
+At the left of each page is a set of links:
+
+* List Contacts
+* Add Contact
+* Bulk Add Contacts
+
+List Contacts is the front page. It displays a table with the contacts.
+You can click on a contact row to edit that contact. You can edit the
+contact's name, language, etc., and also edit their connections near the
+bottom. A blank connection form is at the bottom; add a new connection by
+filling in the blank form's Backend and Identity fields and saving. Each
+existing connection has a Delete checkbox; delete a connection by checking
+its checkbox and saving. You can delete a contact by clicking the Delete
+Contact button at the bottom.
+
+Add Contact goes to a blank form for adding a new contact. It works just
+like the page for editing a contact.
+
+Bulk Add Contacts allows creating many contacts at once by uploading a
+.CSV file with the data. There's help on the page showing the format
+that the file should have.
+
+SMS Messages
+------------
+
+Users can use SMS messages to register themselves or change their
+preferred language through the `register` app.
+
+REGISTER
+~~~~~~~~
+
+Users can create a contact for themselves along with a connection
+representing their backend and identity by sending a text message
+of the form::
+
+ REGISTER <name>
+
+They can also use ``REG`` or ``JOIN`` as synonyms for ``REGISTER``.
+
+LANGUAGE
+~~~~~~~~
+
+After they have registered, users can choose their preferred language
+by sending a text message of the form::
+
+ LANGUAGE <code>
+
+They can also use ``LANG`` as a synonym for ``LANGUAGE``.
+
+The ``<code>`` should be the international code for the language,
+e.g. ``pt-BR`` for Brazilian Portuguese or ``de`` for German.
@@ -1,3 +0,0 @@
-The registration app provides a nice interface for creating, updating,
-and deleting RapidSMS contacts. It is deliberately minimal, and outside
-of the core, so other apps can extend or replace it where necessary.
@@ -5,16 +5,23 @@
from rapidsms.models import Contact, Connection
-class ContactForm(forms.ModelForm):
- class Meta:
- model = Contact
- exclude = ("connections",)
+class ConnectionFormSetBase(forms.models.BaseInlineFormSet):
+ def __init__(self, *args, **kwargs):
+ super(ConnectionFormSetBase, self).__init__(*args, **kwargs)
+ self.forms[0].empty_permitted = False
+ self.forms[0].fields['DELETE'].widget = forms.widgets.HiddenInput()
+
+
+ContactForm = forms.models.modelform_factory(Contact, exclude=("connections", ))
ConnectionFormSet = forms.models.inlineformset_factory(
Contact,
Connection,
extra=1,
- max_num=10)
+ max_num=10,
+ formset=ConnectionFormSetBase,
+)
+
# the built-in FileField doesn't specify the 'size' attribute, so the
# widget is rendered at its default width -- which is too wide for our
@@ -21,7 +21,7 @@ def help(self):
def handle(self, text):
if self.msg.connection.contact is None:
return self.respond_error(
- "You must JOIN or IDENTIFY yourself before you can " +
+ "You must JOIN or REGISTER yourself before you can " +
"set your language preference.")
t = text.lower()
@@ -7,12 +7,11 @@
class ContactTable(tables.Table):
- name = tables.LinkColumn('contact_edit', args=[tables.utils.A('pk')])
identities = tables.Column(empty_values=())
+ id = tables.LinkColumn('registration_contact_edit', args=[tables.utils.A('pk')])
class Meta:
model = Contact
- exclude = ('id', )
def render_identities(self, value, record):
return ', '.join([x.identity for x in record.connection_set.all()])
@@ -13,4 +13,17 @@
<h1>Registration</h1>
</div>
</div>
+
+ <div class="row-fluid">
+ <div class="span3 well">
+ <ul class="nav nav-list">
+ <li class="nav-header">Actions</li>
+ <li><a href="{% url 'registration' %}">List Contacts</a></li>
+ <li><a href="{% url 'registration_contact_add' %}">Add Contact</a></li>
+ <li><a href="{% url 'registration_bulk_add' %}">Bulk Add Contacts</a></li>
+ </ul>
+ </div>
+ <div class="span8">
+ {% block page %}{% endblock %}
+ </div>
{% endblock %}
@@ -2,29 +2,18 @@
{% load url from future %}
{% load forms_tags %}
-{% block content %}
- {{ block.super }}
-
- <div class="row-fluid">
- <div class="span3 well">
- <ul class="nav nav-list">
- <li class="nav-header">Actions</li>
- <li><a href="{% url 'registration' %}">List Contacts</a></li>
- <li><a href="{% url 'contact_add' %}">Add Contact</a></li>
- <li class="active"><a href="{% url 'contact_bulk_add' %}">Bulk Add Contacts</a></li>
- </ul>
+{% block page %}
+ <div class="page_header">
+ <h1>Registration: Bulk Add</h1>
</div>
- <div class="span8">
- {% if csv_errors %}
+ {% if csv_errors %}
<p style="color: red; font-weight: strong;">CSV Error: {{ csv_errors }}</p>
- {% endif %}
- <form action="" method="post" enctype="multipart/form-data">
- {% render_form bulk_form %}
- {% csrf_token %}
- <div class="submit">
- <input type="submit" name="submit" value="Save Contacts" />
- </div>
- </form>
- </div>
-</div>
-{% endblock %}
+ {% endif %}
+ <form action="" method="post" enctype="multipart/form-data">
+ {% render_form bulk_form %}
+ {% csrf_token %}
+ <div class="submit">
+ <input type="submit" name="submit" value="Save Contacts" />
+ </div>
+ </form>
+{% endblock %}
@@ -2,22 +2,21 @@
{% load url from future %}
{% load forms_tags %}
-{% block content %}
- {{ block.super }}
-
- <div class="row-fluid">
- <div class="span3 well">
- <ul class="nav nav-list">
- <li class="nav-header">Actions</li>
- <li><a href="{% url 'registration' %}">List Contacts</a></li>
- <li class="active"><a href="{% url 'contact_add' %}">Add Contact</a></li>
- <li><a href="{% url 'contact_bulk_add' %}">Bulk Add Contacts</a></li>
- </ul>
+{% block page %}
+ <div class="page_header">
+ {% if contact %}
+ <h1>Registration: Edit Contact</h1>
+ {% else %}
+ <h1>Registration: Add Contact</h1>
+ {% endif %}
</div>
<div class="span8">
<form action="" method="post">
- {{ contact_form }}
- {{ connection_formset }}
+ {% render_form contact_form %}
+ {% render_form connection_formset.management_form %}
+ {% for form in connection_formset %}
+ {% render_form form %}
+ {% endfor %}
{% csrf_token %}
<div class="submit">
<input type="submit" name="submit" value="Save Contact" />
@@ -3,26 +3,15 @@
{% load forms_tags %}
{% load django_tables2 %}
-{% block extra_stylesheets %}
+{% block stylesheets %}
+{{ block.super }}
<link type="text/css" rel="stylesheet" href="{{ STATIC_URL }}registration/stylesheets/dashboard.css" />
{% endblock %}
-{% block content %}
- {{ block.super }}
-
-<div class="row-fluid">
- <div class="span3 well">
- <ul class="nav nav-list">
- <li class="nav-header">Actions</li>
- <li class="active"><a href="#">List Contacts</a></li>
- <li><a href="{% url 'contact_add' %}">Add Contact</a></li>
- <li><a href="{% url 'contact_bulk_add' %}">Bulk Add Contacts</a></li>
- </ul>
- </div>
- <div class="span8">
- {% render_table contacts_table %}
+{% block page %}
+ <div class="page_header">
+ <h1>Registration: Contacts</h1>
</div>
-</div>
-
+ {% render_table contacts_table %}
{% endblock %}
Oops, something went wrong.

0 comments on commit c73dad3

Please sign in to comment.