def get_newsletter_statistics(newsletter, mailing_list_pk=None):
    """Return the statistics of a newsletter"""
    recipients_list = get_recipients_list(newsletter, mailing_list_pk)
    recipients = recipients_list.count()
    
    newsletter_status = Status.objects.filter(newsletter=newsletter)
    recipients_status = newsletter_status.filter(creation_date__gte=newsletter.sending_date, contact__in=recipients_list)    
    mails_sent = recipients_status.filter(status=Status.SENT).count()
    if mails_sent > recipients:
        recipients = mails_sent
    remaining_mails = recipients - mails_sent

    statistics = {'tests_sent': newsletter_status.filter(status=Status.SENT_TEST).count(),
                  'mails_sent': mails_sent,
                  'mails_to_send': recipients,
                  'remaining_mails': recipients - mails_sent}

    statistics.update(get_newsletter_opening_statistics(recipients_status, recipients))
    statistics.update(get_newsletter_on_site_opening_statistics(recipients_status))
    statistics.update(get_newsletter_unsubscription_statistics(recipients_status, recipients))
    statistics.update(get_newsletter_clicked_link_statistics(recipients_status, recipients,
                                                             statistics['total_openings']))
    statistics.update(get_newsletter_top_links(recipients_status))

    return statistics
def view_newsletter_report(request, slug, mailing_list_pk=None):
    newsletter = get_object_or_404(Newsletter, slug=slug)
    recipients_list = get_recipients_list(newsletter, mailing_list_pk)
    status = ContactMailingStatus.objects.filter(newsletter=newsletter,
                                                 creation_date__gte=newsletter.sending_date,
                                                 contact__in=recipients_list)
    links = set([s.link for s in status.exclude(link=None)])

    def header_line(links):
        link_cols = [link.title for link in links]
        return [smart_str(_('first name')), smart_str(_('last name')),
                smart_str(_('email')), smart_str(_('openings'))] + link_cols

    def contact_line(contact, links):
        contact_status = status.filter(contact=contact)

        link_cols = [contact_status.filter(status=ContactMailingStatus.LINK_OPENED,
                                           link=link).count() for link in links]
        openings = contact_status.filter(Q(status=ContactMailingStatus.OPENED) |
                                         Q(status=ContactMailingStatus.OPENED_ON_SITE)).count()
        return [smart_str(contact.first_name), smart_str(contact.last_name),
                smart_str(contact.email), openings] + link_cols

    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=report-%s.csv' % newsletter.slug

    writer = csv.writer(response)
    writer.writerow(header_line(links))
    for contact in recipients_list:
        writer.writerow(contact_line(contact, links))

    return response
def view_newsletter_density(request, slug, mailing_list_pk=None):
    newsletter = get_object_or_404(Newsletter, slug=slug)
    recipients_list = get_recipients_list(newsletter, mailing_list_pk)
    status = ContactMailingStatus.objects.filter(newsletter=newsletter,
                                                 creation_date__gte=newsletter.sending_date,
                                                 contact__in=recipients_list)
    context = {'object': newsletter,
               'top_links': get_newsletter_top_links(status)['top_links']}

    return render_to_response('newsletter/newsletter_density.html',
                              context, context_instance=RequestContext(request))
def view_newsletter_charts(request, slug, mailing_list_pk=None):
    newsletter = get_object_or_404(Newsletter, slug=slug)

    start = int(request.POST.get('start', 0))
    end = int(request.POST.get('end', 6))

    recipients_list = get_recipients_list(newsletter, mailing_list_pk)
    recipients = len(recipients_list)

    sending_date = newsletter.sending_date.date()
    labels, clicks_by_day, openings_by_day = [], [], []

    for i in range(start, end + 1):
        day = sending_date + timedelta(days=i)
        day_status = ContactMailingStatus.objects.filter(newsletter=newsletter,
                                                         creation_date__day=day.day,
                                                         creation_date__month=day.month,
                                                         creation_date__year=day.year,
                                                         contact__in=recipients_list)

        opening_stats = get_newsletter_opening_statistics(day_status, recipients)
        click_stats = get_newsletter_clicked_link_statistics(day_status, recipients, 0)
        # Labels
        labels.append(date(day, 'D d M y').capitalize())
        # Values
        openings_by_day.append(opening_stats['total_openings'])
        clicks_by_day.append(click_stats['total_clicked_links'])


    b1 = Chart(type='bar_3d', colour=BAR_COLOR_1,
               text=_('Total openings'), tip=_('#val# openings'),
               on_show={'type': 'grow-up'}, values=openings_by_day)

    b2 = Chart(type='bar_3d', colour=BAR_COLOR_2,
               text=_('Total clicked links'), tip=_('#val# clicks'),
               on_show={'type': 'grow-up'}, values=clicks_by_day)

    chart = Chart(bg_colour=BG_COLOR)
    chart.title.text = _('Consultation histogram')
    chart.title.style = '{font-size: 16px; color: #666666; text-align: center; font-weight: bold;}'

    chart.y_axis = {'colour': AXIS_COLOR, 'grid-colour': GRID_COLOR,
                    'min': 0, 'max': max(openings_by_day + clicks_by_day) + 2,
                    'steps': max(openings_by_day) / 5}
    chart.x_axis = {'colour': AXIS_COLOR, 'grid-colour': GRID_COLOR,
                    '3d': 5, 'labels': {'labels': labels, 'rotate': 60}}
    chart.elements = [b1, b2]

    return HttpResponse(chart.render())