Example #1
0
def gchart(data,
           node,
           check,
           metric,
           start=datetime.now() - timedelta(days=1),
           end=datetime.now()):
    d = []
    ts = []
    for p in data['metrics'][0]['data']:
        d.append(float(p['avg']))
        ts.append(p['ts'])

    # Chart size of 200x125 pixels and specifying the range for the Y axis
    max_y = int(max(d))
    chart = SimpleLineChart(450, 250, y_range=[0, max_y])
    chart.add_data(d)
    left_axis = range(0, max_y + 1, max_y / 5)
    left_axis[0] = ''
    chart.set_axis_labels(Axis.LEFT, left_axis)
    min_dt = datetime.fromtimestamp(min(ts))
    max_dt = datetime.fromtimestamp(max(ts))
    chart.set_axis_labels(Axis.BOTTOM, [str(min_dt), str(max_dt)])
    title = '%s.%s.%s' % (node['name'], check['type'], metric)
    chart.set_title(title)
    return chart.get_url()
Example #2
0
class DiceChart:
    chart = None

    def __init__(self, data, iter=0, width=300, height=300):
        self.chart = SimpleLineChart(width, height, y_range=(0, 10))
        legend = []
        colors = ["cc0000", "00cc00", "0000cc", "990000", "009900", "000099", "0099ff", "FF9900", "9900ff", "ff0099"]
        title = "die rolls per objective"
        if iter > 0:
            title = title + " (%s samples)" % iter
        for i in data.keys():
            self.chart.add_data(data[i])
            legend.append(str(i))

        logging.debug(legend)
        logging.debug(colors)
        self.chart.set_colours(colors)
        self.chart.set_legend(legend)

        grid_x_amount = 100 / (len(data[i]) - 1)
        self.chart.set_grid(grid_x_amount, 10, 5, 5)

        left_axis = range(0, 11, 1)
        left_axis[0] = ""
        self.chart.set_axis_labels(Axis.LEFT, left_axis)

        bottom_len = len(data[i]) + 2
        bottom_axis = range(2, bottom_len, 1)
        self.chart.set_axis_labels(Axis.BOTTOM, bottom_axis)

        self.chart.set_title(title)

    def download(self, name="dicechart.png"):
        self.chart.download(name)
Example #3
0
def getRollingAverageGraph(cursor, colName, rollingWindowDays, title=""):
    sqlCMD = "SELECT pDate, %s from %s" %(colName, N.JOBS_SUMMARY_TABLENAME)
    cursor.execute(sqlCMD)
    results = cursor.fetchall()
    beginWindowIndex = 0
    endWindowIndex = 0
    xData = []
    yData = []
    while endWindowIndex < len(results):
        while endWindowIndex < len(results) and (results[endWindowIndex][0] - results[beginWindowIndex][0]).days <= rollingWindowDays:
            endWindowIndex += 1
        yData.append( sum(results[i][1] for i in xrange(beginWindowIndex, endWindowIndex, 1)) / float(endWindowIndex - beginWindowIndex))
        xData.append(results[endWindowIndex-1][0])
        beginWindowIndex = endWindowIndex
    chart = SimpleLineChart(680, 400, y_range = (min(yData)-1, max(yData)+1))
    chart.add_data(yData)
    
    yLabels = range(0, int(max(yData)+1), 5)
    yLabels[0] = ''
    xLabels = [str(xData[-i]) for i in xrange(1, len(xData)-1, int(0.2*len(xData)))]
    xLabels.reverse()
    chart.set_axis_labels(Axis.LEFT, yLabels)
    chart.set_axis_labels(Axis.BOTTOM, xLabels)
    chart.set_title("Rolling %i-Day Average %s" % (rollingWindowDays, title))
    imgbin = chart.download()
    toReturn = cStringIO.StringIO(imgbin)
    toReturn.seek(0)
    return chart.get_url(), toReturn
