<commit_before>#
# CDR-Stats License
# http://www.cdr-stats.org
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (C) 2011-2012 Star2Billing S.L.
#
# The Initial Developer of the Original Code is
# <NAME> <<EMAIL>>
#
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import password_reset, \
                                    password_reset_done,\
                                    password_reset_confirm, \
                                    password_reset_complete
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render_to_response
from django.template.context import RequestContext
from django.utils.translation import gettext as _
from django.conf import settings
from django.views.decorators.cache import cache_page
from pymongo.connection import Connection
from pymongo.errors import ConnectionFailure
from common.common_functions import current_view, get_news, \
                                    variable_value, \
                                    source_desti_field_chk_mongodb, \
                                    duration_field_chk_mongodb, \
                                    int_convert_to_minute, \
                                    validate_days, \
                                    date_range

from cdr.models import Switch
from cdr.functions_def import get_country_name, \
                                chk_account_code, \
                                get_hangupcause_name
from cdr.forms import CdrSearchForm, \
                        CountryReportForm, \
                        CdrOverviewForm, \
                        CompareCallSearchForm, \
                        ConcurrentCallForm, \
                        SwitchForm, \
                        WorldForm, \
                        loginForm, \
                        EmailReportForm
from user_profile.models import UserProfile
from cdr.mapreduce import *
from bson.objectid import ObjectId
from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta
import math
import csv
import time
import logging


TOTAL_GRAPH_COLOR = '#A61700'
NUM_COUNTRY = 10
news_url = settings.NEWS_URL

cdr_data = settings.DBCON[settings.MG_CDR_COMMON]
#db.cdr.ensureIndex({"variables.answer_stamp":1}, {background:true});
(map, reduce, finalfc, out) = mapreduce_cdr_view()


def common_send_notification(request, status, recipient=None):
    """User Notification (e.g. limit) needs to be saved.
    It is a common function for the admin and customer UI's

    **Attributes**:

        * ``request`` - primary key of the record
        * ``status`` - get label for notifications
        * ``recipient`` - receiver of notification

    **Logic Description**:

        get the notice label from stauts & send notification with
        recipient, from_user & sender detail
    """
    if not recipient:
        recipient = request.user
        sender = User.objects.get(is_superuser=1, username=recipient)
    else:
        if request.user.is_anonymous():
            sender = User.objects.get(is_superuser=1, username=recipient)
        else:
            sender = request.user

    if notification:
        note_label = notification.NoticeType.objects.get(default=status)
        notification.send([recipient],
                          note_label.label,
                          {"from_user": request.user},
                          sender=sender)
    return True


def check_cdr_data_exists(request):
    doc = cdr_data.find_one()
    if not doc:
        return False
    else:
        return True


def login_view(request):
    """Login view

    **Attributes**:

        * ``template`` - cdr/index.html
        * ``form`` - loginForm
    """

    template = 'cdr/index.html'
    errorlogin = ''
    if request.method == 'POST':
        try:
            action = request.POST['action']
        except (KeyError):
            action = "login"

        if action == "logout":
            logout(request)
        else:
            loginform = loginForm(request.POST)
            if loginform.is_valid():
                cd = loginform.cleaned_data
                user = authenticate(
                            username=cd['user'],
                            password=cd['password'])
                if user is not None:
                    if user.is_active:
                        login(request, user)
                        # Redirect to a success page.
                    else:
                        # Return a 'disabled account' error message
                        errorlogin = _('Disabled Account')  # True
                else:
                    # Return an 'invalid login' error message.
                    errorlogin = _('Invalid Login.')  # True
            else:
                return HttpResponseRedirect('/')
    else:
        loginform = None

    data = {
        'loginform': loginform,
        'errorlogin': errorlogin,
        'news': get_news(news_url),
        'is_authenticated': request.user.is_authenticated()
    }
    return render_to_response(
                template,
                data,
                context_instance=RequestContext(request))


def logout_view(request):
    logout(request)
    return HttpResponseRedirect('/')


def cdr_view_daily_report(query_var):
    logging.debug('Map-reduce cdr analytic')
    #Retrieve Map Reduce
    (map, reduce, finalfc, out) = mapreduce_cdr_view()

    cdr_data = settings.DBCON[settings.MG_DAILY_ANALYTIC]
    logging.debug('Before MapReduce')
    total_data = cdr_data.map_reduce(map, reduce, out, query=query_var, finalize=finalfc)
    logging.debug('After MapReduce')

    total_data = total_data.find().sort([('_id.a_Year', -1),
                                         ('_id.b_Month', -1),
                                         ('_id.c_Day', -1)])

    detail_data = []
    total_duration = 0
    total_calls = 0
    duration__avg = 0.0
    for doc in total_data:
        detail_data.append(
            {
                'calldate': datetime(int(doc['_id']['a_Year']),
                int(doc['_id']['b_Month']), int(doc['_id']['c_Day'])),
                'duration__sum': int(doc['value']['duration__sum']),
                'calldate__count': int(doc['value']['calldate__count']),
                'duration__avg': doc['value']['duration__avg'],
            })

        total_duration += int(doc['value']['duration__sum'])
        total_calls += int(doc['value']['calldate__count'])
        duration__avg += float(doc['value']['duration__avg'])

    if total_data.count() != 0:
        max_duration = max([int(x['duration__sum']) for x in detail_data])
        total_avg_duration = \
            (float(duration__avg))/total_data.count()
    else:
        max_duration = 0
        total_avg_duration = 0

    cdr_view_daily_data = {
        'total_data': detail_data,
        'total_duration': total_duration,
        'total_calls': total_calls,
        'total_avg_duration': total_avg_duration,
        'max_duration': max_duration,
    }
    return cdr_view_daily_data


