File: export_emails.py

package info (click to toggle)
python-django-extensions 1.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 2,016 kB
  • ctags: 1,342
  • sloc: python: 8,873; makefile: 117
file content (136 lines) | stat: -rw-r--r-- 5,297 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# -*- coding: utf-8 -*-
from csv import writer
from sys import stdout

import six
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.core.management.base import BaseCommand, CommandError

from django_extensions.management.utils import signalcommand

FORMATS = [
    'address',
    'emails',
    'google',
    'outlook',
    'linkedin',
    'vcard',
]


def full_name(first_name, last_name, username, **extra):
    name = six.u(" ").join(n for n in [first_name, last_name] if n)
    if not name:
        return username
    return name


class Command(BaseCommand):
    help = "Export user email address list in one of a number of formats."
    args = "[output file]"
    label = 'filename to save to'

    can_import_settings = True
    encoding = 'utf-8'  # RED_FLAG: add as an option -DougN

    def add_arguments(self, parser):
        super(Command, self).add_arguments(parser)
        parser.add_argument(
            '--group', '-g', action='store', dest='group', default=None,
            help='Limit to users which are part of the supplied group name'),
        parser.add_argument(
            '--format', '-f', action='store', dest='format', default=FORMATS[0],
            help="output format. May be one of '" + "', '".join(FORMATS) +
            "'."),

    @signalcommand
    def handle(self, *args, **options):
        if len(args) > 1:
            raise CommandError("extra arguments supplied")
        group = options['group']
        if group and not Group.objects.filter(name=group).count() == 1:
            names = six.u("', '").join(g['name'] for g in Group.objects.values('name')).encode('utf-8')
            if names:
                names = "'" + names + "'."
            raise CommandError("Unknown group '" + group + "'. Valid group names are: " + names)
        if len(args) and args[0] != '-':
            outfile = open(args[0], 'w')
        else:
            outfile = stdout

        User = get_user_model()
        qs = User.objects.all().order_by('last_name', 'first_name', 'username', 'email')
        if group:
            qs = qs.filter(groups__name=group).distinct()
        qs = qs.values('last_name', 'first_name', 'username', 'email')
        getattr(self, options['format'])(qs, outfile)

    def address(self, qs, out):
        """simple single entry per line in the format of:
            "full name" <my@address.com>;
        """
        out.write(six.u("\n").join('"%s" <%s>;' % (full_name(**ent), ent['email'])
                                   for ent in qs).encode(self.encoding))
        out.write("\n")

    def emails(self, qs, out):
        """simpler single entry with email only in the format of:
            my@address.com,
        """
        out.write(six.u(",\n").join(ent['email'] for ent in qs).encode(self.encoding))
        out.write("\n")

    def google(self, qs, out):
        """CSV format suitable for importing into google GMail
        """
        csvf = writer(out)
        csvf.writerow(['Name', 'Email'])
        for ent in qs:
            csvf.writerow([full_name(**ent).encode(self.encoding),
                           ent['email'].encode(self.encoding)])

    def outlook(self, qs, out):
        """CSV format suitable for importing into outlook
        """
        csvf = writer(out)
        columns = ['Name', 'E-mail Address', 'Notes', 'E-mail 2 Address', 'E-mail 3 Address',
                   'Mobile Phone', 'Pager', 'Company', 'Job Title', 'Home Phone', 'Home Phone 2',
                   'Home Fax', 'Home Address', 'Business Phone', 'Business Phone 2',
                   'Business Fax', 'Business Address', 'Other Phone', 'Other Fax', 'Other Address']
        csvf.writerow(columns)
        empty = [''] * (len(columns) - 2)
        for ent in qs:
            csvf.writerow([full_name(**ent).encode(self.encoding),
                           ent['email'].encode(self.encoding)] + empty)

    def linkedin(self, qs, out):
        """CSV format suitable for importing into linkedin Groups.
        perfect for pre-approving members of a linkedin group.
        """
        csvf = writer(out)
        csvf.writerow(['First Name', 'Last Name', 'Email'])
        for ent in qs:
            csvf.writerow([ent['first_name'].encode(self.encoding),
                           ent['last_name'].encode(self.encoding),
                           ent['email'].encode(self.encoding)])

    def vcard(self, qs, out):
        try:
            import vobject
        except ImportError:
            print(self.style.ERROR("Please install python-vobject to use the vcard export format."))
            import sys
            sys.exit(1)
        for ent in qs:
            card = vobject.vCard()
            card.add('fn').value = full_name(**ent)
            if not ent['last_name'] and not ent['first_name']:
                # fallback to fullname, if both first and lastname are not declared
                card.add('n').value = vobject.vcard.Name(full_name(**ent))
            else:
                card.add('n').value = vobject.vcard.Name(ent['last_name'], ent['first_name'])
            emailpart = card.add('email')
            emailpart.value = ent['email']
            emailpart.type_param = 'INTERNET'
            out.write(card.serialize().encode(self.encoding))