Example #4
0
def simple_line():
    chart = SimpleLineChart(settings.width, settings.height,
                                      x_range=(0, 35))
    chart.set_colours(['00ff00', 'ff0000','ACff0C','B0ffE0','C0ffFF'])
    chart.add_data([1,2,3,4,5])
    chart.add_data([1,4,9,16,25])
    chart.set_title('This is title')
    chart.set_axis_labels('r', 'str')
    chart.set_legend( ['a','b','c','d','e'])
    chart.download('simple-line.png')
Example #5
0
def lineGraphFeed(feed):
    name = feed.getAttribute("name")
    observations = feed.getElementsByTagName("observation")
    print "  Feed %s has %d observations" % (name,len(observations))
    data = []
    for obs in observations:
        value = int(obs.getAttribute("value"))
        #print "   val:%s (%s)" % (value, type(value))
        data.insert(0,value/10)

    #data.reverse  # remeber the feed is reversed
    print "Max Data: %s" % max(data)

    max_y = int(math.ceil(max(data)/100.0))*100
    print "Max_y : %s" % max_y
    chart = SimpleLineChart(180, 120, y_range=[0, max_y])
    chart.add_data(data)

    lftAxisMax = max_y/100;
    print "lftAxisMax %s"%lftAxisMax
    #left_axis = range(0, lftAxisMax,(lftAxisMax/4.0))
    left_axis = []
    right_axis = []
    for i in range(0,4+1):
        kw = (i*lftAxisMax/4.0)
        left_axis.append(kw)
        right_axis.append(kw*24)

    left_axis[0] = 'kW' # remove the first label
    right_axis[0] = 'kWh/d' # remove the first label
    chart.set_axis_labels(Axis.LEFT, left_axis)
    #chart.set_axis_labels(Axis.RIGHT, right_axis)

    chart.set_title(name)

    # facebook colors
    chart.set_title_style('7f93bc',16)
    #chart.set_colours(['7f93bc'])
    chart.set_colours(['3b5998']) #darker blue

    #Colors
    colors=False
    if (colors):
        # Set the line colour to ...
        chart.set_colours(['FFFFFF'])
        # 0 here is the axis index ? 0 works for now
        chart.set_title_style('FFFFFF',16)
        chart.set_axis_style(0,'FFFFFF')
        chart.set_axis_style(1,'FFFFFF')
        chart.fill_linear_gradient(Chart.BACKGROUND,90,'000000',0.9,'007700',0.1)


    print chart.get_url()
    chart.download('%s-line.png'%name)
Example #6
0
    def printGoogleCharts(X, Y, title, min_y, max_y, output):

        # Create a chart object of 750x400 pixels
        chart = SimpleLineChart(750, 400)

        # Add some data
        chart.add_data(Y)

        # Assign the labels to the pie data
#        chart.set_axis_labels(Axis.BOTTOM, X)
        chart.set_axis_labels(Axis.LEFT, range(int(min_y)-1, int(max_y)+1, 5))
        chart.set_title(title)

        # Print the chart URL
        print chart.get_url()

        # Download the chart
        chart.download(output+".png")
Example #7
0
def gchart(data, node, check, metric, start=datetime.now()-timedelta(days=1), end=datetime.now()):
  d = []
  ts = []
  for p in  data['metrics'][0]['data']:
    d.append(float(p['avg']))
    ts.append(p['ts'])

  # Chart size of 200x125 pixels and specifying the range for the Y axis
  max_y = int(max(d))
  chart = SimpleLineChart(450, 250, y_range=[0,max_y])
  chart.add_data(d)
  left_axis = range(0, max_y + 1, max_y/5)
  left_axis[0] = ''
  chart.set_axis_labels(Axis.LEFT, left_axis)
  min_dt = datetime.fromtimestamp(min(ts))
  max_dt = datetime.fromtimestamp(max(ts))
  chart.set_axis_labels(Axis.BOTTOM, [ str(min_dt), str(max_dt) ])
  title = '%s.%s.%s' % (node['name'], check['type'], metric)
  chart.set_title(title)
  return chart.get_url()
