| 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 |  |  |  |