diff --git a/debian/control b/debian/control index 1564608bb..f1ce626c6 100644 --- a/debian/control +++ b/debian/control @@ -28,7 +28,8 @@ Depends: ${misc:Depends}, ${python:Depends}, python-cryptography (>= 1.3.4), python-django-filters (>= 1), python-django-filters (<< 2), - python-pil + python-pil, + python-tablib Provides: ${python:Provides} Recommends: python-ldap Suggests: python-raven diff --git a/setup.py b/setup.py index ccc97116d..85fee6ae6 100755 --- a/setup.py +++ b/setup.py @@ -132,6 +132,7 @@ setup(name="authentic2", 'XStatic-jquery-ui', 'xstatic-select2', 'pillow', + 'tablib', ], zip_safe=False, classifiers=[ diff --git a/src/authentic2/manager/user_views.py b/src/authentic2/manager/user_views.py index 5c2cad66e..3e03e5917 100644 --- a/src/authentic2/manager/user_views.py +++ b/src/authentic2/manager/user_views.py @@ -1,3 +1,4 @@ +import datetime import uuid import collections @@ -16,6 +17,7 @@ from django.views.generic.detail import SingleObjectMixin from django.views.generic import View from import_export.fields import Field +import tablib from authentic2.constants import SWITCH_USER_SESSION_KEY from authentic2.models import Attribute, PasswordReset @@ -321,19 +323,51 @@ class UsersExportView(ExportMixin, UsersView): resource_class = UserResource export_prefix = 'users-' - def get_resource(self): - '''Subclass default UserResource class to dynamically add field for extra attributes''' - attrs = collections.OrderedDict() - for attribute in Attribute.objects.all(): - attrs['attribute_%s' % attribute.name] = Field(attribute='attributes__%s' % attribute.name) - custom_class = type('UserResourceClass', (self.resource_class,), attrs) - return custom_class() - def get_queryset(self): '''Prefetch attribute values.''' qs = super(UsersExportView, self).get_queryset() return qs.prefetch_related('attribute_values', 'attribute_values__attribute') + @property + def csv(self): + return self._dataset.export('csv') + + def get_dataset(self): + user_resource = UserResource() + fields = user_resource._meta.export_order + ('email_verified', 'is_active', 'modified') + attributes = [attr.name for attr in Attribute.objects.all()] + headers = fields + tuple(['attribute_%s' % attr for attr in attributes]) + + def iso(rec): + if hasattr(rec, 'strftime'): + if isinstance(rec, datetime.datetime): + _format = "%Y-%m-%d %H:%M:%S" + else: + _format = "%Y-%m-%d" + return rec.strftime(_format) + return rec + + def create_record(user): + record = [] + for field in fields: + if field == 'roles': + value = user_resource.dehydrate_roles(user) + else: + value = getattr(user, field) + record.append(value) + + attr_d = user.attributes.values + for attr in attributes: + record.append(attr_d.get(attr, '')) + + return map(iso, record) + + self._dataset = tablib.Dataset(headers=headers) + for user in self.get_data(): + self._dataset.append(create_record(user)) + return self + + users_export = UsersExportView.as_view()