Example #8
0
def users(*args):
    days = 60
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute(
        "SELECT date_joined, COUNT(*) from auth_user where date_joined > NOW() - INTERVAL %i DAY group by DATE(date_joined) order by DATE(date_joined) desc"
        % days)

    data = {}
    max_y = 0
    for dt, num in cursor.fetchall():
        if num > max_y:
            max_y = num
        data[dt.date()] = num

    data2 = []

    dt = date.today() - timedelta(days - 1)
    for i in xrange(days):
        data2.append((dt, data.get(dt, 0)))
        dt = dt + timedelta(1)

    chart = SimpleLineChart(800, 125, y_range=[0, max_y])
    chart.add_data([row[1] for row in data2])
    chart.set_colours(['0000FF'])

    ticks = (max_y % 25) + 1

    left_axis = range(0, max_y, 25)
    left_axis[0] = ''
    chart.set_axis_labels(Axis.RIGHT, left_axis)

    bottom_axis = [
        dt[0].strftime("%b") if dt[0].day == 1 else '' for dt in data2
    ]
    chart.set_axis_labels(Axis.BOTTOM, bottom_axis)

    chart.set_title("Daily Registrations")

    data2.reverse()
    return chart
Example #9
0
        def linegraph(self,days,bars,output,title = ""):
                data = []
                min_count = 0
                max_count = 0
                date = lambda i:datetime.date.today() + datetime.timedelta(-days + i)

                for i in range(0,days+1):
                        count = bars[date(i)]
                        max_count = max(count,max_count)
                        min_count = min(count,min_count)
                        data.append(count)
                chart = SimpleLineChart(800,350,y_range=[min_count, 60000])
                chart.add_data(data)
                # Set the line colour to blue
                chart.set_colours(['0000FF'])

                # Set the vertical stripes
                d = max(1/float(days),round(7/float(days),2))
                chart.fill_linear_stripes(Chart.CHART, 0, 'CCCCCC', d, 'FFFFFF', d)

                fmt="%d/%m"
                chart.set_axis_labels(Axis.BOTTOM, \
                                      [date(i).strftime(fmt) for i in range(0,days,7)])

                # Set the horizontal dotted lines
                chart.set_grid(0, 25, 5, 5)

                # The Y axis labels contains 0 to 100 skipping every 25, but remove the
                # first number because it's obvious and gets in the way of the first X
                # label.
                delta = float(max_count-min_count) / 100
                skip = int(delta) / 5 * 100
                left_axis = range(0, 60000 + 1, skip)
                left_axis[0] = ''
                chart.set_axis_labels(Axis.LEFT, left_axis)

                if len(title) > 0:
                        chart.set_title(title % days)

                chart.download(output)
Example #10
0
    def linegraph(self, days, bars, output, title=""):
        data = []
        min_count = 0
        max_count = 0
        date = lambda i: datetime.date.today() + datetime.timedelta(-days + i)

        for i in range(0, days + 1):
            count = bars[date(i)]
            max_count = max(count, max_count)
            min_count = min(count, min_count)
            data.append(count)
        chart = SimpleLineChart(800, 350, y_range=[min_count, 60000])
        chart.add_data(data)
        # Set the line colour to blue
        chart.set_colours(['0000FF'])

        # Set the vertical stripes
        d = max(1 / float(days), round(7 / float(days), 2))
        chart.fill_linear_stripes(Chart.CHART, 0, 'CCCCCC', d, 'FFFFFF', d)

        fmt = "%d/%m"
        chart.set_axis_labels(Axis.BOTTOM, \
                              [date(i).strftime(fmt) for i in range(0,days,7)])

        # Set the horizontal dotted lines
        chart.set_grid(0, 25, 5, 5)

        # The Y axis labels contains 0 to 100 skipping every 25, but remove the
        # first number because it's obvious and gets in the way of the first X
        # label.
        delta = float(max_count - min_count) / 100
        skip = int(delta) / 5 * 100
        left_axis = range(0, 60000 + 1, skip)
        left_axis[0] = ''
        chart.set_axis_labels(Axis.LEFT, left_axis)

        if len(title) > 0:
            chart.set_title(title % days)

        chart.download(output)