@login_required
def cdr_view(request):
    """List of CDRs

    **Attributes**:

        * ``template`` - cdr/cdr_view.html
        * ``form`` - CdrSearchForm
        * ``mongodb_data_set`` - MG_CDR_COMMON
        * ``map_reduce`` - mapreduce_cdr_view()

    **Logic Description**:

        get the call records as well as daily call analytics
        from mongodb collection according to search parameters
    """

    if not check_cdr_data_exists(request):
        return render_to_response(
                    'cdr/error_import.html',
                    context_instance=RequestContext(request))
    template_name = 'cdr/cdr_view.html'
    logging.debug('CDR View Start')
    query_var = {}
    result = 1  # default min
    switch_id = 0  # default all
    hangup_cause_id = 0  # default all
    destination = ''
    destination_type = ''
    dst = ''
    accountcode = ''
    accountcode_type = ''
    acc = ''
    direction = ''
    duration = ''
    duration_type = ''
    due = ''
    caller = ''
    caller_type = ''
    cli = ''
    search_tag = 0
    action = 'tabs-1'
    menu = 'on'
    cdr_view_daily_data = {}
    if request.method == 'POST':
        logging.debug('CDR Search View')
        search_tag = 1
        request.session['session_search_tag'] = search_tag
        form = CdrSearchForm(request.POST)
        if form.is_valid():
            # set session var value
            request.session['session_destination'] = ''
            request.session['session_result'] = ''
            request.session['session_destination_type'] = ''
            request.session['session_accountcode'] = ''
            request.session['session_accountcode_type'] = ''
            request.session['session_caller'] = ''
            request.session['session_caller_type'] = ''
            request.session['session_duration'] = ''
            request.session['session_duration_type'] = ''
            request.session['session_hangup_cause_id'] = ''
            request.session['session_switch_id'] = ''
            request.session['session_direction'] = ''
            request.session['session_country_id'] = ''
            request.session['session_cdr_view_daily_data'] = {}

            if "from_date" in request.POST:
                # From
                from_date = request.POST['from_date']
                start_date = datetime(int(from_date[0:4]),
                                      int(from_date[5:7]),
                                      int(from_date[8:10]), 0, 0, 0, 0)
                request.session['session_from_date'] = from_date

            if "to_date" in request.POST:
                # To
                to_date = request.POST['to_date']
                end_date = datetime(int(to_date[0:4]),
                                    int(to_date[5:7]),
                                    int(to_date[8:10]), 23, 59, 59, 999999)
                request.session['session_to_date'] = to_date

            result = request.POST['result']
            if result:
                request.session['session_result'] = int(result)

            destination = variable_value(request, 'destination')
            destination_type = variable_value(request, 'destination_type')
            if destination:
                request.session['session_destination'] = destination
                request.session['session_destination_type'] = destination_type

            accountcode = variable_value(request, 'accountcode')
            accountcode_type = variable_value(request, 'accountcode_type')
            if accountcode:
                request.session['session_accountcode'] = accountcode
                request.session['session_accountcode_type'] = accountcode_type

            caller = variable_value(request, 'caller')
            caller_type = variable_value(request, 'caller_type')
            if caller:
                request.session['session_caller'] = caller
                request.session['session_accountcode_type'] = caller_type

            duration = variable_value(request, 'duration')
            duration_type = variable_value(request, 'duration_type')
            if duration:
                request.session['session_duration'] = duration
                request.session['session_duration_type'] = duration_type

            direction = variable_value(request, 'direction')
            if direction and direction != 'all':
                request.session['session_direction'] = str(direction)

            switch_id = variable_value(request, 'switch')
            if switch_id:
                request.session['session_switch_id'] = switch_id

            hangup_cause_id = variable_value(request, 'hangup_cause')
            if hangup_cause_id:
                request.session['session_hangup_cause_id'] = hangup_cause_id

            records_per_page = variable_value(request, 'records_per_page')
            if records_per_page:
                request.session['session_records_per_page'] = records_per_page

            country_id = form.cleaned_data.get('country_id')
            # convert list value in int
            country_id = [int(row) for row in country_id]
            if len(country_id) >= 1:
                request.session['session_country_id'] = country_id
        else:
            # form is not valid
            logging.debug('Error : CDR search form')
            rows = []
            PAGE_SIZE = settings.PAGE_SIZE
            total_duration = 0
            total_calls = 0
            total_avg_duration = 0
            max_duration = 0
            col_name_with_order = []
            detail_data = []
            tday = datetime.today()
            start_date = tday.strftime('%Y-%m-01')
            last_day = ((datetime(tday.year, tday.month, 1, \
                            23, 59, 59, 999999) + relativedelta(months=1)) \
                            - relativedelta(days=1)).strftime('%d')
            end_date = tday.strftime('%Y-%m-' + last_day)
            template_data = {'module': current_view(request),
                             'rows': rows,
                             'form': form,
                             'PAGE_SIZE': PAGE_SIZE,
                             'total_data': detail_data,
                             'total_duration': total_duration,
                             'total_calls': total_calls,
                             'total_avg_duration': total_avg_duration,
                             'max_duration': max_duration,
                             'user': request.user,
                             'search_tag': search_tag,
                             'col_name_with_order': col_name_with_order,
                             'menu': menu,
                             'start_date': start_date,
                             'end_date': end_date,
                             'action': action,
                             'result': result,
                             }
            logging.debug('CDR View End')
            return render_to_response(template_name, template_data,
                context_instance=RequestContext(request))

    try:
        menu = request.GET.get('menu')
    except:
        menu = 'on'

    try:
        if request.GET.get('page') or request.GET.get('sort_by'):
            from_date = request.session.get('session_from_date')
            to_date = request.session.get('session_to_date')
            destination = request.session.get('session_destination')
            destination_type = request.session.get('session_destination_type')
            accountcode = request.session.get('session_accountcode')
            accountcode_type = request.session.get('session_accountcode_type')
            caller = request.session.get('session_caller')
            caller_type = request.session.get('session_caller_type')
            duration = request.session.get('session_duration')
            duration_type = request.session.get('session_duration_type')
            direction = request.session.get('session_direction')
            switch_id = request.session.get('session_switch_id')
            hangup_cause_id = request.session.get('session_hangup_cause_id')
            result = int(request.session.get('session_result'))
            search_tag = request.session.get('session_search_tag')
            records_per_page = request.session.get('session_records_per_page')
            country_id = request.session['session_country_id']
            cdr_view_daily_data = request.session.get(
                                            'session_cdr_view_daily_data')
        else:
            from_date
    except NameError:
        tday = datetime.today()
        from_date = tday.strftime('%Y-%m-01')
        last_day = ((datetime(tday.year, tday.month, 1, 23, 59, 59, 999999) + \
                    relativedelta(months=1)) - \
                    relativedelta(days=1)).strftime('%d')
        to_date = tday.strftime('%Y-%m-' + last_day)
        search_tag = 0
        country_id = ''
        records_per_page = settings.PAGE_SIZE
        # unset session var value
        request.session['session_result'] = 1
        request.session['session_from_date'] = from_date
        request.session['session_to_date'] = to_date
        request.session['session_destination'] = ''
        request.session['session_destination_type'] = ''
        request.session['session_accountcode'] = ''
        request.session['session_accountcode_type'] = ''
        request.session['session_caller'] = ''
        request.session['session_caller_type'] = ''
        request.session['session_duration'] = ''
        request.session['session_duration_type'] = ''
        request.session['session_hangup_cause_id'] = ''
        request.session['session_switch_id'] = ''
        request.session['session_direction'] = ''
        request.session['session_search_tag'] = search_tag
        request.session['session_records_per_page'] = records_per_page
        request.session['session_country_id'] = ''
        request.session['session_cdr_view_daily_data'] = {}

    start_date = datetime(int(from_date[0:4]), int(from_date[5:7]), \
                            int(from_date[8:10]), 0, 0, 0, 0)
    end_date = datetime(int(to_date[0:4]), int(to_date[5:7]), \
                            int(to_date[8:10]), 23, 59, 59, 999999)
    query_var['start_uepoch'] = {'$gte': start_date, '$lt': end_date}

    # Mapreduce query variable
    mr_query_var = {}
    mr_query_var['metadata.date'] = {'$gte': start_date, '$lt': end_date}

    dst = source_desti_field_chk_mongodb(destination, destination_type)
    if dst:
        query_var['destination_number'] = dst

    if request.user.is_superuser:  # superuser
        acc = source_desti_field_chk_mongodb(accountcode, accountcode_type)
        if acc:
            mr_query_var['metadata.accountcode'] = acc
            query_var['accountcode'] = acc

    if not request.user.is_superuser:  # not superuser
        if not chk_account_code(request):
            return HttpResponseRedirect('/?acc_code_error=true')
        else:
            query_var['accountcode'] = \
                mr_query_var['metadata.accountcode'] = \
                    chk_account_code(request)

    cli = source_desti_field_chk_mongodb(caller, caller_type)
    if cli:
        query_var['caller_id_number'] = cli

    due = duration_field_chk_mongodb(duration, duration_type)
    if due:
        query_var['duration'] = mr_query_var['duration_daily'] = due

    if switch_id and int(switch_id) != 0:
        mr_query_var['metadata.switch_id'] = int(switch_id)
        query_var['switch_id'] = int(switch_id)

    if hangup_cause_id and int(hangup_cause_id) != 0:
        query_var['hangup_cause_id'] = int(hangup_cause_id)

    if direction and direction != 'all':
        query_var['direction'] = str(direction)

    if len(country_id) >= 1 and country_id[0] != 0:
        mr_query_var['metadata.country_id'] = {'$in': country_id}
        query_var['country_id'] = {'$in': country_id}

    # Define no of records per page
    PAGE_SIZE = int(records_per_page)
    try:
        PAGE_NUMBER = int(request.GET['page'])
    except:
        PAGE_NUMBER = 1

    final_result = cdr_data.find(query_var, {
                                    "uuid": 0,
                                    "answer_uepoch": 0,
                                    "end_uepoch": 0,
                                    "mduration": 0,
                                    "billmsec": 0,
                                    "read_codec": 0,
                                    "write_codec": 0,
                                    "remote_media_ip": 0,
                                })

    form = CdrSearchForm(initial={
                            'from_date': from_date,
                            'to_date': to_date,
                            'destination': destination,
                            'destination_type': destination_type,
                            'accountcode': accountcode,
                            'accountcode_type': accountcode_type,
                            'caller': caller,
                            'caller_type': caller_type,
                            'duration': duration,
                            'duration_type': duration_type,
                            'result': result,
                            'direction': direction,
                            'hangup_cause': hangup_cause_id,
                            'switch': switch_id,
                            'country_id': country_id,
                            'records_per_page': records_per_page
                            })

    request.session['query_var'] = query_var

    col_name_with_order = {}
    sort_field = variable_value(request, 'sort_by')
    if not sort_field:
        sort_field = 'start_uepoch'  # default sort field
        default_order = -1  # desc
    else:
        if "-" in sort_field:
            default_order = -1
            sort_field = sort_field[1:]
            col_name_with_order[sort_field] = sort_field
        else:
            default_order = 1
            col_name_with_order[sort_field] = '-' + sort_field

    col_name_with_order['sort_field'] = sort_field

    logging.debug('Create cdr result')

    rows = \
        final_result.skip(PAGE_SIZE * (PAGE_NUMBER - 1)).limit(PAGE_SIZE)\
            .sort([(sort_field, default_order)])


    # Get daily report from session while using pagination & sorting
    if request.GET.get('page') or request.GET.get('sort_by'):
        cdr_view_daily_data = request.session['session_cdr_view_daily_data']
    else:
        # pass mapreduce query to cdr_view_daily_report
        cdr_view_daily_data = cdr_view_daily_report(mr_query_var)
        request.session['session_cdr_view_daily_data'] = cdr_view_daily_data

    template_data = {'module': current_view(request),
                     'rows': rows,
                     'form': form,
                     'PAGE_SIZE': PAGE_SIZE,
                     'total_data': cdr_view_daily_data['total_data'],
                     'total_duration': cdr_view_daily_data['total_duration'],
                     'total_calls': cdr_view_daily_data['total_calls'],
                     'total_avg_duration': cdr_view_daily_data['total_avg_duration'],
                     'max_duration': cdr_view_daily_data['max_duration'],
                     'user': request.user,
                     'search_tag': search_tag,
                     'col_name_with_order': col_name_with_order,
                     'menu': menu,
                     'start_date': start_date,
                     'end_date': end_date,
                     'action': action,
                     'result': int(result),
                     }
    logging.debug('CDR View End')
    return render_to_response(template_name, template_data,
                              context_instance=RequestContext(request))


