Esempio n. 1
0
    def __init__(self, survey_id, answer, answered_by, answer_sms_id=None, survey_key=None):
        """Constructor. TO-DO: The logic to know from which neighbourhood
        is the monitor is faulty as sometimes a monitor is responsible for 2
        points. Meaning that the logic here will get the first or last
        neighbourhood, completely ignoring the rest of the points"""
        self.survey_id = survey_id
        self.answer = answer
        self.answered_by = answered_by
        self.answered_at = datetime.utcnow()
        self.survey_key = survey_key

        if not self.NEIGHBOURHOODS:
            self.NEIGHBOURHOODS = Location.i().get_notifications_mapping()

        for district in self.NEIGHBOURHOODS["districts"]:
            for neighbourhood in district['neighbourhoods']:
                for point in neighbourhood['points']:
                    for monitor_id in point['monitors']:
                        monitor = Location.i().get_monitor(monitor_id)
                        if (monitor['phone'] == answered_by or
                                "258" + monitor['phone'] == answered_by):
                            self.neighbourhood = neighbourhood['name']
                            self.quarter = ""
                            self.point = (point['name'] +
                                          " " +
                                          point['location'])
                            break

        if answer_sms_id:
            self.answer_sms_id = answer_sms_id
Esempio n. 2
0
def notify_updates_on_requests():
    """A scheduled task to check if there are any new requests or updated
    requests within the last hour and notify the involved parts"""

    today = date.today()

    start_date = today.strftime('%Y-%m-%d')
    end_date = (today + timedelta(days=1)).strftime('%Y-%m-%d')
    _requests = get_requests(start_date, end_date, True)

    time_ago = datetime.now(config.TZ) + timedelta(seconds=-(1 * 60 * 10))
    now = datetime.now(config.TZ)
    for _request in _requests:
        requested_datetime = parse(_request['requested_datetime'])
        updated_datetime = parse(_request['updated_datetime'])
        status = _request['status']

        if time_ago <= requested_datetime <= now and status == 'open':
            # New request -> notify responsible company/people
            location = Location.i().guess_location(_request)
            district = location['district']
            neighbourhood = location['neighbourhood']
            location_name = location['location_name']

            if neighbourhood:
                phones = Location.i().get_notified_companies_phones(_request['neighbourhood'], _request['service_code'])

                for phone in phones:
                    text_tpl = 'Novo problema reportado no mopa: No: %s - %s em %s. %s'
                    text = text_tpl % (_request['service_request_id'], _request['service_name'], _request['neighbourhood'], _request.get('description', '').replace('Criado por USSD.', ''))
                    text = truncate(text, 160)
                    db_sms = SMS.static_send(phone, text)
                    Uow.add(db_sms)
                Uow.commit()
            else:
                current_app.logger.error("New request with no neighbourhood data found. Cannot notify companies. Request ID: " + _request['service_request_id'])

        elif (time_ago <= updated_datetime <= now) and status != 'open' and _request.get('phone', ''):
            # Update on request -> notify the person who reported
            text_tpl = 'Caro cidadao, o problema reportado por si: %s foi actualizado. Novo estado: %s. Comentario CMM: %s'
            text = text_tpl % (_request['service_request_id'], _request['service_notice'],  _request.get('status_notes', ''))
            text = truncate(text, 160)
            db_sms = SMS.static_send(_request.get('phone'), text)
            Uow.add(db_sms)
            Uow.commit()

    return "Ok", 200
Esempio n. 3
0
def send_daily_survey():
    """Task to send daily survey"""
    survey = Survey(survey_type="G", question=config.SMS_INTRO)
    Uow.add(survey)
    Uow.commit()

    monitor_phones = Location.i().get_monitors_phones()
    for phone in monitor_phones:
        db_sms = SMS.static_send(phone, config.SMS_INTRO)
        Uow.add(db_sms)
        Uow.commit()

    return "Ok", 200