Example #11
0
def users(*args):
    days = 60
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("SELECT date_joined, COUNT(*) from auth_user where date_joined > NOW() - INTERVAL %i DAY group by DATE(date_joined) order by DATE(date_joined) desc" % days)

    data = {}
    max_y = 0;
    for dt, num in cursor.fetchall():
        if num > max_y:
            max_y = num;
        data[dt.date()] = num

    data2 = []

    dt = date.today() - timedelta(days-1)
    for i in xrange(days):
        data2.append((dt, data.get(dt, 0)))
        dt = dt + timedelta(1)

    chart = SimpleLineChart(800, 125, y_range=[0, max_y])
    chart.add_data([row[1] for row in data2])
    chart.set_colours(['0000FF'])

    ticks = (max_y % 25) + 1

    left_axis = range(0, max_y, 25)
    left_axis[0] = ''
    chart.set_axis_labels(Axis.RIGHT, left_axis)

    bottom_axis = [dt[0].strftime("%b") if dt[0].day == 1 else '' for dt in data2]
    chart.set_axis_labels(Axis.BOTTOM, bottom_axis)

    chart.set_title("Daily Registrations")

    data2.reverse() 
    return chart
Example #12
0
def getRollingAverageGraph(cursor, colName, rollingWindowDays, title=""):
    sqlCMD = "SELECT pDate, %s from %s" % (colName, N.JOBS_SUMMARY_TABLENAME)
    cursor.execute(sqlCMD)
    results = cursor.fetchall()
    beginWindowIndex = 0
    endWindowIndex = 0
    xData = []
    yData = []
    while endWindowIndex < len(results):
        while endWindowIndex < len(results) and (
                results[endWindowIndex][0] -
                results[beginWindowIndex][0]).days <= rollingWindowDays:
            endWindowIndex += 1
        yData.append(
            sum(results[i][1]
                for i in xrange(beginWindowIndex, endWindowIndex, 1)) /
            float(endWindowIndex - beginWindowIndex))
        xData.append(results[endWindowIndex - 1][0])
        beginWindowIndex = endWindowIndex
    chart = SimpleLineChart(680, 400, y_range=(min(yData) - 1, max(yData) + 1))
    chart.add_data(yData)

    yLabels = range(0, int(max(yData) + 1), 5)
    yLabels[0] = ''
    xLabels = [
        str(xData[-i]) for i in xrange(1,
                                       len(xData) - 1, int(0.2 * len(xData)))
    ]
    xLabels.reverse()
    chart.set_axis_labels(Axis.LEFT, yLabels)
    chart.set_axis_labels(Axis.BOTTOM, xLabels)
    chart.set_title("Rolling %i-Day Average %s" % (rollingWindowDays, title))
    imgbin = chart.download()
    toReturn = cStringIO.StringIO(imgbin)
    toReturn.seek(0)
    return chart.get_url(), toReturn
