<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4 nu

from __future__ import (unicode_literals, absolute_import,
                        division, print_function)
import logging
import datetime
from collections import OrderedDict

from django.utils import timezone

from snisi_core.models.Providers import Provider
from snisi_core.models.Entities import Entity
from snisi_core.models.Periods import MonthPeriod
from snisi_core.models.Reporting import (ExpectedReporting, ReportClass)
from snisi_nutrition import PROJECT_BRAND
from snisi_nutrition.models.Weekly import NutWeekPeriod
from snisi_nutrition.integrity import (
    create_nut_weekly_report,
    WeeklyNutritionRIntegrityChecker,
    NutritionRIntegrityChecker, create_nut_report,
    URENAMNutritionRIntegrityChecker,
    URENASNutritionRIntegrityChecker,
    URENINutritionRIntegrityChecker,
    StocksNutritionRIntegrityChecker)
from snisi_sms.reply import SMSReply

logger = logging.getLogger(__name__)
reportcls_nut = ReportClass.get_or_none(slug='nutrition_monthly_routine')
reportcls_nut_week = ReportClass.get_or_none(slug='nutrition_weekly_routine')


def nut_handler(message):
    if message.content.lower().startswith('nut '):
        return NUT_HANDLERS.get(
            message.content.lower().split(' ', 2)[1])(message)

    return False

KEYWORDS = {
    'nut': nut_handler,
}


def weekly_report(message):

    """
        nut w username password month year

            <all fields> (see args_names)
    """

    reply = SMSReply(message, PROJECT_BRAND)

    # create variables from text messages.
    try:
        args_names = ['kw', 'w', 'username', 'password',
                      'urenam_screening',
                      'urenam_cases',
                      'urenam_deaths',
                      'urenas_screening',
                      'urenas_cases',
                      'urenas_deaths',
                      'ureni_screening',
                      'ureni_cases',
                      'ureni_deaths']

        args_values = message.content.strip().lower().split()
        arguments = dict(zip(args_names, args_values))
        assert len(args_values) == len(args_names)
    except (ValueError, AssertionError):
        # failure to split means we proabably lack a data or more
        # we can't process it.
        return reply.error("Le format du SMS est incorrect.")

    # convert form-data to int or bool respectively
    try:
        for key, value in arguments.items():
            if key in ('kw', 'w'):
                continue
            elif key in ('username', 'password'):
                arguments[key] = value.strip()
            else:
                arguments[key] = int(value)
    except:
        logger.warning("Unable to convert/cast SMS data: {}"
                       .format(message.content))
        # failure to convert means non-numeric value which we can't process.
        return reply.error("Les données sont malformées.")

    # check credentials
    try:
        provider = Provider.active.get(username=arguments['username'])
    except Provider.DoesNotExist:
        return reply.error("Ce nom d'utilisateur ({}) n'existe pas."
                           .format(arguments['username']))

    if not provider.check_password(arguments['password']):
        return reply.error("Votre mot de passe est incorrect.")

    # now we have well formed and authenticated data.
    # let's check for business-logic errors.
    checker = WeeklyNutritionRIntegrityChecker()

    # feed data holder with sms provided data
    for key, value in arguments.items():
        checker.set(key, value)

    # harmonized meta-data
    try:
        hc = Entity.get_or_none(provider.location.slug)
    except:
        hc = None
    checker.set('entity', hc)
    checker.set('hc', getattr(hc, 'slug', None))
    today = datetime.date.today()
    checker.set('fillin_day', today.day)
    checker.set('fillin_month', today.month)
    checker.set('fillin_year', today.year)
    checker.set('reporting_date', today)
    checker.set('submit_time', message.event_on)
    checker.set('author', provider.name())
    checker.set('submitter', provider)

    # test the data
    checker.check(has_ureni=hc.has_ureni)
    if not checker.is_valid():
        return reply.error(checker.errors.pop().render(short=True))

    # build requirements for report
    period = NutWeekPeriod.find_create_by_date(today).previous()

    entity = checker.get('entity')

    # expected reporting defines if report is expeted or not
    expected_reporting = ExpectedReporting.get_or_none(
        report_class=reportcls_nut_week,
        period=period,
        within_period=False,
        entity=entity,
        within_entity=False,
        amount_expected=ExpectedReporting.EXPECTED_SINGLE)

    # should have already been checked in checker.
    if expected_reporting is None:
        logger.error("Expected reporting not found: "
                     "cls:{cls} - period:{period} - entity:{entity}"
                     .format(cls=reportcls_nut_week,
                             period=period, entity=entity))
        return reply.error("Aucun rapport hedbo attendu à "
                           "{entity} pour {period}"
                           .format(entity=entity, period=period))

    report, text_message = create_nut_weekly_report(
        provider=provider,
        expected_reporting=expected_reporting,
        completed_on=timezone.now(),
        integrity_checker=checker,
        data_source=message.content)

    if report:
        return reply.success(text_message)
    else:
        return reply.error(text_message)


