Repository: watchdogpolska/feder

Issue:
Eksport w CSV EmailLog 
Wprowadziliśmy w ```feder.letters.logs``` statystyki dostarczania wiadomości. Należy wprowadzić zestawienie wszystkich danych z EmailLog dla danego monitoringu, aby można było zrobić statystykę czy coś.


Discussion:
1. czy eksport powinien być autoryzowany? + Jakie uprawnienie?
2. jakie pola (z case, monitoring) powinny być zawarte w CSV?
1/ Generalnie dane w ```EmailLog``` są chronione poprzez ``monitorings.view_log``, więc uprawnienie nie niższe ( https://github.com/watchdogpolska/feder/blob/ae89d4a93ebb2f75025305758e6b988787db04f2/feder/letters/logs/views.py#L20 ). Nie ma także sensu wprowadzać dodatkowego uprawnienia dla samego eksportu.
2/ Myślę, że styknie ```Case.id, Monitoring.id, Case.email,Case.institution.name,Case.institution.id``` + ```EmailLog```.

Resolving patch:
diff --git a/feder/letters/logs/urls.py b/feder/letters/logs/urls.py
--- a/feder/letters/logs/urls.py
+++ b/feder/letters/logs/urls.py
@@ -11,6 +11,8 @@
         name="list"),
     url(_(r'^monitoring-(?P<monitoring_pk>[\d-]+)$'), views.EmailLogMonitoringListView.as_view(),
         name="list"),
+    url(_(r'^monitoring-(?P<monitoring_pk>[\d-]+)/export$'), views.EmailLogMonitoringCsvView.as_view(),
+        name="export"),
     url(_(r'^log-(?P<pk>[\d-]+)$'), views.EmailLogDetailView.as_view(),
         name="detail"),
 ]
diff --git a/feder/letters/logs/views.py b/feder/letters/logs/views.py
--- a/feder/letters/logs/views.py
+++ b/feder/letters/logs/views.py
@@ -1,8 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
+from django.utils import timezone
+import unicodecsv as csv
+
 from braces.views import SelectRelatedMixin, PrefetchRelatedMixin
 from cached_property import cached_property
+from django.http import HttpResponse
 from django.shortcuts import get_object_or_404
 from django.views.generic import DetailView, ListView
 
@@ -10,7 +14,7 @@
 from feder.letters.logs.models import EmailLog
 from feder.main.mixins import AttrPermissionRequiredMixin
 from feder.monitorings.models import Monitoring
-
+from django.views.generic.list import ListView
 
 class ListMonitoringMixin(AttrPermissionRequiredMixin, SelectRelatedMixin):
     select_related = ['case']
@@ -39,6 +43,61 @@ def monitoring(self):
         return get_object_or_404(Monitoring, pk=self.kwargs['monitoring_pk'])
 
 
+class EmailLogMonitoringCsvView(ListMonitoringMixin, ListView):
+    permission_required = 'monitorings.view_log'
+
+    select_related = ['case', 'case__institution']
+
+    @cached_property
+    def monitoring(self):
+        return get_object_or_404(Monitoring, pk=self.kwargs['monitoring_pk'])
+
+    def get(self, *args, **kwargs):
+        response = self._get_csv_response()
+        self._write_rows(response, self.get_queryset())
+        return response
+
+    @staticmethod
+    def _get_base_model_field_names(queryset):
+        opts = queryset.model._meta
+        return [field.name for field in opts.fields if field.related_model is None]
+
+    def _get_csv_response(self):
+        csv_response = HttpResponse(content_type='text/csv')
+        current_time = timezone.now()
+        filename = 'email_log_{0}-{1}-{2}.csv'.format(self.monitoring.id,
+                                                      current_time.strftime('%Y_%m_%d-%H_%M_%S'),
+                                                      current_time.tzname()
+                                                      )
+        csv_response['Content-Disposition'] = "attachment;filename={0}".format(filename)
+        return csv_response
+
+    def _write_rows(self, response, queryset):
+        writer = csv.writer(response)
+
+        # automatically add all fields from base table/model
+        base_field_names = self._get_base_model_field_names(queryset)
+
+        # print header row
+        writer.writerow(base_field_names +
+                        [
+                            'case id',
+                            'case email',
+                            'institution',
+                            'institution id',
+                            'monitoring id']
+                        )
+
+        for obj in queryset:
+            writer.writerow(
+                [getattr(obj, field) for field in base_field_names] + [
+                obj.case.id,
+                obj.case.email,
+                obj.case.institution.name,
+                obj.case.institution_id,
+                obj.case.monitoring_id,
+            ])
+
 class EmailLogCaseListView(ListMonitoringMixin, ListView):
     template_name_suffix = '_list_for_case'
 


Test patch:
diff --git a/feder/letters/logs/tests.py b/feder/letters/logs/tests.py
--- a/feder/letters/logs/tests.py
+++ b/feder/letters/logs/tests.py
@@ -144,6 +144,25 @@ def get_url(self):
         return reverse('logs:list', kwargs={'monitoring_pk': self.monitoring.pk})
 
 
+class EmailLogMonitoringCsvViewTestCase(ObjectMixin, PermissionStatusMixin, TestCase):
+    permission = ['monitorings.view_log']
+
+    def get_url(self):
+        return reverse('logs:export', kwargs={'monitoring_pk': self.monitoring.pk})
+
+    def test_has_logs(self):
+        logrecord_for_another_monitoring = LogRecordFactory()
+        self.login_permitted_user()
+        response = self.client.get(self.get_url())
+        self.assertTrue(response.get('Content-Disposition').startswith('attachment;filename='))
+        self.assertContains(response, self.emaillog.case.institution)
+        self.assertNotContains(response,
+                               logrecord_for_another_monitoring.email.case.institution.name,
+                               200,
+                               ('Csv export for a monitoring should not '
+                                'contain emaillogs for another monitoring'))
+
+
 class EmailLogCaseListViewTestCase(ObjectMixin, PermissionStatusMixin, TestCase):
     permission = ['monitorings.view_log']