Example #13
0
def email_report(email, download_link, daily_report, weekly_report,
                 host, port, login=None, password=None, dry_run=False,
                 verbose=False):
    daily = [v[0] for k, v in daily_report.items()] if daily_report else []
    weekly = [v[0] for k, v in weekly_report.items()] if weekly_report else []

    cumulative_data = daily_report if daily_report else weekly_report
    if cumulative_data is None:
        raise Exception("No data given to generate a cumulative report!")
    cumulative = [v[1] for k, v in cumulative_data.items()]

    width, height = 700, 300

    # Create the charts
    daily_chart = SimpleLineChart(width, height)
    weekly_chart = SimpleLineChart(width, height)
    cumulative_chart = SimpleLineChart(width, height)

    # Titles
    daily_chart.set_title('Daily Downloads')
    weekly_chart.set_title('Weekly Downloads')
    cumulative_chart.set_title('Cumulative Downloads')

    # Add data
    if daily:
        daily_chart.add_data(daily)
        daily_chart.set_axis_range(Axis.LEFT, 0, max(daily))
        daily_chart.set_axis_labels(Axis.RIGHT, [min(daily), max(daily)])

    if weekly:
        weekly_chart.add_data(weekly)
        weekly_chart.set_axis_range(Axis.LEFT, 0, max(weekly))
        weekly_chart.set_axis_labels(Axis.RIGHT, [min(weekly), max(weekly)])

    cumulative_chart.add_data(cumulative)
    cumulative_chart.set_axis_range(Axis.LEFT, 0, max(cumulative))
    cumulative_chart.set_axis_labels(
        Axis.RIGHT, [min(cumulative), max(cumulative)])

    # Set the styling
    marker = ('B', 'C5D4B5BB', '0', '0', '0')
    colors = ['3D7930', 'FF9900']

    daily_chart.markers.append(marker)
    weekly_chart.markers.append(marker)
    cumulative_chart.markers.append(marker)

    daily_chart.set_colours(colors)
    weekly_chart.set_colours(colors)
    cumulative_chart.set_colours(colors)

    grid_args = 0, 10
    grid_kwargs = dict(line_segment=2, blank_segment=6)
    daily_chart.set_grid(*grid_args, **grid_kwargs)
    weekly_chart.set_grid(*grid_args, **grid_kwargs)
    cumulative_chart.set_grid(*grid_args, **grid_kwargs)

    #daily_chart.fill_linear_stripes(
    #   Chart.CHART, 0, 'CCCCCC', 0.2, 'FFFFFF', 0.2)

    daily_chart_url = daily_chart.get_url() if daily else None
    weekly_chart_url = weekly_chart.get_url() if weekly else None
    cumulative_chart_url = cumulative_chart.get_url()

    # Create recent versions of the charts
    if daily:
        recent_daily = daily[-90:]

        # Get last year's daily data. First, get the first date for the daily
        # data.
        start = daily_report.items()[-90][0]
        dt = datetime.datetime.strptime(start, '%Y/%m/%d')
        dt = dt - datetime.timedelta(weeks=52)
        last_year_datestr = datetime_to_str(dt)

        # Get the index in the data for the datestr
        try:
            i = daily_report.keys().index(last_year_datestr)
            recent_daily_comparison = daily[i:i + 90]
        except ValueError:
            recent_daily_comparison = []

        if recent_daily_comparison:
            daily_chart.data = [recent_daily, recent_daily_comparison]
        else:
            daily_chart.data = [recent_daily]
        # Reset the axes
        daily_chart.axis = []
        min_daily = min(recent_daily + recent_daily_comparison)
        max_daily = max(recent_daily + recent_daily_comparison)
        daily_chart.set_axis_range(Axis.LEFT, 0, max_daily)
        daily_chart.set_axis_labels(Axis.RIGHT, [min_daily, max_daily])
        daily_chart.set_title('Recent Daily Downloads (filled is now)')

        daily_recent_chart_url = daily_chart.get_url()
    else:
        daily_recent_chart_url = None

    if verbose:
        print('Daily: ' + daily_chart_url) if daily_chart_url else None
        print('Weekly: ' + weekly_chart_url) if weekly_chart_url else None
        print('Cumulative: ' + cumulative_chart_url)
        print('Daily Recent: ' + daily_recent_chart_url) if daily_recent_chart_url else None

    # Create the body of the message (a plain-text and an HTML version).
    text = "Get an HTML mail client."
    html = """\
<html>
    <body>
        <h2>Latest download count: {latest_daily}</h2>
        <h2>Latest weekly download count: {latest_weekly}</h2>
        <h2>Latest cumulative total: {cumulative}</h2>
        <p><a href="{download}">Download today's report</a>.</p>
        <p><img src="cid:daily.png" width="{width}" height="{height}" alt="Daily Downloads" /></p>
        <p><img src="cid:weekly.png" width="{width}" height="{height}" alt="Weekly Downloads" /></p>
        <p><img src="cid:cumulative.png" width="{width}" height="{height}" alt="Cumulative Downloads" /></p>
        <p><img src="cid:daily-recent.png" width="{width}" height="{height}" alt="Recent Daily Downloads" /></p>
    </body>
</html>""".format(
        latest_daily=daily[-1] if daily else 0,
        latest_weekly=weekly[-1] if weekly else 0,
        cumulative=cumulative[-1],
        download=download_link,
        width=width,
        height=height,
    )

    # Create message container - the correct MIME type is multipart/alternative.
    message_root = MIMEMultipart('related')
    message_root['Subject'] = "Daily iTunes Download Report"
    message_root['From'] = email
    message_root['To'] = email
    message_root.preamble = 'This is a multi-part message.'

    # Record the MIME types of both parts - text/plain and text/html.
    alternative = MIMEMultipart('alternative')
    message_root.attach(alternative)

    part1 = MIMEText(text, 'plain')
    part2 = MIMEText(html, 'html')

    # Attach parts into message container.
    # According to RFC 2046, the last part of a multipart message, in this case
    # the HTML message, is best and preferred.
    alternative.attach(part1)
    alternative.attach(part2)

    # Get the images
    if daily_chart_url:
        r = requests.get(daily_chart_url)
        img = MIMEImage(r.content)
        img.add_header('Content-ID', '<daily.png>')
        message_root.attach(img)

    if weekly_chart_url:
        r = requests.get(weekly_chart_url)
        img = MIMEImage(r.content)
        img.add_header('Content-ID', '<weekly.png>')
        message_root.attach(img)

    r = requests.get(cumulative_chart_url)
    img = MIMEImage(r.content)
    img.add_header('Content-ID', '<cumulative.png>')
    message_root.attach(img)

    if daily_recent_chart_url:
        r = requests.get(daily_recent_chart_url)
        img = MIMEImage(r.content)
        img.add_header('Content-ID', '<daily-recent.png>')
        message_root.attach(img)

    try:
        # Send the message via local SMTP server.
        s = smtplib.SMTP(host, port)
        s.starttls()
        s.login(login, password)

        # sendmail function takes 3 arguments: sender's address,
        # recipient's address and message to send - here it is sent as one
        # string.
        s.sendmail(email, [email], message_root.as_string())
        s.quit()
    except (ssl.SSLError, smtplib.SMTPServerDisconnected):
        print('Error')
        s.close()