@login_required
def cdr_export_to_csv(request):
    """
    **Logic Description**:

        get the call records  from mongodb collection
        according to search parameters & store into csv file
    """
    # get the response object, this can be used as a stream
    response = HttpResponse(mimetype='text/csv')
    # force download
    response['Content-Disposition'] = 'attachment;filename=export.csv'
    # the csv writer

    query_var = request.session['query_var']
    final_result = cdr_data.find(query_var,  {"uuid": 0,
                                              "answer_uepoch": 0,
                                              "end_uepoch": 0,
                                              "mduration": 0,
                                              "billmsec": 0,
                                              "read_codec": 0,
                                              "write_codec": 0,
                                              "remote_media_ip": 0
                                            })

    writer = csv.writer(response, dialect=csv.excel_tab)
    writer.writerow(['Call-date', 'CLID', 'Destination', 'Duration', \
                     'Bill sec', 'Hangup cause', 'AccountCode', 'Direction'])

    for cdr in final_result:
        writer.writerow([
                         cdr['start_uepoch'],
                         cdr['caller_id_number'] + '-' + cdr['caller_id_name'],
                         cdr['destination_number'],
                         cdr['duration'],
                         cdr['billsec'],
                         get_hangupcause_name(cdr['hangup_cause_id']),
                         cdr['accountcode'],
                         cdr['direction']
                       ])
    return response


@login_required
def cdr_detail(request, id, switch_id):
    """Detail of Call

    **Attributes**:

        * ``template`` - cdr/cdr_detail.html

    **Logic Description**:

        get the single call record in detail from mongodb collection
    """
    c_switch = Switch.objects.get(id=switch_id)
    ipaddress = c_switch.ipaddress
    try:
        menu = request.GET.get('menu')
    except:
        menu = 'on'

    if settings.LOCAL_SWITCH_TYPE == 'freeswitch':
        #Connect on MongoDB Database
        host = settings.MG_IMPORT[ipaddress]['host']
        port = settings.MG_IMPORT[ipaddress]['port']
        db_name = settings.MG_IMPORT[ipaddress]['db_name']
        try:
            connection = Connection(host, port)
            DBCON = connection[db_name]
        except ConnectionFailure:
            raise Http404

        doc = DBCON[settings.MG_IMPORT[ipaddress]['collection']].\
                    find({'_id': ObjectId(id)})
        return render_to_response(
                        'cdr/cdr_detail_freeswitch.html',
                        {'row': list(doc), 'menu': menu},
                        context_instance=RequestContext(request))

    elif settings.LOCAL_SWITCH_TYPE == 'asterisk':
        #Connect on Mysql Database
        #TODO support other DBMS
        import MySQLdb as Database
        db_name = settings.ASTERISK_MYSQL[ipaddress]['db_name']
        table_name = settings.ASTERISK_MYSQL[ipaddress]['table_name']
        user = settings.ASTERISK_MYSQL[ipaddress]['user']
        password = settings.ASTERISK_MYSQL[ipaddress]['password']
        host = settings.ASTERISK_MYSQL[ipaddress]['host']
        try:
            connection = Database.connect(user=user, passwd=password,
                                            db=db_name, host=host)
            cursor = connection.cursor()
        except:
            raise Http404

        cursor.execute("SELECT dst, UNIX_TIMESTAMP(calldate), clid, channel, "\
                        "duration, billsec, disposition, accountcode, " \
                        "uniqueid, %s FROM %s WHERE %s=%s" % \
                        (settings.ASTERISK_PRIMARY_KEY, table_name,
                        settings.ASTERISK_PRIMARY_KEY, id))
        row = cursor.fetchone()
        if not row:
            raise Http404

        return render_to_response(
                            'cdr/cdr_detail_asterisk.html',
                            {'row': list(row), 'menu': menu},
                            context_instance=RequestContext(request))


