1#!/usr/bin/env python3
  2
  3"""Prepare the daily digest then email it to all subscribers."""
  4
  5
  6
  7import sys
  8from io import StringIO
  9from datetime import datetime, timedelta
 10
 11import django
 12
 13from chart.common.path import Path
 14from chart.db.connection import db_connect
 15from chart.project import settings
 16import chart.alg.settings
 17from chart.alg import init_algorithm
 18from chart.reports.document import Document
 19from chart.reports.report_template import ReportTemplate
 20from chart.common.util import nvl
 21from chart.common import sendmail
 22from chart.backend.job import JobStatus
 23from chart.reports.manifest import Manifest
 24
 25db_conn = db_connect()
 26
 27
 28def daily_digest(start_time, stop_time, simulate):
 29    """Prepare and send the daily digest email."""
 30    template = ReportTemplate('daily_digest')
 31    doc = Document()
 32    doc.htmls = []
 33    doc.config = {'sensing-start': start_time,
 34                  'sensing-stop': stop_time}
 35    doc.render_html(template.widgets)
 36    digest = StringIO()
 37    doc.write(digest)
 38
 39    # write full digest to working directory for archiving
 40    # encoding is used in case there are strange characters in the Wiki report
 41    # chart.alg.settings.REPORT_FILENAME.open('wb').write(digest.encode('utf-8'))
 42    import codecs
 43    codecs.open(str(chart.alg.settings.REPORT_FILENAME),
 44                mode='wb',
 45                encoding='latin-1',
 46                errors='xmlcharrefreplace').write(digest.getvalue())
 47
 48    # email individual digests
 49    for first_name, last_name, email in db_conn.query(
 50        'SELECT first_name, last_name, email '
 51        'FROM auth_user, users '
 52        'WHERE auth_user.id=users.django_user_id '
 53        'AND users.daily_digest=1'):
 54
 55        name = '{first} {last}'.format(first=nvl(first_name),
 56                                       last=nvl(last_name))
 57
 58        if simulate is not True:
 59            html = digest.getvalue()
 60            if sys.version_info.major > 3:
 61                html = html.encode('utf-8')
 62
 63            sendmail.sendmail_html(
 64                from_address=(settings.EMAIL_NAME.format('digest'),
 65                              settings.EMAIL_ADDRESS.format('digest')),
 66                to_addresses=((name, email),),
 67                subject='Daily digest for {d}'.format(d=start_time.date()),
 68                html=html)
 69
 70
 71def weekly_digest(start_time, stop_time, simulate):
 72    """Prepare and send the daily digest email."""
 73    template = ReportTemplate('weekly_digest')
 74    doc = Document()
 75    doc.htmls = []
 76    doc.config = {'sensing-start': start_time,
 77                  'sensing-stop': stop_time}
 78    doc.render_html(template.widgets)
 79    digest = StringIO()
 80    doc.write(digest)
 81
 82    # write full digest to working directory for archiving
 83    # encoding is used in case there are strange characters in the Wiki report
 84    # chart.alg.settings.REPORT_FILENAME.open('wb').write(digest.encode('utf-8'))
 85    import codecs
 86    codecs.open(str(chart.alg.settings.REPORT_FILENAME),
 87                mode='wb',
 88                encoding='latin-1',
 89                errors='xmlcharrefreplace').write(digest.getvalue())
 90
 91    # email individual digests
 92    for first_name, last_name, email in db_conn.query(
 93        'SELECT first_name, last_name, email '
 94        'FROM auth_user, users '
 95        'WHERE auth_user.id=users.django_user_id '
 96        'AND users.daily_digest=1'):
 97
 98        name = '{first} {last}'.format(first=nvl(first_name),
 99                                       last=nvl(last_name))
100
101        if simulate is not True:
102            sendmail.sendmail_html(
103                from_address=(settings.EMAIL_NAME.format('digest'),
104                              settings.EMAIL_ADDRESS.format('digest')),
105                to_addresses=((name, email),),
106                subject='Weekly digest for {d}'.format(d=start_time.date()),
107                html=digest.getvalue())
108
109
110def main():
111    """Command line entry point."""
112    django.setup()
113    # Read the work order file
114    wo, resultfile, _ = init_algorithm()
115
116    for job in wo.read_jobs():
117        start = job.sensing_start.date()
118        stop = job.sensing_stop.date()
119        if (stop - start) < timedelta(hours=25):
120            daily_digest(datetime(start.year, start.month, start.day),
121                         datetime(stop.year, stop.month, stop.day) - timedelta(minutes=1),
122                         simulate=False)
123
124        elif (stop - start) > timedelta(days=6):
125            weekly_digest(datetime(start.year, start.month, start.day),
126                         datetime(stop.year, stop.month, stop.day) - timedelta(minutes=1),
127                         simulate=False)
128
129        tmp_filename = Path(str(chart.alg.settings.REPORT_FILENAME) + '.tmp')
130        chart.alg.settings.REPORT_FILENAME.rename(tmp_filename)
131        report = chart.alg.settings.REPORT_FILENAME.open('w', encoding='utf8')
132        # report = chart.alg.settings.REPORT_FILENAME.open('wb')
133        body = tmp_filename.open('r', encoding='utf8', errors='replace').read()
134        report.write("""<head>
135{style}
136</head>
137<body>
138{body}
139</body>
140</html>""".format(style=sendmail.email_styles,
141                  body=body))
142        report.close()
143        tmp_filename.unlink()
144        resultfile.add_job(job, JobStatus.COMPLETED)
145        manifest = Manifest(mode=Manifest.Mode.WRITE)
146        manifest.job_id = job.job_id
147        manifest.activity = wo.activity
148        manifest.sid = job.sid
149        manifest.sensing_start = job.sensing_start
150        manifest.sensing_stop = job.sensing_stop
151        # manifest.close()
152
153if __name__ == '__main__':
154    main()