Example #14
0
def email_report(email, download_link, daily_report, weekly_report,
                 host, port, login=None, password=None, dry_run=False,
                 verbose=False):
    daily = [v[0] for k, v in daily_report.items()] if daily_report else []
    daily_updates = daily_report.items()[-1][1][1]
    daily_edu = daily_report.items()[-1][1][2]
    weekly = [v[0] for k, v in weekly_report.items()] if weekly_report else []

    cumulative_data = daily_report if daily_report else weekly_report
    if cumulative_data is None:
        raise Exception("No data given to generate a cumulative report!")
    cumulative = [v[3] for k, v in cumulative_data.items()]

    width, height = 700, 300

    # Create the charts
    daily_chart = SimpleLineChart(width, height)
    weekly_chart = SimpleLineChart(width, height)
    cumulative_chart = SimpleLineChart(width, height)

    # Titles
    daily_chart.set_title('Daily Downloads')
    weekly_chart.set_title('Weekly Downloads')
    cumulative_chart.set_title('Cumulative Downloads')

    # Add data
    if daily:
        daily_data = daily[-180:]
        daily_chart.add_data(daily_data)
        daily_chart.set_axis_range(Axis.LEFT, 0, max(daily_data))
        daily_chart.set_axis_labels(Axis.RIGHT, [min(daily_data), max(daily_data)])

    if weekly:
        weekly_chart.add_data(weekly)
        weekly_chart.set_axis_range(Axis.LEFT, 0, max(weekly))
        weekly_chart.set_axis_labels(Axis.RIGHT, [min(weekly), max(weekly)])

    cumulative_chart.add_data(cumulative)
    cumulative_chart.set_axis_range(Axis.LEFT, 0, max(cumulative))
    cumulative_chart.set_axis_labels(
        Axis.RIGHT, [min(cumulative), max(cumulative)])

    # Set the styling
    marker = ('B', 'C5D4B5BB', '0', '0', '0')
    colors = ['3D7930', 'FF9900']

    daily_chart.markers.append(marker)
    weekly_chart.markers.append(marker)
    cumulative_chart.markers.append(marker)

    daily_chart.set_colours(colors)
    weekly_chart.set_colours(colors)
    cumulative_chart.set_colours(colors)

    grid_args = 0, 10
    grid_kwargs = dict(line_segment=2, blank_segment=6)
    daily_chart.set_grid(*grid_args, **grid_kwargs)
    weekly_chart.set_grid(*grid_args, **grid_kwargs)
    cumulative_chart.set_grid(*grid_args, **grid_kwargs)

    #daily_chart.fill_linear_stripes(
    #   Chart.CHART, 0, 'CCCCCC', 0.2, 'FFFFFF', 0.2)

    daily_chart_url = daily_chart.get_url() if daily else None
    weekly_chart_url = weekly_chart.get_url() if weekly else None
    cumulative_chart_url = cumulative_chart.get_url()

    # Create recent versions of the charts
    if daily:
        recent_daily = daily[-90:]

        # Get last year's daily data. First, get the first date for the daily
        # data.
        start = daily_report.items()[-90][0]
        dt = datetime.datetime.strptime(start, '%Y/%m/%d')
        dt = dt - datetime.timedelta(weeks=52)
        last_year_datestr = datetime_to_str(dt)

        # Get the index in the data for the datestr
        try:
            i = daily_report.keys().index(last_year_datestr)
            recent_daily_comparison = daily[i:i + 90]
        except ValueError:
            recent_daily_comparison = []

        if recent_daily_comparison:
            daily_chart.data = [recent_daily, recent_daily_comparison]
        else:
            daily_chart.data = [recent_daily]
        # Reset the axes
        daily_chart.axis = []
        min_daily = min(recent_daily + recent_daily_comparison)
        max_daily = max(recent_daily + recent_daily_comparison)
        daily_chart.set_axis_range(Axis.LEFT, 0, max_daily)
        daily_chart.set_axis_labels(Axis.RIGHT, [min_daily, max_daily])
        daily_chart.set_title('Recent Daily Downloads (filled is now)')

        daily_recent_chart_url = daily_chart.get_url()
    else:
        daily_recent_chart_url = None

    if verbose:
        print('Daily: ' + daily_chart_url) if daily_chart_url else None
        print('Weekly: ' + weekly_chart_url) if weekly_chart_url else None
        print('Cumulative: ' + cumulative_chart_url)
        print('Daily Recent: ' + daily_recent_chart_url) if daily_recent_chart_url else None

    yesterday = datetime.date.today() - datetime.timedelta(days=1)

    # Create the body of the message (a plain-text and an HTML version).
    text = "Get an HTML mail client."
    html = """\
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=600" />
    <style>
        @media only screen and (min-device-width: 541px) {{
            .content {{
                width: 540px !important;
            }}
        }}
    </style>
</head>

<body>

<table class="content" align="center" cellpadding="0" cellspacing="0" border="0" style="width: 100%; max-width: 540px; border: 1px solid #cbcbcb;">
    <tr>
        <td height="32" style="text-align: center; background-color:#fe8359;height:32px;color:#fff" bgcolor="fe8359">
            <span style="font-size:11px">Daily Report for</span>
            <span style="font-size:14px;font-weight:bold">{yesterday:%A, %B %d, %Y}</span>
        </td>
    </tr>
    <tr>
        <td height="30" valign="middle">
            <table cellpadding="0" cellspacing="0" border="0" style="width: 100%; text-align: center">
                <tr>
                    <td style="margin-top: 5px;">
                        <span style="font-size: 10px; color: #777">Downloads:</span>
                        <div style="font-size: 15px; margin-top: 3px; "><b>{latest_daily:,}</b></div>
                    </td>
                    <td style="margin-top: 5px;">
                        <span style="font-size: 10px; color: #777">Updates:</span>
                        <div style="font-size: 15px; margin-top: 3px; "><b>{latest_updates:,}</b></div>
                    </td>
                    <td style="margin-top: 5px;">
                        <span style="font-size: 10px; color: #777">Educational:</span>
                        <div style="font-size: 15px; margin-top: 3px; "><b>{latest_edu:,}</b></div>
                    </td>
                    <td style="margin-top: 5px;">
                        <span style="font-size: 10px; color: #777">Since Monday:</span>
                        <div style="font-size: 15px; margin-top: 3px; "><b>{latest_weekly:,}</b></div>
                    </td>
                    <td style="margin-top: 5px;">
                        <span style="font-size: 10px; color: #777">Cumulative:</span>
                        <div style="font-size: 15px; margin-top: 3px; "><b>{cumulative:,}</b></div>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
    <tr>
        <td></td>
    </tr>
    <tr>
        <td><hr color="#cbcbcb"></td>
    </tr>

    <tr><td style="padding: 5px;"><img src="cid:daily.png" width="{width}" height="{height}" alt="Daily Downloads" /></td></tr>
    <tr><td style="padding: 5px;"><img src="cid:weekly.png" width="{width}" height="{height}" alt="Weekly Downloads" /></td></tr>
    <tr><td style="padding: 5px;"><img src="cid:cumulative.png" width="{width}" height="{height}" alt="Cumulative Downloads" /></td></tr>
    <tr><td style="padding: 5px;"><img src="cid:daily-recent.png" width="{width}" height="{height}" alt="Recent Daily Downloads" /></td></tr>

    <tr>
        <td><hr color="#cbcbcb"></td>
    </tr>
    <tr>
        <td style="padding: 10px; text-align: center;">
            <a style="color: #777" href="{download}">Download today's report</a>
        </td>
    </tr>
</table>


</body>

</html>""".format(
        yesterday=yesterday,
        latest_daily=daily[-1] if daily else 0,
        latest_weekly=weekly[-1] if weekly else 0,
        latest_updates=daily_updates,
        latest_edu=daily_edu,
        cumulative=cumulative[-1],
        download=download_link,
        width=width,
        height=height,
    )

    # Create message container - the correct MIME type is multipart/alternative.
    message_root = MIMEMultipart('related')
    message_root['Subject'] = "iTunes Report for {:%A, %B %d, %Y}".format(yesterday)
    message_root['From'] = email
    message_root['To'] = email
    message_root.preamble = 'This is a multi-part message.'

    # Record the MIME types of both parts - text/plain and text/html.
    alternative = MIMEMultipart('alternative')
    message_root.attach(alternative)

    part1 = MIMEText(text, 'plain')
    part2 = MIMEText(html, 'html')

    # Attach parts into message container.
    # According to RFC 2046, the last part of a multipart message, in this case
    # the HTML message, is best and preferred.
    alternative.attach(part1)
    alternative.attach(part2)

    # Get the images
    if daily_chart_url:
        r = requests.get(daily_chart_url)
        img = MIMEImage(r.content, _subtype='png')
        img.add_header('Content-ID', '<daily.png>')
        message_root.attach(img)

    if weekly_chart_url:
        r = requests.get(weekly_chart_url)
        img = MIMEImage(r.content, _subtype='png')
        img.add_header('Content-ID', '<weekly.png>')
        message_root.attach(img)

    r = requests.get(cumulative_chart_url)
    img = MIMEImage(r.content, _subtype='png')
    img.add_header('Content-ID', '<cumulative.png>')
    message_root.attach(img)

    if daily_recent_chart_url:
        r = requests.get(daily_recent_chart_url)
        img = MIMEImage(r.content, _subtype='png')
        img.add_header('Content-ID', '<daily-recent.png>')
        message_root.attach(img)

    try:
        # Send the message via local SMTP server.
        s = smtplib.SMTP(host, port)
        s.starttls()
        s.login(login, password)

        # sendmail function takes 3 arguments: sender's address,
        # recipient's address and message to send - here it is sent as one
        # string.
        s.sendmail(email, [email], message_root.as_string())
        s.quit()
    except (ssl.SSLError, smtplib.SMTPServerDisconnected):
        print('Error')
        s.close()