Extracting contact forms data to pseudo csv format
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Tue, 5 Nov 2013 08:22:51 +0000 (09:22 +0100)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Tue, 5 Nov 2013 09:49:05 +0000 (10:49 +0100)
contact/admin.py
contact/locale/pl/LC_MESSAGES/django.mo
contact/locale/pl/LC_MESSAGES/django.po
contact/templates/admin/contact/contact/change_list.html [new file with mode: 0644]
contact/utils.py [new file with mode: 0644]
edumed/contact_forms.py
edumed/locale/pl/LC_MESSAGES/django.mo
edumed/locale/pl/LC_MESSAGES/django.po

index 33b1963..f849f95 100644 (file)
@@ -5,6 +5,10 @@ from django.utils.translation import ugettext as _
 from .forms import contact_forms, admin_list_width
 from django.template import Template
 from django.utils.safestring import mark_safe
 from .forms import contact_forms, admin_list_width
 from django.template import Template
 from django.utils.safestring import mark_safe
+from django.conf.urls import patterns, url
+from django.http import HttpResponse
+
+from .utils import csv_prepare
 
 
 class ContactAdminMeta(admin.ModelAdmin.__class__):
 
 
 class ContactAdminMeta(admin.ModelAdmin.__class__):
@@ -90,5 +94,65 @@ class ContactAdmin(admin.ModelAdmin):
         return super(ContactAdmin, self).change_view(request, object_id,
             extra_context=extra_context)
 
         return super(ContactAdmin, self).change_view(request, object_id,
             extra_context=extra_context)
 
+    def changelist_view(self, request, extra_context=None):
+        context = dict()
+        if 'form_tag' in request.GET:
+            form = contact_forms[request.GET['form_tag']]
+            context['extract_types'] = [dict(slug = 'all', label = _('all'))] + [dict(slug = 'contacts', label = _('contacts'))]
+            context['extract_types'] += [type for type in getattr(form, 'extract_types', [])]
+        return super(ContactAdmin, self).changelist_view(request, extra_context = context)
+
+    def get_urls(self):
+        urls = super(ContactAdmin, self).get_urls()
+        return patterns('',
+            url(r'^extract/(?P<form_tag>[\w-]+)/(?P<extract_type_slug>[\w-]+)/$', self.admin_site.admin_view(extract_view), name='contact_extract')
+        ) + super(ContactAdmin, self).get_urls()
+
+
+def extract_view(request, form_tag, extract_type_slug):
+    toret = u''
+    contacts_by_spec = dict()
+    form = contact_forms[form_tag]
+
+    q = Contact.objects.filter(form_tag = form_tag)
+    at_year = request.GET.get('created_at__year')
+    at_month = request.GET.get('created_at__month')
+    if at_year:
+        q = q.filter(created_at__year = at_year)
+        if at_month:
+            q = q.filter(created_at__month = at_month)
+
+    # Segregate contacts by body key sets
+    for contact in q.all():
+        if extract_type_slug == 'contacts':
+            keys = ['contact']
+        elif extract_type_slug == 'all':
+            keys = contact.body.keys() + ['contact']
+        else:
+            keys = form.get_extract_fields(contact, extract_type_slug)
+        contacts_by_spec.setdefault(tuple(keys), []).append(contact)
+    
+    # Generate list for each body key set
+    for keys, contacts in contacts_by_spec.items():
+        toret += u','.join(keys) + '\n'
+        for contact in contacts:
+            if extract_type_slug == 'contacts':
+                records = [dict(contact=contact.contact)]
+            elif extract_type_slug == 'all':
+                records = [dict(contact = contact.contact, **contact.body)]
+            else:
+                records = form.get_extract_records(keys, contact, extract_type_slug)
+
+            for record in records:
+                for key in keys:
+                    if key not in record:
+                        record[key] = ''
+                    record[key] = csv_prepare(record[key])
+                toret += u','.join([record[key] for key in keys]) + '\n'
+        toret += '\n\n'
+
+    response = HttpResponse(toret, content_type = 'text/csv')
+    response['Content-Disposition'] = 'attachment; filename="kontakt.csv"'
+    return response
 
 admin.site.register(Contact, ContactAdmin)
 
 admin.site.register(Contact, ContactAdmin)
