wikipbx-dev team mailing list archive
-
wikipbx-dev team
-
Mailing list archive
-
Message #00054
Re: address book application
Hello,
attached you can find a first try at a shared contacts app for wikipbx.
I'll try to push something to the phone-contacts app tomorrow because
i've some merge issues and it's time to go home :)
Comments are appreciated.
thanks,
riccardo
=== added directory 'wikipbx/contacts'
=== added file 'wikipbx/contacts/__init__.py'
=== added file 'wikipbx/contacts/forms.py'
--- wikipbx/contacts/forms.py 1970-01-01 00:00:00 +0000
+++ wikipbx/contacts/forms.py 2010-11-02 17:12:12 +0000
@@ -0,0 +1,14 @@
+from django.utils.translation import gettext as _
+from django import forms
+
+from wikipbx.contacts.models import Contact
+
+class ContactForm(forms.ModelForm):
+ class Meta:
+ model = Contact
+ exclude = ('account',)
+
+CONTACTS_EXPORT_CHOICES = (('gigaset', u'Siemens Gigaset'),)
+
+class ExportContactForm(forms.Form):
+ export_type = forms.ChoiceField(choices=CONTACTS_EXPORT_CHOICES, label=_(u"Contacts export format:"))
=== added file 'wikipbx/contacts/models.py'
--- wikipbx/contacts/models.py 1970-01-01 00:00:00 +0000
+++ wikipbx/contacts/models.py 2010-11-02 17:07:30 +0000
@@ -0,0 +1,18 @@
+from django.utils.translation import ugettext_lazy as _
+from django.db import models
+from wikipbx.wikipbxweb.models import Account
+
+class Contact(models.Model):
+ name = models.CharField(_(u"name"), max_length=150, unique=True)
+ numbers = models.CharField(_(u"caller ID number"), max_length=25)
+ blacklist = models.BooleanField(_(u"blacklist"), default=False)
+ notes = models.TextField(_(u"notes"), null=True, blank=True)
+ account = models.ForeignKey(Account, verbose_name=_(u"account"))
+
+ def __unicode__(self):
+ return self.name
+
+ class Meta:
+ verbose_name = _(u"contact")
+ verbose_name_plural = _(u"contacts")
+ ordering = ['name']
=== added directory 'wikipbx/contacts/templates'
=== added file 'wikipbx/contacts/templates/contacts.html'
--- wikipbx/contacts/templates/contacts.html 1970-01-01 00:00:00 +0000
+++ wikipbx/contacts/templates/contacts.html 2010-11-02 17:08:33 +0000
@@ -0,0 +1,69 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block dashcontent %}
+<h2>
+ <img src="{{ MEDIA_URL }}icons/user.png"/>{% trans "Contacts - This Account" %}
+</h2>
+
+{% if contacts %}
+<div>
+ <form action="/contacts/export/" method="post">
+ {{ export.as_p }}
+ <input type="submit" value={% trans "Export" %}>
+ </form>
+</div>
+
+<table>
+ <thead>
+ <tr>
+ <th>
+ {% trans "Name" %}
+ </th>
+ <th>
+ {% trans "Caller ID number" %}
+ </th>
+ <th>
+ {% trans "Blacklist" %}
+ </th>
+ <th>
+ {% trans "Notes" %}
+ </th>
+ <th>
+ {% trans "Delete" %}
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for contact in contacts %}
+ <tr>
+ <td>
+ <img src="{{ MEDIA_URL }}icons/user_edit.png"/>
+ <a href="{% url contact-edit contact.id %}">{{ contact.name }}</a>
+ </td>
+ <td>
+ {{ contact.numbers }}
+ </td>
+ <td>
+ {{ contact.blacklist }}
+ </td>
+ <td>
+ {{ contact.notes }}
+ </td>
+ <td>
+ <a href="{% url contact-delete contact.id %}">
+ <img src="{{ MEDIA_URL }}icons/delete.png"/>
+ </a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+
+{% else %}
+
+<div><img src="{{ MEDIA_URL }}icons/tux.png"/>{% trans "No contacts defined" %}</div>
+
+{% endif %}
+
+{% endblock %}
=== added file 'wikipbx/contacts/templates/edit_contact.html'
--- wikipbx/contacts/templates/edit_contact.html 1970-01-01 00:00:00 +0000
+++ wikipbx/contacts/templates/edit_contact.html 2010-11-02 14:32:20 +0000
@@ -0,0 +1,14 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block dashcontent %}
+<form method="post">
+ <table>
+ {{ form }}
+ <tr>
+ <td></td>
+ <td><input type="submit" class="button" value={% trans "Update" %}></td>
+ </tr>
+ </table>
+</form>
+{% endblock %}
=== added file 'wikipbx/contacts/tests.py'
--- wikipbx/contacts/tests.py 1970-01-01 00:00:00 +0000
+++ wikipbx/contacts/tests.py 2010-11-02 10:21:12 +0000
@@ -0,0 +1,23 @@
+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+class SimpleTest(TestCase):
+ def test_basic_addition(self):
+ """
+ Tests that 1 + 1 always equals 2.
+ """
+ self.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+
=== added file 'wikipbx/contacts/urls.py'
--- wikipbx/contacts/urls.py 1970-01-01 00:00:00 +0000
+++ wikipbx/contacts/urls.py 2010-11-02 17:00:49 +0000
@@ -0,0 +1,14 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns(
+ 'contacts.views',
+
+ url(r'^$', 'contacts', name='contact-list'),
+ url(r'^add/$', 'edit_contact', { 'contact_id': None }, name='contact-add'),
+ url(r'^edit/(?P<contact_id>\d+)/$', 'edit_contact',
+ name='contact-edit'),
+ url(r'^del/(?P<contact_id>\d+)/$', 'del_contact',
+ name='contact-delete'),
+ url(r'^export/$', 'export_contacts',
+ name='contact-export'),
+)
=== added file 'wikipbx/contacts/views.py'
--- wikipbx/contacts/views.py 1970-01-01 00:00:00 +0000
+++ wikipbx/contacts/views.py 2010-11-02 17:31:46 +0000
@@ -0,0 +1,84 @@
+from django.views.decorators.http import require_POST
+from django.utils.translation import gettext as _
+from django.shortcuts import get_object_or_404
+from django.core.urlresolvers import reverse
+from django.views.generic import simple
+from django import http
+
+from wikipbx.wikipbxweb import decorators
+from wikipbx.contacts.models import Contact
+from wikipbx.contacts import forms
+
+import string
+
+@decorators.require_admin
+def contacts(request):
+ account = request.user.get_profile().account
+ contacts = Contact.objects.filter(account=account)
+ export = forms.ExportContactForm()
+ return simple.direct_to_template(
+ request, 'contacts.html', {'contacts': contacts, 'export': export })
+
+@decorators.require_admin
+def edit_contact(request, contact_id):
+ account = request.user.get_profile().account
+ if contact_id is None:
+ contact = Contact(account=account)
+ else:
+ contact = get_object_or_404(Contact, account=account, pk=contact_id)
+
+ if request.method == 'POST':
+ form = forms.ContactForm(request.POST, instance=contact)
+
+ if form.is_valid():
+ contact = form.save()
+
+ msg = _(u"Contact %s saved.") % contact
+ return http.HttpResponseRedirect(
+ reverse('contact-list') + "?infomsg=%s" % msg)
+ else:
+ form = forms.ContactForm(instance=contact)
+
+ return simple.direct_to_template(request, 'edit_contact.html', {'form': form})
+
+@decorators.require_admin
+def del_contact(request, contact_id):
+ account = request.user.get_profile().account
+ contact = get_object_or_404(Contact, account=account, pk=contact_id)
+ contact.delete()
+ msg = _(u"Contact %s deleted.") % contact
+ return http.HttpResponseRedirect(
+ reverse('contact-list') + "?infomsg=%s" % msg)
+
+VCF_SKELETON = \
+"""BEGIN:VCARD
+VERSION:2.1
+FN: %s
+N: %s
+TEL;HOME:%s
+END:VCARD
+
+"""
+
+def gigaset_export(contacts):
+ vcf = ""
+ for c in contacts:
+ v = VCF_SKELETON % (c.name, c.name, c.numbers)
+ vcf = "%s%s" % (vcf, v)
+ return http.HttpResponse(vcf, mimetype="text/x-vcard")
+
+@decorators.require_admin
+@require_POST
+def export_contacts(request):
+ account = request.user.get_profile().account
+ contacts = Contact.objects.filter(account=account)
+ if True:
+ export_type = request.POST['export_type']
+ if export_type == "gigaset":
+ return gigaset_export(contacts)
+ else:
+ pass
+
+ export = forms.ExportContactForm()
+ return simple.direct_to_template(
+ request, 'contacts.html', {'contacts': contacts, 'export': export })
=== modified file 'wikipbx/settings_template.py'
--- wikipbx/settings_template.py 2010-10-17 15:42:18 +0000
+++ wikipbx/settings_template.py 2010-11-02 15:12:33 +0000
@@ -89,6 +89,7 @@
# Don't forget to use absolute paths, not relative paths.
os.path.join(INSTALL_SRC, "wikipbxweb/templates"),
os.path.join(INSTALL_SRC, "freeswitchxml"),
+ os.path.join(INSTALL_SRC, "contacts/templates"),
)
INSTALLED_APPS = (
@@ -98,6 +99,7 @@
'django.contrib.sites',
'django.contrib.admin',
'wikipbx.wikipbxweb',
+ 'wikipbx.contacts',
)
TEMPLATE_CONTEXT_PROCESSORS = (
=== modified file 'wikipbx/urls.py'
--- wikipbx/urls.py 2010-09-04 11:48:49 +0000
+++ wikipbx/urls.py 2010-11-02 14:52:07 +0000
@@ -140,6 +140,12 @@
url(r'^test_mailserver/$', 'test_mailserver', name='email-test'),
)
+# Contacts
+urlpatterns += patterns(
+ '',
+ url(r'^contacts/', include('contacts.urls')),
+)
+
# Enable static serving only for debug mode. Use your web server as front-end
# in production.
if settings.DEBUG:
=== modified file 'wikipbx/wikipbxweb/templates/left_toolbar_base.html'
--- wikipbx/wikipbxweb/templates/left_toolbar_base.html 2010-09-04 19:14:23 +0000
+++ wikipbx/wikipbxweb/templates/left_toolbar_base.html 2010-11-02 15:18:47 +0000
@@ -155,6 +155,15 @@
<img src="{{ MEDIA_URL }}icons/sound.png"/><a href="{% url soundclip-list %}">{% trans "Manage" %}</a>
</div>
</div>
+
+<div class="header">{% trans "Contacts" %}</div>
+<div class="indent">
+ <div class="menu-entry">
+ <img src="{{ MEDIA_URL }}icons/user_add.png"><a href="{% url contact-add %}">{% trans "Add" %}</a>
+ </div>
+ <div class="menu-entry">
+ <img src="{{ MEDIA_URL }}icons/user.png"/><a href="{% url contact-list %}">{% trans "Manage" %}</a>
+ </div>
{% endblock %}
{% block help %}
Follow ups
References