def fix_sms_from_v15(stocks_data):
    nstr = stocks_data

    # head
    if nstr.startswith('-1-'):
        nstr = nstr.replace('-1-', '0-', 1)

    # body
    while '--1-' in nstr:
        nstr = nstr.replace('--1-', '-0-', 1)

    # tail
    if nstr.endswith('--1'):
        nstr = nstr[:-3] + "-0"

    return nstr


def monthly_report(message):

    """
        nut username password month year

            <all fields> (see args_names)
    """

    reply = SMSReply(message, PROJECT_BRAND)

    # create variables from text messages.
    try:
        args_names = [
            'kw', 'kw2', 'username', 'password',<commit_msg>fixed incoing sms with localized thousands<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4 nu

from __future__ import (unicode_literals, absolute_import,
                        division, print_function)
import logging
import datetime
from collections import OrderedDict

from django.utils import timezone

from snisi_core.models.Providers import Provider
from snisi_core.models.Entities import Entity
from snisi_core.models.Periods import MonthPeriod
from snisi_core.models.Reporting import (ExpectedReporting, ReportClass)
from snisi_nutrition import PROJECT_BRAND
from snisi_nutrition.models.Weekly import NutWeekPeriod
from snisi_nutrition.integrity import (
    create_nut_weekly_report,
    WeeklyNutritionRIntegrityChecker,
    NutritionRIntegrityChecker, create_nut_report,
    URENAMNutritionRIntegrityChecker,
    URENASNutritionRIntegrityChecker,
    URENINutritionRIntegrityChecker,
    StocksNutritionRIntegrityChecker)
from snisi_sms.reply import SMSReply

logger = logging.getLogger(__name__)
reportcls_nut = ReportClass.get_or_none(slug='nutrition_monthly_routine')
reportcls_nut_week = ReportClass.get_or_none(slug='nutrition_weekly_routine')


def nut_handler(message):
    if message.content.lower().startswith('nut '):
        return NUT_HANDLERS.get(
            message.content.lower().split(' ', 2)[1])(message)

    return False

KEYWORDS = {
    'nut': nut_handler,
}


def weekly_report(message):

    """
        nut w username password month year

            <all fields> (see args_names)
    """

    reply = SMSReply(message, PROJECT_BRAND)

    # create variables from text messages.
    try:
        args_names = ['kw', 'w', 'username', 'password',
                      'urenam_screening',
                      'urenam_cases',
                      'urenam_deaths',
                      'urenas_screening',
                      'urenas_cases',
                      'urenas_deaths',
                      'ureni_screening',
                      'ureni_cases',
                      'ureni_deaths']

        args_values = message.content.strip().lower().split()
        arguments = dict(zip(args_names, args_values))
        assert len(args_values) == len(args_names)
    except (ValueError, AssertionError):
        # failure to split means we proabably lack a data or more
        # we can't process it.
        return reply.error("Le format du SMS est incorrect.")

    # convert form-data to int or bool respectively
    try:
        for key, value in arguments.items():
            if key in ('kw', 'w'):
                continue
            elif key in ('username', 'password'):
                arguments[key] = value.strip()
            else:
                arguments[key] = int(value)
    except:
        logger.warning("Unable to convert/cast SMS data: {}"
                       .format(message.content))
        # failure to convert means non-numeric value which we can't process.
        return reply.error("Les données sont malformées.")

    # check credentials
    try:
        provider = Provider.active.get(username=arguments['username'])
    except Provider.DoesNotExist:
        return reply.error("Ce nom d'utilisateur ({}) n'existe pas."
                           .format(arguments['username']))

    if not provider.check_password(arguments['password']):
        return reply.error("Votre mot de passe est incorrect.")

    # now we have well formed and authenticated data.
    # let's check for business-logic errors.
    checker = WeeklyNutritionRIntegrityChecker()

    # feed data holder with sms provided data
    for key, value in arguments.items():
        checker.set(key, value)

    # harmonized meta-data
    try:
        hc = Entity.get_or_none(provider.location.slug)
    except:
        hc = None
    checker.set('entity', hc)
    checker.set('hc', getattr(hc, 'slug', None))
    today = datetime.date.today()
    checker.set('fillin_day', today.day)
    checker.set('fillin_month', today.month)
    checker.set('fillin_year', today.year)
    checker.set('reporting_date', today)
    checker.set('submit_time', message.event_on)
    checker.set('author', provider.name())
    checker.set('submitter', provider)

    # test the data
    checker.check(has_ureni=hc.has_ureni)
    if not checker.is_valid():
        return reply.error(checker.errors.pop().render(short=True))

    # build requirements for report
    period = NutWeekPeriod.find_create_by_date(today).previous()

    entity = checker.get('entity')

    # expected reporting defines if report is expeted or not
    expected_reporting = ExpectedReporting.get_or_none(
        report_class=reportcls_nut_week,
        period=period,
        within_period=False,
        entity=entity,
        within_entity=False,
        amount_expected=ExpectedReporting.EXPECTED_SINGLE)

    # should have already been checked in checker.
    if expected_reporting is None:
        logger.error("Expected reporting not found: "
                     "cls:{cls} - period:{period} - entity:{entity}"
                     .format(cls=reportcls_nut_week,
                             period=period, entity=entity))
        return reply.error("Aucun rapport hedbo attendu à "
                           "{entity} pour {period}"
                           .format(entity=entity, period=period))

    report, text_message = create_nut_weekly_report(
        provider=provider,
        expected_reporting=expected_reporting,
        completed_on=timezone.now(),
        integrity_checker=checker,
        data_source=message.content)

    if report:
        return reply.success(text_message)
    else:
        return reply.error(text_message)


def fix_sms_from_v15(stocks_data):
    nstr = stocks_data

    # fix locale on thousands
    nstr = nstr.replace(',', '')

    # head
    if nstr.startswith('-1-'):
        nstr = nstr.replace('-1-', '0-', 1)

    # body
    while '--1-' in nstr:
        nstr = nstr.replace('--1-', '-0-', 1)

    # tail
    if nstr.endswith('--1'):
        nstr = nstr[:-3] + "-0"

    return nstr


def monthly_report(message):

    """
        nut username password month year

            <all fields> (see args_names)
    """

    reply = SMSReply(message, PROJECT_BRAND)

    # create variables from text messages.
    try:
        args_names = [
            'kw', 'kw2', 'username', 'password',
{'fraction_non_alphanumeric': 0.10155448591493726, 'fraction_numerical': 0.003156316578552829, 'mean_word_length': 2.545174825174825, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1340902', 'n_tokens_mistral': 3793, 'n_tokens_neox': 3635, 'n_words': 860}