index 985b0c0..2b2e6e9 100644 (file)
Binary files a/contact/locale/pl/LC_MESSAGES/django.mo and b/contact/locale/pl/LC_MESSAGES/django.mo differ
index 7805958..35e33a3 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-10-10 13:12+0200\n"
+"POT-Creation-Date: 2013-11-05 10:16+0100\n"
 "PO-Revision-Date: 2012-10-10 13:12+0100\n"
 "Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "PO-Revision-Date: 2012-10-10 13:12+0100\n"
 "Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -15,50 +15,62 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2)\n"
 
 
-#: admin.py:49
+#: admin.py:77
 msgid "Body"
 msgstr "Treść"
 
 msgid "Body"
 msgstr "Treść"
 
-#: models.py:10
+#: admin.py:101
+msgid "all"
+msgstr "wszystko"
+
+#: admin.py:101
+msgid "contacts"
+msgstr "kontakty"
+
+#: forms.py:29
+msgid "Contact form"
+msgstr "Formularz kontaktowy"
+
+#: forms.py:30
+msgid "Submit"
+msgstr "Wyślij"
+
+#: models.py:11
 msgid "submission date"
 msgstr "data wysłania"
 
 msgid "submission date"
 msgstr "data wysłania"
 
-#: models.py:11
+#: models.py:12
 msgid "IP address"
 msgstr "adres IP"
 
 msgid "IP address"
 msgstr "adres IP"
 
-#: models.py:12
+#: models.py:13
 msgid "contact"
 msgstr "kontakt"
 
 msgid "contact"
 msgstr "kontakt"
 
-#: models.py:13
+#: models.py:14
 msgid "form"
 msgstr "formularz"
 
 msgid "form"
 msgstr "formularz"
 
-#: models.py:14
+#: models.py:15
 msgid "body"
 msgstr "treść"
 
 msgid "body"
 msgstr "treść"
 
-#: models.py:18
+#: models.py:29
 msgid "submitted form"
 msgstr "przysłany formularz"
 
 msgid "submitted form"
 msgstr "przysłany formularz"
 
-#: models.py:19
+#: models.py:30
 msgid "submitted forms"
 msgstr "przysłane formularze"
 
 msgid "submitted forms"
 msgstr "przysłane formularze"
 
-#: templates/contact/form.html:5
-msgid "Contact form"
-msgstr "Formularz kontaktowy"
+#: templates/admin/contact/contact/change_list.html:12
+msgid "Extract"
+msgstr "Ekstrakt"
 
 
-#: templates/contact/form.html:14
-msgid "Submit"
-msgstr "Wyślij"
-
-#: templates/contact/mail_body.txt:2
-#: templates/contact/mail_subject.txt:1
+#: templates/contact/mail_body.txt:2 templates/contact/mail_subject.txt:1
 #, python-format
 msgid "Thank you for contacting us at %(site_name)s."
 msgstr "Dziękujemy za skontaktowanie się z nami na stronie %(site_name)s."
 #, python-format
 msgid "Thank you for contacting us at %(site_name)s."
 msgstr "Dziękujemy za skontaktowanie się z nami na stronie %(site_name)s."
@@ -71,11 +83,10 @@ msgstr "Twoje zgłoszenie zostało przekazane osobie koordynującej projekt."
 msgid "Message sent automatically. Please do not reply to it."
 msgstr "Wiadomość wysłana automatycznie, prosimy nie odpowiadać."
 
 msgid "Message sent automatically. Please do not reply to it."
 msgstr "Wiadomość wysłana automatycznie, prosimy nie odpowiadać."
 
-#: templates/contact/thanks.html:5
+#: templates/contact/thanks.html:4 templates/contact/thanks.html.py:8
 msgid "Thank you"
 msgstr "Dziękujemy"
 
 msgid "Thank you"
 msgstr "Dziękujemy"
 