@login_required
def cdr_global_report(request):
    """CDR global report

    **Attributes**:

        * ``template`` - cdr/cdr_global_report.html
        * ``form`` - SwitchForm
        * ``mongodb_data_set`` - MG_CDR_COMMON
        * ``map_reduce`` - mapreduce_cdr_view()

    **Logic Description**:

        get all call records from mongodb collection to create
        global call report
    """

    if not check_cdr_data_exists(request):
        return render_to_response(
                    'cdr/error_import.html',
                    context_instance=RequestContext(request))

    logging.debug('CDR global report view start')
    query_var = {}
    total_data = []
    form = SwitchForm()
    switch_id = 0
    if request.method == 'POST':
        logging.debug('CDR global report with search options')
        form = SwitchForm(request.POST)
        if form.is_valid():
            switch_id = form.cleaned_data.get('switch')
            if switch_id and int(switch_id) != 0:
                query_var['switch_id'] = int(switch_id)

    if not request.user.is_superuser:  # not superuser
        if chk_account_code(request):
            query_var['accountcode'] = chk_account_code(request)
        else:
            return HttpResponseRedirect('/?acc_code_error=true')

    logging.debug('Map-reduce cdr global report analytic')
    #Retrieve Map Reduce
    (map, reduce, finalfc, out) = mapreduce_cdr_view()

    #Run Map Reduce
    cdr_data = settings.DBCON[settings.MG_DAILY_ANALYTIC]
    calls = cdr_data.map_reduce(map, reduce, out,
                            query=query_var, finalize=finalfc,)
    calls = calls.find().sort([('_id.a_Year', -1),
                        ('_id.b_Month', -1), ('_id.c_Day', -1)])

    if calls.count() != 0:
        maxtime = datetime(int(calls[0]['_id']['a_Year']),
                           int(calls[0]['_id']['b_Month']),
                           int(calls[0]['_id']['c_Day']), 0, 0, 0, 0)
        mintime = maxtime
        calls_dict = {}

        for d in calls:
            dtime = datetime(int(d['_id']['a_Year']),
                             int(d['_id']['b_Month']),
                             int(d['_id']['c_Day']), 0, 0, 0, 0)
            if dtime > maxtime:
                maxtime = dtime
            elif dtime < mintime:
                mintime = dtime
            calls_dict[int(dtime.strftime("%Y%m%d"))] = \
                    {'calldate__count': d['value']['calldate__count'],
                     'duration__sum': d['value']['duration__sum'],
                     'duration__avg': d['value']['duration__avg']}
        dateList = date_range(mintime, maxtime)

        i = 0
        for cdate in dateList:
            inttime = int(cdate.strftime("%Y%m%d"))
            name_date = _(cdate.strftime("%B")) + " " + \
                        str(cdate.day) + ", " + str(cdate.year)
            if inttime in calls_dict.keys():
                total_data.append({
                    'count': i,
                    'day': cdate.day,
                    'month': cdate.month,
                    'year': cdate.year,
                    'date': name_date,
                    'calldate__count': calls_dict[inttime]['calldate__count'],
                    'duration__sum': calls_dict[inttime]['duration__sum'],
                    'duration__avg': calls_dict[inttime]['duration__avg']})
            else:
                total_data.append({
                    'count': i,
                    'day': cdate.day,
                    'month': cdate.month,
                    'year': cdate.year,
                    'date': name_date,
                    'calldate__count': 0,
                    'duration__sum': 0,
                    'duration__avg': 0})
            i += 1

    # remove mapreduce output from database (no longer required)
    settings.DBCON[out].drop()

    logging.debug('CDR global report view end')
    template_data = {'module': current_view(request),
                     'total_data': total_data,
                     'form': form,
                    }
    return render_to_response('cdr/cdr_global_report.html', template_data,
                              context_instance=RequestContext(request))