Esempio n. 4
0
def send_daily_survey():
    """Task to send daily survey"""
    survey = Survey(survey_type="G", question=config.SMS_INTRO)
    Uow.add(survey)
    Uow.commit()

    monitor_phones = Location.i().get_monitors_phones()
    for phone in monitor_phones:
        db_sms = SMS.static_send(phone, config.SMS_INTRO)
        Uow.add(db_sms)
        Uow.commit()

    return "Ok", 200
Esempio n. 5
0
    def __init__(self,
                 survey_id,
                 answer,
                 answered_by,
                 answer_sms_id=None,
                 survey_key=None):
        """Constructor. TO-DO: The logic to know from which neighbourhood
        is the monitor is faulty as sometimes a monitor is responsible for 2
        points. Meaning that the logic here will get the first or last
        neighbourhood, completely ignoring the rest of the points"""
        self.survey_id = survey_id
        self.answer = answer
        self.answered_by = answered_by
        self.answered_at = datetime.utcnow()
        self.survey_key = survey_key

        if not self.NEIGHBOURHOODS:
            self.NEIGHBOURHOODS = Location.i().get_notifications_mapping()

        for district in self.NEIGHBOURHOODS["districts"]:
            for neighbourhood in district['neighbourhoods']:
                for point in (neighbourhood['points']
                              if neighbourhood.has_key('points') else []):
                    for monitor_id in (point['monitors']
                                       if point.has_key('monitors') else []):
                        monitor = Location.i().get_monitor(monitor_id)
                        if (monitor['phone'] == answered_by
                                or "258" + monitor['phone'] == answered_by):
                            self.neighbourhood = neighbourhood['name']
                            self.quarter = ""
                            self.point = (point['name'] + " " +
                                          point['location'])
                            break

        if answer_sms_id:
            self.answer_sms_id = answer_sms_id
Esempio n. 6
0
def check_if_answers_were_received():
    """Task to check if monitor answered daily survey and alert them if they did not"""
    monitor_phones = Location.i().get_monitors_phones()

    survey = Survey.todays()

    if survey:
        monitors_who_answered = Survey.get_answerers(survey.id) or []

        for phone in monitor_phones:
            if ("258" + phone) not in monitors_who_answered:
                db_sms = SMS.static_send(phone, config.SMS_NO_FEEDBACK_RECEIVED)
                Uow.add(db_sms)
                Uow.commit()

    return "Ok", 200
Esempio n. 7
0
def check_if_answers_were_received():
    """Task to check if monitor answered daily survey and alert them if they did not"""
    monitor_phones = Location.i().get_monitors_phones()

    survey = Survey.todays()

    if survey:
        monitors_who_answered = Survey.get_answerers(survey.id) or []

        for phone in monitor_phones:
            if ("258" + phone) not in monitors_who_answered:
                db_sms = SMS.static_send(phone,
                                         config.SMS_NO_FEEDBACK_RECEIVED)
                Uow.add(db_sms)
                Uow.commit()

    return "Ok", 200
Esempio n. 8
0
def send_weekly_report(today=None):
    """Task to run weekly for report"""

    today = date.today() if today is None else datetime.strptime(today, '%Y-%m-%d')
    start_date = today + timedelta(days=-7)
    end_date = today

    old_start_date = start_date + timedelta(days=-7)
    old_end_date = start_date

    # Get requests
    default = ''
    requests_list = []

    for _request in get_requests(start_date, end_date, True):
        location = Location.i().guess_location(_request)

        del _request['zipcode']
        del _request['lat']
        del _request['long']

        district = location['district']
        neighbourhood = location['neighbourhood']
        location_name = location['location_name']

        report = Report()
        report.id = xstr(_request['service_request_id'])
        report.district = district
        report.neighbourhood = neighbourhood
        report.location_name = location_name
        report.nature = xstr(_request['service_name'])
        report.requested_datetime = (xstr(_request['requested_datetime'])[0:10] + " " + xstr(_request['requested_datetime'])[11:19])
        report.updated_datetime = (xstr(_request['updated_datetime'])[0:10] + " " + xstr(_request['updated_datetime'])[11:19])
        report.type = xstr(_request['service_name'])
        report.status = xstr(_request['service_notice'])
        report.status_notes = xstr(_request.get('status_notes', ''))

        Uow.add(report)
        try:
            Uow.commit()
        except IntegrityError:
            Uow.rollback()
        except Exception, ex:
            Uow.rollback()
            current_app.logger.error("Error While Inserting Report in DB\n" + traceback.format_exc())