-#: templates/contact/thanks.html:8
+#: templates/contact/thanks.html:11
 msgid "Thank you for submitting the contact form."
 msgstr "Dziękujemy za wypełnienie formularza kontaktowego."
 msgid "Thank you for submitting the contact form."
 msgstr "Dziękujemy za wypełnienie formularza kontaktowego."
-
diff --git a/contact/templates/admin/contact/contact/change_list.html b/contact/templates/admin/contact/contact/change_list.html
new file mode 100644 (file)
index 0000000..3b47c97
--- /dev/null
@@ -0,0 +1,18 @@
+{% extends "admin/change_list.html" %}
+{% load i18n %}
+{% load admin_urls %}
+
+
+{% block object-tools-items %}
+    {{block.super}}
+    {% if request.GET.form_tag %}
+        {% for extract_type in extract_types %}
+            <li>
+                <a href="{% url 'admin:contact_extract' form_tag=request.GET.form_tag extract_type_slug=extract_type.slug %}?created_at__month={{request.GET.created_at__month}}&created_at__year={{request.GET.created_at__year}}">
+                    {% trans 'Extract' %}: {{extract_type.label}}
+                </a>
+            </li>
+        {% endfor %}
+    {% endif %}
+{% endblock %}
+
diff --git a/contact/utils.py b/contact/utils.py
new file mode 100644 (file)
index 0000000..ce37833
--- /dev/null
@@ -0,0 +1,8 @@
+def csv_escape(string):
+    return '"' + string.replace('\r\n', ' ').replace('\n', ' ').replace('"', '\"') + '"'
+
+def csv_prepare(obj):
+    to_escape = obj
+    if not isinstance(obj, unicode):
+        to_escape = str(to_escape)
+    return csv_escape(to_escape)
\ No newline at end of file
index 507c6d1..8d3131e 100644 (file)
@@ -128,6 +128,37 @@ class WTEMForm(ContactForm):
         required=False
     )
 
         required=False
     )
 
+    extract_types = (dict(slug='extended', label=_('extended')),)
+
+    @staticmethod
+    def get_extract_fields(contact, extract_type_slug):
+        fields = contact.body.keys()
+        fields.pop(fields.index('student'))
+        fields.extend(['contact', 'student_first_name', 'student_last_name', 'student_email'])
+        return fields
+
+    @staticmethod
+    def get_extract_records(keys, contact, extract_type_slug):
+        toret = [dict()]
+        for field_name in keys:
+            if field_name.startswith('student_'):
+                continue
+            if field_name == 'contact':
+                val = contact.contact
+            else:
+                val = contact.body[field_name]
+            toret[0][field_name] = val
+        
+        current = toret[0]
+        for student in contact.body['student']:
+            for attr in ('first_name', 'last_name', 'email'):
+                current['student_' + attr] = student[attr]
+            if not current in toret:
+                toret.append(current)
+            current = dict()
+        return toret
+
+
 class MILForm(ContactForm):
     form_tag = 'mil'
     form_title = _('Share your thoughts on the "Media and information literacy competencies catalogue"')
 class MILForm(ContactForm):
     form_tag = 'mil'
     form_title = _('Share your thoughts on the "Media and information literacy competencies catalogue"')
index 455c60e..2417c1b 100644 (file)
Binary files a/edumed/locale/pl/LC_MESSAGES/django.mo and b/edumed/locale/pl/LC_MESSAGES/django.mo differ
index 2370fa9..cd080d3 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-10-18 15:07+0200\n"
+"POT-Creation-Date: 2013-11-05 10:12+0100\n"
 "PO-Revision-Date: 2012-11-19 15:58+0100\n"
 "Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "PO-Revision-Date: 2012-11-19 15:58+0100\n"
 "Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,45 +18,48 @@ msgstr ""
 "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
 "|| n%100>=20) ? 1 : 2)\n"
 
 "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
 "|| n%100>=20) ? 1 : 2)\n"
 
