Command.handle()   F
last analyzed

Complexity

Conditions 15

Size

Total Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 74
rs 2.3086
cc 15

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like Command.handle() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# Guillaume Genty, Waycom
2
# Dec. 2017
3
4
from django.core.management.base import BaseCommand, CommandError
5
from django.conf import settings
6
from pyfreebilling.cdr.models import CDR, Company, RateCard
7
from datetime import date, time, timedelta, datetime
8
import calendar
9
from django.db import connection
10
from django.utils import timezone
11
from pprint import pprint
12
from dateutil.tz import tzlocal
13
from StringIO import StringIO
14
import csv
15
from django.core.mail import EmailMessage, mail_admins
16
17
TODAY = date.today()
18
MIDNIGHT = datetime.combine(TODAY, time.min)
19
20
CDR_PERIODS = {
21
    'cdr_day': (MIDNIGHT - timedelta(days=1), MIDNIGHT),
22
    'cdr_week': (MIDNIGHT - timedelta(days=TODAY.weekday()+7), MIDNIGHT - timedelta(days=TODAY.weekday())),
23
    'cdr_month': (datetime.combine((TODAY.replace(day=1)-timedelta(days=1)).replace(day=1), time.min), MIDNIGHT - timedelta(days=TODAY.day-1))
24
}
25
#print CDR_PERIODS
26
27
class Command(BaseCommand):
28
    help = 'Send all CDR exports by email.'
29
    
30
    def add_arguments(self, parser):
31
        parser.add_argument('period', nargs=1, type=str, choices=CDR_PERIODS.keys()+['all'])
32
33
    def handle(self, *args, **options):
34
35
        tz = tzlocal()
36
        wantperiod = options['period'][0]
37
        
38
        rc_didin = [x.id for x in RateCard.objects.all().filter(rctype='DIDIN')]
39
        rc_emerg = [x.id for x in RateCard.objects.all().filter(rctype='EMERGENCY')]
40
        
41
        customers = Company.objects.all().filter(customer_enabled=True)
42
        for cust in customers:
43
44
            emails = cust.email_address.all().filter(location__startswith='cdr_')
45
            if not emails:
46
                continue
47
            
48
            targets = {}
49
            for e in emails:
50
                if not e.location in targets:
51
                    targets[e.location] = []
52
                targets[e.location].append(e.email_address)
53
            
54
            for period in CDR_PERIODS:
55
                if wantperiod != 'all' and period != wantperiod:
56
                    continue
57
                if not period in targets:
58
                    continue
59
                #print CDR_PERIODS[period]
60
                try:
61
                    p_start = CDR_PERIODS[period][0].replace(tzinfo=tz)
62
                    p_end = CDR_PERIODS[period][1].replace(tzinfo=tz)
63
                    #p_end = datetime.now().replace(tzinfo=tz) # DEBUG
64
                    list = CDR.objects.all().filter(end_stamp__gte=p_start, end_stamp__lt=p_end, customer_id=cust.id, billsec__gt=0)
65
                    csvfile = StringIO()
66
                    csvwriter = csv.writer(csvfile)
67
                    csvwriter.writerow(['direction', 'start', 'end', 'billed_sec', 'from', 'to', 'ip', 'destination', 'price', 'uuid'])
68
                    for l in list:
69
                        if l.ratecard_id_id in rc_emerg:
70
                            continue
71
                        if l.ratecard_id_id in rc_didin:
72
                            csvwriter.writerow(['IN',
73
                                                timezone.localtime(l.start_stamp),
74
                                                timezone.localtime(l.end_stamp),
75
                                                l.billsec,
76
                                                l.caller_id_number.lstrip("+"),
77
                                                l.destination_number.lstrip("+"),
78
                                                None,
79
                                                l.sell_destination.encode('ascii',errors='ignore'),
80
                                                l.total_sell,
81
                                                l.bleg_uuid
82
                                              ])
83
                        else:
84
                            csvwriter.writerow(['OUT',
85
                                                timezone.localtime(l.start_stamp),
86
                                                timezone.localtime(l.end_stamp),
87
                                                l.billsec,
88
                                                l.caller_id_number.lstrip("+"),
89
                                                l.destination_number.lstrip("+"),
90
                                                l.customer_ip,
91
                                                l.sell_destination.encode('ascii',errors='ignore'),
92
                                                l.total_sell,
93
                                                l.uuid
94
                                              ])
95
96
                    message = EmailMessage("%s - CDR for customer %s"%(settings.EMAIL_SIGNATURE, cust.name),
97
                                           "Extract of call data records from %s to %s.\nCSV file attached."%(timezone.localtime(p_start), timezone.localtime(p_end)),
98
                                           None,
99
                                           targets[period])
100
                    message.attach('%s-%s-%s.csv'%(period.replace('_','-'), cust.slug, p_start.strftime('%Y%m%d')), csvfile.getvalue(), 'text/csv')
101
                    message.send()
102
                    self.stdout.write('CDRs for %s sent to %s'%(cust.name, ', '.join(targets[period])))
103
                except Exception, e:
104
                    self.stderr.write(str(e))
105
106
        self.stdout.write('OK')
107
        
108
        #pprint(connection.queries)
109
110