Esempio n. 9
0
    def test_gets_notified_people(self):
        people = Location.i().get_notified_companies_phones('Magoanine B', '04')
        self.assertTrue(len(people) >= 1)

        people = Location.i().get_notified_companies_phones('25 de Junho A', '04')
        self.assertTrue(len(people) >= 1)

        people = Location.i().get_notified_companies_phones('Luis Cabral', '04')
        self.assertTrue(len(people) >= 1)

        people = Location.i().get_notified_companies_phones('Nsalane', '04')
        self.assertTrue(len(people) == 0)

        people = Location.i().get_notified_companies_phones('Malhazine', '04')
        self.assertTrue(len(people) >= 1)

        people = Location.i().get_notified_companies_phones('Magoanine C', '04')
        self.assertTrue(len(people) >= 1)
Esempio n. 10
0
    def test_gets_notified_people(self):
        people = Location.i().get_notified_companies_phones(
            'Magoanine B', '04')
        self.assertTrue(len(people) >= 1)

        people = Location.i().get_notified_companies_phones(
            '25 de Junho A', '04')
        self.assertTrue(len(people) >= 1)

        people = Location.i().get_notified_companies_phones(
            'Luis Cabral', '04')
        self.assertTrue(len(people) >= 1)

        people = Location.i().get_notified_companies_phones('Nsalane', '04')
        self.assertTrue(len(people) == 0)

        people = Location.i().get_notified_companies_phones('Malhazine', '04')
        self.assertTrue(len(people) >= 1)

        people = Location.i().get_notified_companies_phones(
            'Magoanine C', '04')
        self.assertTrue(len(people) >= 1)
Esempio n. 11
0
def send_daily_report(today=None):
    """Task to run the Daily PDF Exporter"""

    today = date.today() if today is None else datetime.strptime(today, '%Y-%m-%d')

    # Get requests
    default = ''
    requests_list = []
    districts = []

    start_date = (today + timedelta(days=-2)).strftime('%Y-%m-%d')
    end_date = today.strftime('%Y-%m-%d')

    for _request in get_requests(start_date, end_date, None):

        location = Location.i().guess_location(_request)

        district = location['district']
        districts.append(district.lower())
        neighbourhood = location['neighbourhood']
        location_name = location['location_name']

        requests_list.append({
                'id': xstr(_request['service_request_id']),
                'district': district,
                'neighbourhood': neighbourhood,
                'location_name': location_name,
                'nature': xstr(_request['service_name']),
                'datetime': xstr(_request['requested_datetime'])[0:10] + " " + xstr(_request['requested_datetime'])[11:19],
                'type': xstr(_request['service_name']),
                'status': xstr(_request['service_notice']),
                'status_notes': xstr(_request.get('status_notes', ''))
            })

    # sorting
    requests_list = sorted(requests_list, key=lambda i: (i['district'], i['neighbourhood'], i['nature'], i['datetime']))

    # per district export
    districts = set(districts)

    for district in districts:
        district_requests = filter(lambda x: x['district'].lower() == district, requests_list)

        # Generate PDF
        context = {
            'today': today.strftime('%d-%m-%Y'),
            'requests_list': district_requests,
            'static': os.path.join(config.BASE_DIR, 'templates') + '/'
        }

        f_name = 'relatorio-diario-' + slugify(district) + '-' + today.strftime('%Y_%m_%d') + '.pdf'
        generate_pdf('daily_report.html', context, f_name)

        # Send mail
        html = '''\
            <html>
                <head></head>
                <body>
                <p>Sauda&ccedil;&otilde;es!<br/><br/>
                    Segue em anexo o relat&oacute;rio MOPA<br/><br/>
                    Cumprimentos,<br/>
                    <em>Enviado automaticamente</em>
                </p>
                </body>
            </html>
                '''
        send_mail(
            config.DAILY_REPORT_TO,
            '[MOPA] Relatorio Diario - ' + district.title() + ' - ' + today.strftime('%Y-%m-%d'),
            html,
            is_html=True,
            cc=config.DAILY_REPORT_CC,
            sender=(config.EMAIL_DEFAULT_NAME, config.EMAIL_DEFAULT_SENDER),
            attachments=[config.REPORTS_DIR + '/' + f_name]
        )

    return "Ok", 200