-#: contact_forms.py:133
+#: contact_forms.py:131
+msgid "extended"
+msgstr "rozszerzony"
+
+#: contact_forms.py:160
 msgid ""
 "Share your thoughts on the \"Media and information literacy competencies "
 "catalogue\""
 msgid ""
 "Share your thoughts on the \"Media and information literacy competencies "
 "catalogue\""
-msgstr ""
-" Podziel się uwagami na temat Katalogu Kompetencji "
+msgstr " Podziel się uwagami na temat Katalogu Kompetencji "
 
 
-#: contact_forms.py:134
+#: contact_forms.py:161
 msgid "Submit"
 msgstr "Zgłoś"
 
 msgid "Submit"
 msgstr "Zgłoś"
 
-#: contact_forms.py:138
+#: contact_forms.py:165
 msgid "Name and Surname"
 msgstr "Imię i nazwisko"
 
 msgid "Name and Surname"
 msgstr "Imię i nazwisko"
 
-#: contact_forms.py:139
+#: contact_forms.py:166
 msgid "E-mail"
 msgstr "Adres e-mail"
 
 msgid "E-mail"
 msgstr "Adres e-mail"
 
-#: contact_forms.py:141
+#: contact_forms.py:168
 msgid "Institution"
 msgstr "Instytucja"
 
 msgid "Institution"
 msgstr "Instytucja"
 
-#: contact_forms.py:144
+#: contact_forms.py:171
 msgid "What do you think about the proposed educational stages classification?"
 msgstr "Co sądzisz o zaproponowanym podziale na etapy edukacyjne?"
 
 msgid "What do you think about the proposed educational stages classification?"
 msgstr "Co sądzisz o zaproponowanym podziale na etapy edukacyjne?"
 
-#: contact_forms.py:151
+#: contact_forms.py:178
 msgid "What do you think about the proposed thematic fields?"
 msgstr "Co sądzisz o zaproponowanym podziale na obszary tematyczne?"
 
 msgid "What do you think about the proposed thematic fields?"
 msgstr "Co sądzisz o zaproponowanym podziale na obszary tematyczne?"
 
-#: contact_forms.py:158
+#: contact_forms.py:185
 msgid ""
 "What important areas of media and information literacy have been left out?"
 msgstr ""
 "Jakie ważne obszary edukacji medialnej i informacyjnej zostały Twoim zdaniem "
 "niewystarczająco pogłębione lub pominięto je w ogóle?"
 
 msgid ""
 "What important areas of media and information literacy have been left out?"
 msgstr ""
 "Jakie ważne obszary edukacji medialnej i informacyjnej zostały Twoim zdaniem "
 "niewystarczająco pogłębione lub pominięto je w ogóle?"
 
-#: contact_forms.py:165
+#: contact_forms.py:192
 msgid "Other suggestions and comments"
 msgstr "Inne uwagi i sugestie"
 
 msgid "Other suggestions and comments"
 msgstr "Inne uwagi i sugestie"
 
@@ -77,19 +80,19 @@ msgstr "Strona której szukasz nie została znaleziona."
 msgid "Forum search"
 msgstr "Szukaj na forum"
 
 msgid "Forum search"
 msgstr "Szukaj na forum"
 
-#: templates/base_mil.html:8
+#: templates/base_mil.html:9
 msgid "Consultations"
 msgstr "Konsultacje"
 
 msgid "Consultations"
 msgstr "Konsultacje"
 
-#: templates/base_mil.html:9
+#: templates/base_mil.html:10
 msgid "Competencies"
 msgstr "Kompetencje"
 
 msgid "Competencies"
 msgstr "Kompetencje"
 
-#: templates/base_mil.html:10
+#: templates/base_mil.html:11
 msgid "Take Part"
 msgstr "Weź udział"
 
 msgid "Take Part"
 msgstr "Weź udział"
 
-#: templates/base_mil.html:14
+#: templates/base_mil.html:15
 msgid "Contact"
 msgstr "Kontakt"
 
 msgid "Contact"
 msgstr "Kontakt"