@login_required
def cdr_dashboard(request):
    """CDR dashboard for a current day

    **Attributes**:

        * ``template`` - cdr/cdr_dashboard.html
        * ``form`` - SwitchForm
        * ``mongodb_data_set`` - MG_CDR_COMMON
        * ``map_reduce`` - mapreduce_cdr_dashboard()

    **Logic Description**:

        get all call records from mongodb collection for current day
        to create hourly report as well as hangup cause/country analytics
    """
    logging.debug('Debug Message')

    if not check_cdr_data_exists(request):
        return render_to_response(
                    'cdr/error_import.html',
                    context_instance=RequestContext(request))

    logging.debug('CDR dashboard view start')
    now = datetime.now()
    form = SwitchForm()
    switch_id = 0
    query_var = {}
    mr_query_var = {}
    search_tag = 0
    if request.method == 'POST':
        logging.debug('CDR dashboard view with search option')
        search_tag = 1
        form = SwitchForm(request.POST)
        if form.is_valid():
            switch_id = form.cleaned_data.get('switch')
            if switch_id and int(switch_id) != 0:
                query_var['switch_id'] = int(switch_id)

    #start_date = datetime(now.year, now.month, now.day, 0, 0, 0, 0)
    #end_date = datetime(now.year, now.month, now.day, 23, 59, 59, 999999)
    end_date = datetime(now.year, now.month, now.day,
                        now.hour, now.minute, now.second, now.microsecond)
    start_date = end_date + relativedelta(days=-int(1))

    query_var['start_uepoch'] = {'$gte': start_date, '$lt': end_date}

    mr_query_var['metadata.date'] = {'$gte': start_date, '$lt': end_date}

    if not request.user.is_superuser:  # not superuser
        if chk_account_code(request):
            query_var['accountcode'] = chk_account_code(request)
            mr_query_var['metadata.accountcode'] = query_var['accountcode']
        else:
            return HttpResponseRedirect('/?acc_code_error=true')

    logging.debug('Map-reduce cdr dashboard analytic')
    #Retrieve Map Reduce
    #(map, reduce, finalfc, out) = mapreduce_cdr_dashboard()
    (map, reduce, finalfc, out) = mapreduce_cdr_dashboard_daily()

    #Run Map Reduce
    daily_data = settings.DBCON[settings.MG_DAILY_ANALYTIC]

    logging.debug('Before MapReduce mapreduce_cdr_dashboard')
    calls = daily_data.map_reduce(map, reduce, out, query=query_var)
    print "======================"
    print daily_data
    print out
    print calls
    logging.debug('After MapReduce mapreduce_cdr_dashboard')
    calls = calls.find().sort([('_id.g_Millisec', 1),
                               ('value.hangup_cause_id', 1)])
    logging.debug('After calls.find')

    # if exists, drop previous collection
    settings.DBCON[settings.MG_CDR_HANGUP].drop()

    total_calls = 0
    total_duration = 0
    total_record_final = []
    hangup_analytic = dict()
    for d in calls:
        total_record_final.append([d['_id']['g_Millisec'],
                                   d['value']['calldate__count'],<commit_msg>drop non needed<commit_after>#
# CDR-Stats License
# http://www.cdr-stats.org
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright (C) 2011-2012 Star2Billing S.L.
#
# The Initial Developer of the Original Code is
# <NAME> <<EMAIL>>
#
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import password_reset, \
                                    password_reset_done,\
                                    password_reset_confirm, \
                                    password_reset_complete
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render_to_response
from django.template.context import RequestContext
from django.utils.translation import gettext as _
from django.conf import settings
from django.views.decorators.cache import cache_page
from pymongo.connection import Connection
from pymongo.errors import ConnectionFailure
from common.common_functions import current_view, get_news, \
                                    variable_value, \
                                    source_desti_field_chk_mongodb, \
                                    duration_field_chk_mongodb, \
                                    int_convert_to_minute, \
                                    validate_days, \
                                    date_range

from cdr.models import Switch
from cdr.functions_def import get_country_name, \
                                chk_account_code, \
                                get_hangupcause_name
from cdr.forms import CdrSearchForm, \
                        CountryReportForm, \
                        CdrOverviewForm, \
                        CompareCallSearchForm, \
                        ConcurrentCallForm, \
                        SwitchForm, \
                        WorldForm, \
                        loginForm, \
                        EmailReportForm
from user_profile.models import UserProfile
from cdr.mapreduce import *
from bson.objectid import ObjectId
from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta
import math
import csv
import time
import logging


TOTAL_GRAPH_COLOR = '#A61700'
NUM_COUNTRY = 10
news_url = settings.NEWS_URL

cdr_data = settings.DBCON[settings.MG_CDR_COMMON]
#db.cdr.ensureIndex({"variables.answer_stamp":1}, {background:true});
(map, reduce, finalfc, out) = mapreduce_cdr_view()


def common_send_notification(request, status, recipient=None):
    """User Notification (e.g. limit) needs to be saved.
    It is a common function for the admin and customer UI's

    **Attributes**:

        * ``request`` - primary key of the record
        * ``status`` - get label for notifications
        * ``recipient`` - receiver of notification

    **Logic Description**:

        get the notice label from stauts & send notification with
        recipient, from_user & sender detail
    """
    if not recipient:
        recipient = request.user
        sender = User.objects.get(is_superuser=1, username=recipient)
    else:
        if request.user.is_anonymous():
            sender = User.objects.get(is_superuser=1, username=recipient)
        else:
            sender = request.user

    if notification:
        note_label = notification.NoticeType.objects.get(default=status)
        notification.send([recipient],
                          note_label.label,
                          {"from_user": request.user},
                          sender=sender)
    return True


def check_cdr_data_exists(request):
    doc = cdr_data.find_one()
    if not doc:
        return False
    else:
        return True


def login_view(request):
    """Login view

    **Attributes**:

        * ``template`` - cdr/index.html
        * ``form`` - loginForm
    """

    template = 'cdr/index.html'
    errorlogin = ''
    if request.method == 'POST':
        try:
            action = request.POST['action']
        except (KeyError):
            action = "login"

        if action == "logout":
            logout(request)
        else:
            loginform = loginForm(request.POST)
            if loginform.is_valid():
                cd = loginform.cleaned_data
                user = authenticate(
                            username=cd['user'],
                            password=cd['password'])
                if user is not None:
                    if user.is_active:
                        login(request, user)
                        # Redirect to a success page.
                    else:
                        # Return a 'disabled account' error message
                        errorlogin = _('Disabled Account')  # True
                else:
                    # Return an 'invalid login' error message.
                    errorlogin = _('Invalid Login.')  # True
            else:
                return HttpResponseRedirect('/')
    else:
        loginform = None

    data = {
        'loginform': loginform,
        'errorlogin': errorlogin,
        'news': get_news(news_url),
        'is_authenticated': request.user.is_authenticated()
    }
    return render_to_response(
                template,
                data,
                context_instance=RequestContext(request))


def logout_view(request):
    logout(request)
    return HttpResponseRedirect('/')


def cdr_view_daily_report(query_var):
    logging.debug('Map-reduce cdr analytic')
    #Retrieve Map Reduce
    (map, reduce, finalfc, out) = mapreduce_cdr_view()

    cdr_data = settings.DBCON[settings.MG_DAILY_ANALYTIC]
    logging.debug('Before MapReduce')
    total_data = cdr_data.map_reduce(map, reduce, out, query=query_var, finalize=finalfc)
    logging.debug('After MapReduce')

    total_data = total_data.find().sort([('_id.a_Year', -1),
                                         ('_id.b_Month', -1),
                                         ('_id.c_Day', -1)])

    detail_data = []
    total_duration = 0
    total_calls = 0
    duration__avg = 0.0
    for doc in total_data:
        detail_data.append(
            {
                'calldate': datetime(int(doc['_id']['a_Year']),
                int(doc['_id']['b_Month']), int(doc['_id']['c_Day'])),
                'duration__sum': int(doc['value']['duration__sum']),
                'calldate__count': int(doc['value']['calldate__count']),
                'duration__avg': doc['value']['duration__avg'],
            })

        total_duration += int(doc['value']['duration__sum'])
        total_calls += int(doc['value']['calldate__count'])
        duration__avg += float(doc['value']['duration__avg'])

    if total_data.count() != 0:
        max_duration = max([int(x['duration__sum']) for x in detail_data])
        total_avg_duration = \
            (float(duration__avg))/total_data.count()
    else:
        max_duration = 0
        total_avg_duration = 0

    cdr_view_daily_data = {
        'total_data': detail_data,
        'total_duration': total_duration,
        'total_calls': total_calls,
        'total_avg_duration': total_avg_duration,
        'max_duration': max_duration,
    }
    return cdr_view_daily_data


@login_required
def cdr_view(request):
    """List of CDRs

    **Attributes**:

        * ``template`` - cdr/cdr_view.html
        * ``form`` - CdrSearchForm
        * ``mongodb_data_set`` - MG_CDR_COMMON
        * ``map_reduce`` - mapreduce_cdr_view()

    **Logic Description**:

        get the call records as well as daily call analytics
        from mongodb collection according to search parameters
    """

    if not check_cdr_data_exists(request):
        return render_to_response(
                    'cdr/error_import.html',
                    context_instance=RequestContext(request))
    template_name = 'cdr/cdr_view.html'
    logging.debug('CDR View Start')
    query_var = {}
    result = 1  # default min
    switch_id = 0  # default all
    hangup_cause_id = 0  # default all
    destination = ''
    destination_type = ''
    dst = ''
    accountcode = ''
    accountcode_type = ''
    acc = ''
    direction = ''
    duration = ''
    duration_type = ''
    due = ''
    caller = ''
    caller_type = ''
    cli = ''
    search_tag = 0
    action = 'tabs-1'
    menu = 'on'
    cdr_view_daily_data = {}
    if request.method == 'POST':
        logging.debug('CDR Search View')
        search_tag = 1
        request.session['session_search_tag'] = search_tag
        form = CdrSearchForm(request.POST)
        if form.is_valid():
            # set session var value
            request.session['session_destination'] = ''
            request.session['session_result'] = ''
            request.session['session_destination_type'] = ''
            request.session['session_accountcode'] = ''
            request.session['session_accountcode_type'] = ''
            request.session['session_caller'] = ''
            request.session['session_caller_type'] = ''
            request.session['session_duration'] = ''
            request.session['session_duration_type'] = ''
            request.session['session_hangup_cause_id'] = ''
            request.session['session_switch_id'] = ''
            request.session['session_direction'] = ''
            request.session['session_country_id'] = ''
            request.session['session_cdr_view_daily_data'] = {}

            if "from_date" in request.POST:
                # From
                from_date = request.POST['from_date']
                start_date = datetime(int(from_date[0:4]),
                                      int(from_date[5:7]),
                                      int(from_date[8:10]), 0, 0, 0, 0)
                request.session['session_from_date'] = from_date

            if "to_date" in request.POST:
                # To
                to_date = request.POST['to_date']
                end_date = datetime(int(to_date[0:4]),
                                    int(to_date[5:7]),
                                    int(to_date[8:10]), 23, 59, 59, 999999)
                request.session['session_to_date'] = to_date

            result = request.POST['result']
            if result:
                request.session['session_result'] = int(result)

            destination = variable_value(request, 'destination')
            destination_type = variable_value(request, 'destination_type')
            if destination:
                request.session['session_destination'] = destination
                request.session['session_destination_type'] = destination_type

            accountcode = variable_value(request, 'accountcode')
            accountcode_type = variable_value(request, 'accountcode_type')
            if accountcode:
                request.session['session_accountcode'] = accountcode
                request.session['session_accountcode_type'] = accountcode_type

            caller = variable_value(request, 'caller')
            caller_type = variable_value(request, 'caller_type')
            if caller:
                request.session['session_caller'] = caller
                request.session['session_accountcode_type'] = caller_type

            duration = variable_value(request, 'duration')
            duration_type = variable_value(request, 'duration_type')
            if duration:
                request.session['session_duration'] = duration
                request.session['session_duration_type'] = duration_type

            direction = variable_value(request, 'direction')
            if direction and direction != 'all':
                request.session['session_direction'] = str(direction)

            switch_id = variable_value(request, 'switch')
            if switch_id:
                request.session['session_switch_id'] = switch_id

            hangup_cause_id = variable_value(request, 'hangup_cause')
            if hangup_cause_id:
                request.session['session_hangup_cause_id'] = hangup_cause_id

            records_per_page = variable_value(request, 'records_per_page')
            if records_per_page:
                request.session['session_records_per_page'] = records_per_page

            country_id = form.cleaned_data.get('country_id')
            # convert list value in int
            country_id = [int(row) for row in country_id]
            if len(country_id) >= 1:
                request.session['session_country_id'] = country_id
        else:
            # form is not valid
            logging.debug('Error : CDR search form')
            rows = []
            PAGE_SIZE = settings.PAGE_SIZE
            total_duration = 0
            total_calls = 0
            total_avg_duration = 0
            max_duration = 0
            col_name_with_order = []
            detail_data = []
            tday = datetime.today()
            start_date = tday.strftime('%Y-%m-01')
            last_day = ((datetime(tday.year, tday.month, 1, \
                            23, 59, 59, 999999) + relativedelta(months=1)) \
                            - relativedelta(days=1)).strftime('%d')
            end_date = tday.strftime('%Y-%m-' + last_day)
            template_data = {'module': current_view(request),
                             'rows': rows,
                             'form': form,
                             'PAGE_SIZE': PAGE_SIZE,
                             'total_data': detail_data,
                             'total_duration': total_duration,
                             'total_calls': total_calls,
                             'total_avg_duration': total_avg_duration,
                             'max_duration': max_duration,
                             'user': request.user,
                             'search_tag': search_tag,
                             'col_name_with_order': col_name_with_order,
                             'menu': menu,
                             'start_date': start_date,
                             'end_date': end_date,
                             'action': action,
                             'result': result,
                             }
            logging.debug('CDR View End')
            return render_to_response(template_name, template_data,
                context_instance=RequestContext(request))

    try:
        menu = request.GET.get('menu')
    except:
        menu = 'on'

    try:
        if request.GET.get('page') or request.GET.get('sort_by'):
            from_date = request.session.get('session_from_date')
            to_date = request.session.get('session_to_date')
            destination = request.session.get('session_destination')
            destination_type = request.session.get('session_destination_type')
            accountcode = request.session.get('session_accountcode')
            accountcode_type = request.session.get('session_accountcode_type')
            caller = request.session.get('session_caller')
            caller_type = request.session.get('session_caller_type')
            duration = request.session.get('session_duration')
            duration_type = request.session.get('session_duration_type')
            direction = request.session.get('session_direction')
            switch_id = request.session.get('session_switch_id')
            hangup_cause_id = request.session.get('session_hangup_cause_id')
            result = int(request.session.get('session_result'))
            search_tag = request.session.get('session_search_tag')
            records_per_page = request.session.get('session_records_per_page')
            country_id = request.session['session_country_id']
            cdr_view_daily_data = request.session.get(
                                            'session_cdr_view_daily_data')
        else:
            from_date
    except NameError:
        tday = datetime.today()
        from_date = tday.strftime('%Y-%m-01')
        last_day = ((datetime(tday.year, tday.month, 1, 23, 59, 59, 999999) + \
                    relativedelta(months=1)) - \
                    relativedelta(days=1)).strftime('%d')
        to_date = tday.strftime('%Y-%m-' + last_day)
        search_tag = 0
        country_id = ''
        records_per_page = settings.PAGE_SIZE
        # unset session var value
        request.session['session_result'] = 1
        request.session['session_from_date'] = from_date
        request.session['session_to_date'] = to_date
        request.session['session_destination'] = ''
        request.session['session_destination_type'] = ''
        request.session['session_accountcode'] = ''
        request.session['session_accountcode_type'] = ''
        request.session['session_caller'] = ''
        request.session['session_caller_type'] = ''
        request.session['session_duration'] = ''
        request.session['session_duration_type'] = ''
        request.session['session_hangup_cause_id'] = ''
        request.session['session_switch_id'] = ''
        request.session['session_direction'] = ''
        request.session['session_search_tag'] = search_tag
        request.session['session_records_per_page'] = records_per_page
        request.session['session_country_id'] = ''
        request.session['session_cdr_view_daily_data'] = {}

    start_date = datetime(int(from_date[0:4]), int(from_date[5:7]), \
                            int(from_date[8:10]), 0, 0, 0, 0)
    end_date = datetime(int(to_date[0:4]), int(to_date[5:7]), \
                            int(to_date[8:10]), 23, 59, 59, 999999)
    query_var['start_uepoch'] = {'$gte': start_date, '$lt': end_date}

    # Mapreduce query variable
    mr_query_var = {}
    mr_query_var['metadata.date'] = {'$gte': start_date, '$lt': end_date}

    dst = source_desti_field_chk_mongodb(destination, destination_type)
    if dst:
        query_var['destination_number'] = dst

    if request.user.is_superuser:  # superuser
        acc = source_desti_field_chk_mongodb(accountcode, accountcode_type)
        if acc:
            mr_query_var['metadata.accountcode'] = acc
            query_var['accountcode'] = acc

    if not request.user.is_superuser:  # not superuser
        if not chk_account_code(request):
            return HttpResponseRedirect('/?acc_code_error=true')
        else:
            query_var['accountcode'] = \
                mr_query_var['metadata.accountcode'] = \
                    chk_account_code(request)

    cli = source_desti_field_chk_mongodb(caller, caller_type)
    if cli:
        query_var['caller_id_number'] = cli

    due = duration_field_chk_mongodb(duration, duration_type)
    if due:
        query_var['duration'] = mr_query_var['duration_daily'] = due

    if switch_id and int(switch_id) != 0:
        mr_query_var['metadata.switch_id'] = int(switch_id)
        query_var['switch_id'] = int(switch_id)

    if hangup_cause_id and int(hangup_cause_id) != 0:
        query_var['hangup_cause_id'] = int(hangup_cause_id)

    if direction and direction != 'all':
        query_var['direction'] = str(direction)

    if len(country_id) >= 1 and country_id[0] != 0:
        mr_query_var['metadata.country_id'] = {'$in': country_id}
        query_var['country_id'] = {'$in': country_id}

    # Define no of records per page
    PAGE_SIZE = int(records_per_page)
    try:
        PAGE_NUMBER = int(request.GET['page'])
    except:
        PAGE_NUMBER = 1

    final_result = cdr_data.find(query_var, {
                                    "uuid": 0,
                                    "answer_uepoch": 0,
                                    "end_uepoch": 0,
                                    "mduration": 0,
                                    "billmsec": 0,
                                    "read_codec": 0,
                                    "write_codec": 0,
                                    "remote_media_ip": 0,
                                })

    form = CdrSearchForm(initial={
                            'from_date': from_date,
                            'to_date': to_date,
                            'destination': destination,
                            'destination_type': destination_type,
                            'accountcode': accountcode,
                            'accountcode_type': accountcode_type,
                            'caller': caller,
                            'caller_type': caller_type,
                            'duration': duration,
                            'duration_type': duration_type,
                            'result': result,
                            'direction': direction,
                            'hangup_cause': hangup_cause_id,
                            'switch': switch_id,
                            'country_id': country_id,
                            'records_per_page': records_per_page
                            })

    request.session['query_var'] = query_var

    col_name_with_order = {}
    sort_field = variable_value(request, 'sort_by')
    if not sort_field:
        sort_field = 'start_uepoch'  # default sort field
        default_order = -1  # desc
    else:
        if "-" in sort_field:
            default_order = -1
            sort_field = sort_field[1:]
            col_name_with_order[sort_field] = sort_field
        else:
            default_order = 1
            col_name_with_order[sort_field] = '-' + sort_field

    col_name_with_order['sort_field'] = sort_field

    logging.debug('Create cdr result')

    rows = \
        final_result.skip(PAGE_SIZE * (PAGE_NUMBER - 1)).limit(PAGE_SIZE)\
            .sort([(sort_field, default_order)])


    # Get daily report from session while using pagination & sorting
    if request.GET.get('page') or request.GET.get('sort_by'):
        cdr_view_daily_data = request.session['session_cdr_view_daily_data']
    else:
        # pass mapreduce query to cdr_view_daily_report
        cdr_view_daily_data = cdr_view_daily_report(mr_query_var)
        request.session['session_cdr_view_daily_data'] = cdr_view_daily_data

    template_data = {'module': current_view(request),
                     'rows': rows,
                     'form': form,
                     'PAGE_SIZE': PAGE_SIZE,
                     'total_data': cdr_view_daily_data['total_data'],
                     'total_duration': cdr_view_daily_data['total_duration'],
                     'total_calls': cdr_view_daily_data['total_calls'],
                     'total_avg_duration': cdr_view_daily_data['total_avg_duration'],
                     'max_duration': cdr_view_daily_data['max_duration'],
                     'user': request.user,
                     'search_tag': search_tag,
                     'col_name_with_order': col_name_with_order,
                     'menu': menu,
                     'start_date': start_date,
                     'end_date': end_date,
                     'action': action,
                     'result': int(result),
                     }
    logging.debug('CDR View End')
    return render_to_response(template_name, template_data,
                              context_instance=RequestContext(request))


@login_required
def cdr_export_to_csv(request):
    """
    **Logic Description**:

        get the call records  from mongodb collection
        according to search parameters & store into csv file
    """
    # get the response object, this can be used as a stream
    response = HttpResponse(mimetype='text/csv')
    # force download
    response['Content-Disposition'] = 'attachment;filename=export.csv'
    # the csv writer

    query_var = request.session['query_var']
    final_result = cdr_data.find(query_var,  {"uuid": 0,
                                              "answer_uepoch": 0,
                                              "end_uepoch": 0,
                                              "mduration": 0,
                                              "billmsec": 0,
                                              "read_codec": 0,
                                              "write_codec": 0,
                                              "remote_media_ip": 0
                                            })

    writer = csv.writer(response, dialect=csv.excel_tab)
    writer.writerow(['Call-date', 'CLID', 'Destination', 'Duration', \
                     'Bill sec', 'Hangup cause', 'AccountCode', 'Direction'])

    for cdr in final_result:
        writer.writerow([
                         cdr['start_uepoch'],
                         cdr['caller_id_number'] + '-' + cdr['caller_id_name'],
                         cdr['destination_number'],
                         cdr['duration'],
                         cdr['billsec'],
                         get_hangupcause_name(cdr['hangup_cause_id']),
                         cdr['accountcode'],
                         cdr['direction']
                       ])
    return response


@login_required
def cdr_detail(request, id, switch_id):
    """Detail of Call

    **Attributes**:

        * ``template`` - cdr/cdr_detail.html

    **Logic Description**:

        get the single call record in detail from mongodb collection
    """
    c_switch = Switch.objects.get(id=switch_id)
    ipaddress = c_switch.ipaddress
    try:
        menu = request.GET.get('menu')
    except:
        menu = 'on'

    if settings.LOCAL_SWITCH_TYPE == 'freeswitch':
        #Connect on MongoDB Database
        host = settings.MG_IMPORT[ipaddress]['host']
        port = settings.MG_IMPORT[ipaddress]['port']
        db_name = settings.MG_IMPORT[ipaddress]['db_name']
        try:
            connection = Connection(host, port)
            DBCON = connection[db_name]
        except ConnectionFailure:
            raise Http404

        doc = DBCON[settings.MG_IMPORT[ipaddress]['collection']].\
                    find({'_id': ObjectId(id)})
        return render_to_response(
                        'cdr/cdr_detail_freeswitch.html',
                        {'row': list(doc), 'menu': menu},
                        context_instance=RequestContext(request))

    elif settings.LOCAL_SWITCH_TYPE == 'asterisk':
        #Connect on Mysql Database
        #TODO support other DBMS
        import MySQLdb as Database
        db_name = settings.ASTERISK_MYSQL[ipaddress]['db_name']
        table_name = settings.ASTERISK_MYSQL[ipaddress]['table_name']
        user = settings.ASTERISK_MYSQL[ipaddress]['user']
        password = settings.ASTERISK_MYSQL[ipaddress]['password']
        host = settings.ASTERISK_MYSQL[ipaddress]['host']
        try:
            connection = Database.connect(user=user, passwd=password,
                                            db=db_name, host=host)
            cursor = connection.cursor()
        except:
            raise Http404

        cursor.execute("SELECT dst, UNIX_TIMESTAMP(calldate), clid, channel, "\
                        "duration, billsec, disposition, accountcode, " \
                        "uniqueid, %s FROM %s WHERE %s=%s" % \
                        (settings.ASTERISK_PRIMARY_KEY, table_name,
                        settings.ASTERISK_PRIMARY_KEY, id))
        row = cursor.fetchone()
        if not row:
            raise Http404

        return render_to_response(
                            'cdr/cdr_detail_asterisk.html',
                            {'row': list(row), 'menu': menu},
                            context_instance=RequestContext(request))


@login_required
def cdr_global_report(request):
    """CDR global report

    **Attributes**:

        * ``template`` - cdr/cdr_global_report.html
        * ``form`` - SwitchForm
        * ``mongodb_data_set`` - MG_CDR_COMMON
        * ``map_reduce`` - mapreduce_cdr_view()

    **Logic Description**:

        get all call records from mongodb collection to create
        global call report
    """

    if not check_cdr_data_exists(request):
        return render_to_response(
                    'cdr/error_import.html',
                    context_instance=RequestContext(request))

    logging.debug('CDR global report view start')
    query_var = {}
    total_data = []
    form = SwitchForm()
    switch_id = 0
    if request.method == 'POST':
        logging.debug('CDR global report with search options')
        form = SwitchForm(request.POST)
        if form.is_valid():
            switch_id = form.cleaned_data.get('switch')
            if switch_id and int(switch_id) != 0:
                query_var['switch_id'] = int(switch_id)

    if not request.user.is_superuser:  # not superuser
        if chk_account_code(request):
            query_var['accountcode'] = chk_account_code(request)
        else:
            return HttpResponseRedirect('/?acc_code_error=true')

    logging.debug('Map-reduce cdr global report analytic')
    #Retrieve Map Reduce
    (map, reduce, finalfc, out) = mapreduce_cdr_view()

    #Run Map Reduce
    cdr_data = settings.DBCON[settings.MG_DAILY_ANALYTIC]
    calls = cdr_data.map_reduce(map, reduce, out,
                            query=query_var, finalize=finalfc,)
    calls = calls.find().sort([('_id.a_Year', -1),
                        ('_id.b_Month', -1), ('_id.c_Day', -1)])

    if calls.count() != 0:
        maxtime = datetime(int(calls[0]['_id']['a_Year']),
                           int(calls[0]['_id']['b_Month']),
                           int(calls[0]['_id']['c_Day']), 0, 0, 0, 0)
        mintime = maxtime
        calls_dict = {}

        for d in calls:
            dtime = datetime(int(d['_id']['a_Year']),
                             int(d['_id']['b_Month']),
                             int(d['_id']['c_Day']), 0, 0, 0, 0)
            if dtime > maxtime:
                maxtime = dtime
            elif dtime < mintime:
                mintime = dtime
            calls_dict[int(dtime.strftime("%Y%m%d"))] = \
                    {'calldate__count': d['value']['calldate__count'],
                     'duration__sum': d['value']['duration__sum'],
                     'duration__avg': d['value']['duration__avg']}
        dateList = date_range(mintime, maxtime)

        i = 0
        for cdate in dateList:
            inttime = int(cdate.strftime("%Y%m%d"))
            name_date = _(cdate.strftime("%B")) + " " + \
                        str(cdate.day) + ", " + str(cdate.year)
            if inttime in calls_dict.keys():
                total_data.append({
                    'count': i,
                    'day': cdate.day,
                    'month': cdate.month,
                    'year': cdate.year,
                    'date': name_date,
                    'calldate__count': calls_dict[inttime]['calldate__count'],
                    'duration__sum': calls_dict[inttime]['duration__sum'],
                    'duration__avg': calls_dict[inttime]['duration__avg']})
            else:
                total_data.append({
                    'count': i,
                    'day': cdate.day,
                    'month': cdate.month,
                    'year': cdate.year,
                    'date': name_date,
                    'calldate__count': 0,
                    'duration__sum': 0,
                    'duration__avg': 0})
            i += 1

    # remove mapreduce output from database (no longer required)
    settings.DBCON[out].drop()

    logging.debug('CDR global report view end')
    template_data = {'module': current_view(request),
                     'total_data': total_data,
                     'form': form,
                    }
    return render_to_response('cdr/cdr_global_report.html', template_data,
                              context_instance=RequestContext(request))


@login_required
def cdr_dashboard(request):
    """CDR dashboard for a current day

    **Attributes**:

        * ``template`` - cdr/cdr_dashboard.html
        * ``form`` - SwitchForm
        * ``mongodb_data_set`` - MG_CDR_COMMON
        * ``map_reduce`` - mapreduce_cdr_dashboard()

    **Logic Description**:

        get all call records from mongodb collection for current day
        to create hourly report as well as hangup cause/country analytics
    """
    logging.debug('Debug Message')

    if not check_cdr_data_exists(request):
        return render_to_response(
                    'cdr/error_import.html',
                    context_instance=RequestContext(request))

    logging.debug('CDR dashboard view start')
    now = datetime.now()
    form = SwitchForm()
    switch_id = 0
    query_var = {}
    mr_query_var = {}
    search_tag = 0
    if request.method == 'POST':
        logging.debug('CDR dashboard view with search option')
        search_tag = 1
        form = SwitchForm(request.POST)
        if form.is_valid():
            switch_id = form.cleaned_data.get('switch')
            if switch_id and int(switch_id) != 0:
                query_var['switch_id'] = int(switch_id)

    #start_date = datetime(now.year, now.month, now.day, 0, 0, 0, 0)
    #end_date = datetime(now.year, now.month, now.day, 23, 59, 59, 999999)
    end_date = datetime(now.year, now.month, now.day,
                        now.hour, now.minute, now.second, now.microsecond)
    start_date = end_date + relativedelta(days=-int(1))

    query_var['start_uepoch'] = {'$gte': start_date, '$lt': end_date}

    mr_query_var['metadata.date'] = {'$gte': start_date, '$lt': end_date}

    if not request.user.is_superuser:  # not superuser
        if chk_account_code(request):
            query_var['accountcode'] = chk_account_code(request)
            mr_query_var['metadata.accountcode'] = query_var['accountcode']
        else:
            return HttpResponseRedirect('/?acc_code_error=true')

    logging.debug('Map-reduce cdr dashboard analytic')
    #Retrieve Map Reduce
    #(map, reduce, finalfc, out) = mapreduce_cdr_dashboard()
    (map, reduce, finalfc, out) = mapreduce_cdr_dashboard_daily()

    #Run Map Reduce
    daily_data = settings.DBCON[settings.MG_DAILY_ANALYTIC]

    logging.debug('Before MapReduce mapreduce_cdr_dashboard')
    calls = daily_data.map_reduce(map, reduce, out, query=query_var)
    print "======================"
    print daily_data
    print out
    print calls
    logging.debug('After MapReduce mapreduce_cdr_dashboard')
    calls = calls.find().sort([('_id.g_Millisec', 1),
                               ('value.hangup_cause_id', 1)])
    logging.debug('After calls.find')

    total_calls = 0
    total_duration = 0
    total_record_final = []
    hangup_analytic = dict()
    for d in calls:
        total_record_final.append([d['_id']['g_Millisec'],
                                   d['value']['calldate__count'],
{'fraction_non_alphanumeric': 0.10660762451499373, 'fraction_numerical': 0.006519638246621183, 'mean_word_length': 1.858497567411561, 'pattern_counts': {'":': 38, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 98, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7020544', 'n_tokens_mistral': 19899, 'n_tokens_neox': 18928, 'n_words': 3701}