Esempio n. 12
0
    response = None

    try:
        response = retry_call(requests.get, fargs=['http://mopa.co.mz:8080/critical-points/' + today.strftime('%Y-%m-%d')], exceptions=ConnectTimeout, tries=3)
    except Exception, ex:
        ex_type, ex_obj, ex_tb = sys.exc_info()
        fname = os.path.split(ex_tb.tb_frame.f_code.co_filename)[1]
        current_app.logger.error("Could not fetch daily survey answers required to generate report.\nError message:{ex_msg}.\nException Type: {ex_type}.\nFile name: {file_name}.\nLine No: {line_no}.\nTraceback: {traceback}".format(ex_msg=str(ex), ex_type=str(ex_type), file_name=str(fname), line_no=str(ex_tb.tb_lineno), traceback=traceback.format_exc()))

    if not response:
        return

    answers = response.json()

    for answer in answers:
        monitor = Location.i().get_monitor_by_phone(answer["sent_to"])
        if monitor:
            point = Location.i().get_monitor_point(monitor["id"])
            if point:
                answer["name"] = point.get('name', "")
                answer["location"] = point.get('location', "")
                answer["geo_location"] = point.get('geo_location', "")
                answer["neighbourhood"] = point.get('neighbourhood', "")
                answer["district"] = point.get('district', "")
                if answer.get('answer'):
                    answer["answer"] = 'Nao' if \
                        answer.get('answer') == 'N' else 'Sim'

    # Generate PDF
    if answers:
        del answers[0]  # remove table column labels
Esempio n. 13
0
def send_daily_survey_replies():
    """Task to send daily survey answers as PDF"""

    today = date.today()

    response = None

    try:
        response = retry_call(requests.get,
                              fargs=[
                                  'http://mopa.co.mz:8080/critical-points/' +
                                  today.strftime('%Y-%m-%d')
                              ],
                              exceptions=ConnectTimeout,
                              tries=3)
    except Exception as ex:
        ex_type, ex_obj, ex_tb = sys.exc_info()
        fname = os.path.split(ex_tb.tb_frame.f_code.co_filename)[1]
        current_app.logger.error(
            "Could not fetch daily survey answers required to generate report.\nError message:{ex_msg}.\nException Type: {ex_type}.\nFile name: {file_name}.\nLine No: {line_no}.\nTraceback: {traceback}"
            .format(ex_msg=str(ex),
                    ex_type=str(ex_type),
                    file_name=str(fname),
                    line_no=str(ex_tb.tb_lineno),
                    traceback=traceback.format_exc()))

    if not response:
        return

    answers = response.json()

    for answer in answers:
        monitor = Location.i().get_monitor_by_phone(answer["sent_to"])
        if monitor:
            point = Location.i().get_monitor_point(monitor["id"])
            if point:
                answer["name"] = point.get('name', "")
                answer["location"] = point.get('location', "")
                answer["geo_location"] = point.get('geo_location', "")
                answer["neighbourhood"] = point.get('neighbourhood', "")
                answer["district"] = point.get('district', "")
                if answer.get('answer'):
                    answer["answer"] = 'Nao' if \
                        answer.get('answer') == 'N' else 'Sim'

    # Generate PDF
    if answers:
        del answers[0]  # remove table column labels
    context = {
        'today': today.strftime('%d-%m-%Y'),
        'answers': answers,
        'static': os.path.join(config.BASE_DIR, 'templates') + '/'
    }

    report_file_name = 'respostas-ao-inquerito-diario-' + today.strftime(
        '%Y_%m_%d') + '.pdf'
    generate_pdf('daily_survey_answers.html', context, report_file_name)

    # Send mail
    html = '''
<html>
    <head></head>
    <body>
    <p>Sauda&ccedil;&otilde;es!<br/><br/>
        Seguem em anexo as respostas aos inqu&eacute;ritos
        di&aacute;rios<br/><br/>
        Cumprimentos,<br/>
        <em>Enviado automaticamente</em>
    </p>
    </body>
</html>
            '''
    send_mail('[MOPA] Respostas aos Inqueritos Diarios - ' +
              today.strftime('%Y-%m-%d'),
              html_message=html,
              to=config.DAILY_ENQUIRY_REPORT_TO,
              cc=config.DAILY_REPORT_CC,
              sender=(config.EMAIL_DEFAULT_NAME, config.EMAIL_DEFAULT_SENDER),
              attachments=[config.REPORTS_DIR + '/' + report_file_name])

    return "Ok", 200
Esempio n. 14
0
def send_daily_report(today=None):
    """Task to run the Daily PDF Exporter"""

    today = date.today() if today is None else datetime.strptime(
        today, '%Y-%m-%d')

    # Get requests
    requests_list = []
    districts = []

    start_date = (today + timedelta(days=-2)).strftime('%Y-%m-%d')
    end_date = today.strftime('%Y-%m-%d')

    for _request in get_requests(start_date, end_date, None):

        location = Location.i().guess_location(_request)

        district = location['district']
        districts.append(district.lower())
        neighbourhood = location['neighbourhood']
        location_name = location['location_name']

        requests_list.append({
            'id':
            xstr(_request['service_request_id']),
            'district':
            district,
            'neighbourhood':
            neighbourhood,
            'location_name':
            location_name,
            'nature':
            xstr(_request['service_name']),
            'datetime':
            xstr(_request['requested_datetime'])[0:10] + " " +
            xstr(_request['requested_datetime'])[11:19],
            'type':
            xstr(_request['service_name']),
            'status':
            xstr(_request['service_notice']),
            'status_notes':
            xstr(_request.get('status_notes', ''))
        })

    # sorting
    requests_list = sorted(
        requests_list,
        key=lambda i:
        (i['district'], i['neighbourhood'], i['nature'], i['datetime']))

    # per district export
    districts = set(districts)

    for district in districts:
        district_requests = filter(lambda x: x['district'].lower() == district,
                                   requests_list)

        # Generate PDF
        context = {
            'today': today.strftime('%d-%m-%Y'),
            'requests_list': district_requests,
            'static': os.path.join(config.BASE_DIR, 'templates') + '/'
        }

        report_file_name = 'relatorio-diario-' + slugify(
            district) + '-' + today.strftime('%Y_%m_%d') + '.pdf'
        generate_pdf('daily_report.html', context, report_file_name)

        # Send mail
        html = '''
<html>
    <head></head>
    <body>
    <p>Sauda&ccedil;&otilde;es!<br/><br/>
        Segue em anexo o relat&oacute;rio MOPA<br/><br/>
        Cumprimentos,<br/>
        <em>Enviado automaticamente</em>
    </p>
    </body>
</html>
                '''
        send_mail('[MOPA] Relatorio Diario - ' + district.title() + ' - ' +
                  today.strftime('%Y-%m-%d'),
                  html_message=html,
                  to=config.DAILY_REPORT_TO,
                  cc=config.DAILY_REPORT_CC,
                  sender=(config.EMAIL_DEFAULT_NAME,
                          config.EMAIL_DEFAULT_SENDER),
                  attachments=[config.REPORTS_DIR + '/' + report_file_name])

    return "Ok", 200
Esempio n. 15
0
def send_weekly_report(today=None):
    """Task to run weekly for report"""

    today = date.today() if today is None else datetime.strptime(
        today, '%Y-%m-%d')
    start_date = today + timedelta(days=-7)
    end_date = today

    old_start_date = start_date + timedelta(days=-7)
    old_end_date = start_date

    for _request in get_requests(start_date, end_date, True):
        location = Location.i().guess_location(_request)

        del _request['zipcode']
        del _request['lat']
        del _request['long']

        district = location['district']
        neighbourhood = location['neighbourhood']
        location_name = location['location_name']

        report = Report()
        report.id = xstr(_request['service_request_id'])
        report.district = district
        report.neighbourhood = neighbourhood
        report.location_name = location_name
        report.nature = xstr(_request['service_name'])
        report.requested_datetime = (
            xstr(_request['requested_datetime'])[0:10] + " " +
            xstr(_request['requested_datetime'])[11:19])
        report.updated_datetime = (xstr(_request['updated_datetime'])[0:10] +
                                   " " +
                                   xstr(_request['updated_datetime'])[11:19])
        report.type = xstr(_request['service_name'])
        report.status = xstr(_request['service_notice'])
        report.status_notes = xstr(_request.get('status_notes', ''))

        Uow.add(report)
        try:
            Uow.commit()
        except IntegrityError:
            Uow.rollback()
        except Exception as ex:
            Uow.rollback()
            current_app.logger.error("Error While Inserting Report in DB\n" +
                                     traceback.format_exc())

    # Report by State
    # ---------------
    estados_report_rows = Report.get_summary_report(start_date, end_date,
                                                    old_start_date,
                                                    old_end_date)

    # calculate totals for states
    total_occurrences = 0
    total_pct = 0
    total_tempo_medio_resolucao = 0
    total_variacao = 0

    for estado in estados_report_rows:
        total_occurrences += estado["no_occorencias"]
        total_pct += estado["pct_do_total"]
        total_tempo_medio_resolucao += estado["tempo_medio_resolucao"]
        total_variacao += estado.get("variacao") if estado.get(
            "variacao") else 0

    estados_report_rows.append({
        'type': 'TOTAL',
        'no_occorencias': total_occurrences,
        'pct_do_total': total_pct,
        'tempo_medio_resolucao': total_tempo_medio_resolucao,
        'variacao': total_variacao
    })

    # Report by District
    # ------------------
    district_rows = Report.get_summary_by_district_report(
        start_date, end_date, old_start_date, old_end_date)

    # Calculate totals per district
    district_totals = {}
    district_names = []
    districts = {}

    for row in district_rows:
        district_names.append(row["district"])

    district_names = list(set(district_names))  # remove duplicates

    for row in district_rows:
        if not district_totals.get(row["district"]):
            district_totals[row["district"]] = {
                "no_occorencias": 0,
                "pct_do_total": 0,
                "tempo_medio_resolucao": 0,
                "variacao": 0
            }

        district_totals[
            row["district"]]["no_occorencias"] += row["no_occorencias"]
        district_totals[row["district"]]["pct_do_total"] += row["pct_do_total"]
        district_totals[row["district"]]["tempo_medio_resolucao"] += row[
            "tempo_medio_resolucao"]
        district_totals[row["district"]]["variacao"] += row.get("variacao", 0)

    for district in district_names:
        districts[district] = {
            "name": district,
            "totals": district_totals[district],
            "rows": []
        }

        for row in district_rows:
            if row["district"] == district:
                districts[district]["rows"].append(row)

    # Tiago Report
    # ------------
    t_report_rows = Report.get_by_problem(start_date, end_date)
    t_neighbourhood_names = []
    t_neighbourhoods = {}
    problem_types = [
        u"Tchova não passou", u"Contentor está cheio", u"Amontoado de lixo",
        u"Lixo fora do contentor", u"Lixo na vala de drenagem",
        u"Camião não passou", u"Contentor a Arder", u"Entulho na rua",
        u"Ramos no chão"
    ]

    problem_images = map(lambda x: remove_accents(x).lower().replace(' ', '_'),
                         problem_types)

    for row in t_report_rows:
        t_neighbourhood_names.append(row["bairro"])

    t_neighbourhood_names = list(set(t_neighbourhood_names))

    for neighbourhood in t_neighbourhood_names:
        t_neighbourhoods[neighbourhood] = {"name": neighbourhood, "rows": []}

        for row in t_report_rows:
            if row["bairro"] == neighbourhood:
                t_neighbourhoods[neighbourhood]["rows"].append({
                    "problema":
                    row.get("problema", "-"),
                    "registado":
                    row.get("registado", 0),
                    "em_processo":
                    row.get("em_processo", 0),
                    "resolvido":
                    row.get("resolvido", 0),
                    "invalido":
                    row.get("invalido", 0),
                    "total":
                    row.get("total", 0)
                })

    for neighbourhood in t_neighbourhood_names:
        neighbourhood_problems = []

        for row in t_neighbourhoods[neighbourhood]["rows"]:
            neighbourhood_problems.append(row["problema"])

        for problem_type in problem_types:
            if problem_type not in neighbourhood_problems:
                t_neighbourhoods[neighbourhood]["rows"].append({
                    "problema": problem_type,
                    "registado": 0,
                    "em_processo": 0,
                    "resolvido": 0,
                    "invalido": 0,
                    "total": 0
                })

        t_neighbourhoods[neighbourhood]["rows"] = sorted(
            t_neighbourhoods[neighbourhood]["rows"],
            key=lambda i: (-1 * i['total']))

    for neighbourhood in t_neighbourhood_names:
        if t_neighbourhoods[neighbourhood]["rows"][0]["total"] > 0:
            t_neighbourhoods[neighbourhood][
                "most_frequent_problem"] = t_neighbourhoods[neighbourhood][
                    "rows"][0]["problema"]
        else:
            t_neighbourhoods[neighbourhood]["most_frequent_problem"] = None

        t_neighbourhoods[neighbourhood]["rows"] = sorted(
            t_neighbourhoods[neighbourhood]["rows"],
            key=lambda i: (-1 * i['resolvido']))

        if t_neighbourhoods[neighbourhood]["rows"][0]["resolvido"] > 0:
            t_neighbourhoods[neighbourhood][
                "most_solved_problem"] = t_neighbourhoods[neighbourhood][
                    "rows"][0]["problema"]
        else:
            t_neighbourhoods[neighbourhood]["most_solved_problem"] = None

        t_neighbourhoods[neighbourhood]["rows"] = sorted(
            t_neighbourhoods[neighbourhood]["rows"],
            key=lambda i: (-1 * i['total']))

    for neighbourhood in t_neighbourhood_names:
        t_neighbourhoods[neighbourhood][
            "worst_critical_points"] = Report.get_worst_critical_points(
                neighbourhood, start_date, end_date)

    # Generate PDF
    context = {
        'today': today.strftime('%d-%m-%Y'),
        'sumario': {
            'estados': estados_report_rows,
            'district_names': district_names,
            'districts': districts
        },
        'details': {
            'neighbourhood_names': t_neighbourhood_names,
            'neighbourhoods': t_neighbourhoods
        },
        'icons': dict(zip(problem_types, problem_images)),
        'static': os.path.join(config.BASE_DIR, 'templates') + '/'
    }
    report_file_name = 'relatorio-semanal-' + today.strftime(
        '%Y_%m_%d') + '.pdf'
    generate_pdf('weekly_report.html', context, report_file_name)

    # Send mail
    html = '''
<html>
    <head></head>
    <body>
    <p>Sauda&ccedil;&otilde;es!<br/><br/>
        Segue em anexo o relat&oacute;rio MOPA<br/><br/>
        Cumprimentos,<br/>
        <em>Enviado automaticamente</em>
    </p>
    </body>
</html>
            '''
    send_mail('[MOPA] Relatorio Semanal - ' + today.strftime('%Y-%m-%d'),
              html_message=html,
              to=config.WEEKLY_REPORT_TO,
              cc=config.DAILY_REPORT_CC,
              sender=(config.EMAIL_DEFAULT_NAME, config.EMAIL_DEFAULT_SENDER),
              attachments=[config.REPORTS_DIR + '/' + report_file_name])

    return "Ok", 200