def save_school(self, school_data):
        required_fields = {'LNG', 'LAT', 'CO_ENTIDADE', 'NO_ENTIDADE'}

        if required_fields - set(school_data.keys()) == set():
            brasil_environment_map = {
                'urbana': 'urban',
                'rural': 'rural',
            }
            environment = school_data.get('TP_LOCALIZACAO', '').lower()
            environment = brasil_environment_map.get(environment, environment)

            school, created = School.objects.update_or_create(
                external_id=school_data['CO_ENTIDADE'],
                country=self.country,
                defaults={
                    'name': school_data['NO_ENTIDADE'],
                    'geopoint': Point(x=school_data['LNG'], y=school_data['LAT']),
                    'environment': environment,
                    'admin_1_name': school_data.get('NM_ESTADO', ''),
                    'admin_4_name': school_data.get('NM_MUNICIP', ''),
                },
            )

            date = timezone.now().date()
            school_weekly = SchoolWeeklyStatus.objects.filter(
                school=school, week=date.isocalendar()[1], year=date.isocalendar()[0],
            ).last()

            if not school_weekly:
                school_weekly = SchoolWeeklyStatus.objects.filter(school=school).last()

                if school_weekly:
                    # copy latest available one
                    school_weekly.id = None
                    school_weekly.year = get_current_year()
                    school_weekly.week = get_current_week()
                else:
                    school_weekly = SchoolWeeklyStatus.objects.create(
                        school=school,
                        year=get_current_year(),
                        week=get_current_week(),
                    )

            school_weekly.connectivity = True
            school_weekly.computer_lab = bool(int(float(school_data.get('QT_COMP_ALUNO', 0))))
            school_weekly.num_computers = int(float(school_data.get('QT_COMPUTADOR', 0)))
            school_weekly.connectivity_type = school_data.get(
                'TIPO_TECNOLOGIA', SchoolWeeklyStatus._meta.get_field('connectivity_type').default,
            )
            school_weekly.save()
Exemple #2
0
    def test_aggregate_country_daily_status_to_country_weekly_status(self):
        CountryDailyStatusFactory(country=self.country,
                                  date=datetime.now().date())
        SchoolWeeklyStatusFactory(
            school__country=self.country,
            connectivity=True,
            connectivity_speed=4000000,
            coverage_availability=True,
            coverage_type='unknown',
            year=get_current_year(),
            week=get_current_week(),
        )
        SchoolWeeklyStatusFactory(
            school__country=self.country,
            connectivity_speed=6000000,
            year=get_current_year(),
            week=get_current_week(),
        )

        country_weekly = CountryWeeklyStatus.objects.filter(
            country=self.country).last()
        if not country_weekly.is_verified:
            country_weekly.update_country_status_to_joined()

        update_country_weekly_status(self.country)
        self.assertEqual(
            CountryWeeklyStatus.objects.filter(country=self.country).count(),
            1)
        self.assertEqual(
            CountryWeeklyStatus.objects.filter(
                country=self.country).last().connectivity_speed, 5000000)

        country_weekly = CountryWeeklyStatus.objects.filter(
            country=self.country).last()
        self.assertEqual(country_weekly.integration_status,
                         CountryWeeklyStatus.REALTIME_MAPPED)
        self.assertEqual(
            country_weekly.connectivity_availability,
            CountryWeeklyStatus.CONNECTIVITY_TYPES_AVAILABILITY.realtime_speed)
        self.assertEqual(
            country_weekly.coverage_availability, CountryWeeklyStatus.
            COVERAGE_TYPES_AVAILABILITY.coverage_availability)
Exemple #3
0
def aggregate_school_daily_status_to_school_weekly_status(country) -> bool:
    date = timezone.now().date()
    week_ago = date - timedelta(days=7)
    schools = School.objects.filter(
        country=country,
        id__in=SchoolDailyStatus.objects.filter(
            date__gte=week_ago, ).values_list(
                'school',
                flat=True).order_by('school_id').distinct('school_id'),
    ).iterator()

    updated = False

    for school in schools:
        updated = True
        school_weekly, created = SchoolWeeklyStatus.objects.get_or_create(
            school=school,
            week=get_current_week(),
            year=get_current_year(),
        )

        aggregate = SchoolDailyStatus.objects.filter(
            school=school,
            date__gte=week_ago,
        ).aggregate(
            Avg('connectivity_speed'),
            Avg('connectivity_latency'),
        )

        school_weekly.connectivity = True
        school_weekly.connectivity_speed = aggregate['connectivity_speed__avg']
        school_weekly.connectivity_latency = aggregate[
            'connectivity_latency__avg']

        prev_weekly = SchoolWeeklyStatus.objects.filter(
            school=school, date__lt=school_weekly.date).last()
        if prev_weekly:
            school_weekly.num_students = prev_weekly.num_students
            school_weekly.num_teachers = prev_weekly.num_teachers
            school_weekly.num_classroom = prev_weekly.num_classroom
            school_weekly.num_latrines = prev_weekly.num_latrines
            school_weekly.running_water = prev_weekly.running_water
            school_weekly.electricity_availability = prev_weekly.electricity_availability
            school_weekly.computer_lab = prev_weekly.computer_lab
            school_weekly.num_computers = prev_weekly.num_computers

        school_weekly.save()

    return updated
Exemple #4
0
    def test_aggregate_school_daily_status_to_school_weekly_status_connectivity_no(
            self):
        today = datetime.now().date()
        SchoolDailyStatusFactory(school=self.school,
                                 connectivity_speed=None,
                                 date=today - timedelta(days=8))
        SchoolWeeklyStatusFactory(
            school=self.school,
            week=get_current_week(),
            year=get_current_year(),
            connectivity=False,
        )

        aggregate_school_daily_status_to_school_weekly_status(self.country)
        self.assertEqual(SchoolWeeklyStatus.objects.count(), 1)
        self.assertEqual(SchoolWeeklyStatus.objects.last().connectivity, False)
Exemple #5
0
    def test_aggregate_school_daily_status_to_school_weekly_status_connectivity_unknown(
            self):
        # daily status is too old, so it wouldn't be involved into country calculations
        today = datetime.now().date()
        SchoolDailyStatusFactory(school=self.school,
                                 connectivity_speed=None,
                                 date=today - timedelta(days=8))
        SchoolWeeklyStatusFactory(
            school=self.school,
            week=get_current_week(),
            year=get_current_year(),
            connectivity=None,
        )

        aggregate_school_daily_status_to_school_weekly_status(self.country)
        self.assertEqual(SchoolWeeklyStatus.objects.count(), 1)
        self.assertEqual(SchoolWeeklyStatus.objects.last().connectivity, None)
Exemple #6
0
def update_country_weekly_status(country: Country):
    last_weekly_status_country = country.last_weekly_status
    country_status, created = CountryWeeklyStatus.objects.get_or_create(
        country=country,
        year=get_current_year(),
        week=get_current_week(),
    )
    if created:
        country.last_weekly_status = country_status
        country.save()
        country.last_weekly_status.integration_status = last_weekly_status_country.integration_status
        country.last_weekly_status.save(update_fields=('integration_status', ))

    # calculate pie charts. first we need to understand which case is applicable for country
    latest_statuses = SchoolWeeklyStatus.objects.filter(
        school__country=country, _school__isnull=False)
    connectivity_types = CountryWeeklyStatus.CONNECTIVITY_TYPES_AVAILABILITY
    coverage_types = CountryWeeklyStatus.COVERAGE_TYPES_AVAILABILITY

    if RealTimeConnectivity.objects.filter(school__country=country).exists():
        country_status.connectivity_availability = connectivity_types.realtime_speed
        connectivity_stats = aggregate_connectivity_by_speed(latest_statuses)
    elif latest_statuses.filter(connectivity_speed__gte=0).exists():
        country_status.connectivity_availability = connectivity_types.static_speed
        connectivity_stats = aggregate_connectivity_by_speed(latest_statuses)
    elif latest_statuses.filter(connectivity__isnull=False).exists():
        country_status.connectivity_availability = connectivity_types.connectivity
        connectivity_stats = aggregate_connectivity_by_availability(
            latest_statuses)
    else:
        country_status.connectivity_availability = connectivity_types.no_connectivity
        connectivity_stats = aggregate_connectivity_default(latest_statuses)

    if latest_statuses.exclude(
            coverage_type=SchoolWeeklyStatus.COVERAGE_TYPES.unknown).exists():
        country_status.coverage_availability = coverage_types.coverage_type
        coverage_stats = aggregate_coverage_by_types(latest_statuses)
    elif latest_statuses.filter(coverage_availability__isnull=False).exists():
        country_status.coverage_availability = coverage_types.coverage_availability
        coverage_stats = aggregate_coverage_by_availability(latest_statuses)
    else:
        country_status.coverage_availability = coverage_types.no_coverage
        coverage_stats = aggregate_coverage_default(latest_statuses)

    # remember connectivity pie chart
    country_status.schools_connectivity_good = connectivity_stats[
        ColorMapSchema.GOOD]
    country_status.schools_connectivity_moderate = connectivity_stats[
        ColorMapSchema.MODERATE]
    country_status.schools_connectivity_no = connectivity_stats[
        ColorMapSchema.NO]
    country_status.schools_connectivity_unknown = connectivity_stats[
        ColorMapSchema.UNKNOWN]

    # remember coverage pie chart
    country_status.schools_coverage_good = coverage_stats[ColorMapSchema.GOOD]
    country_status.schools_coverage_moderate = coverage_stats[
        ColorMapSchema.MODERATE]
    country_status.schools_coverage_no = coverage_stats[ColorMapSchema.NO]
    country_status.schools_coverage_unknown = coverage_stats[
        ColorMapSchema.UNKNOWN]

    # calculate speed & latency where available
    schools_stats = latest_statuses.aggregate(
        total=Count('*'),
        connectivity_speed=Avg('connectivity_speed',
                               filter=Q(connectivity_speed__gt=0)),
        connectivity_latency=Avg('connectivity_latency',
                                 filter=Q(connectivity_latency__gt=0)),
    )

    country_status.connectivity_speed = schools_stats['connectivity_speed']
    country_status.connectivity_latency = schools_stats['connectivity_latency']

    country_status.schools_total = schools_stats['total']
    schools_with_data = country_status.schools_connectivity_moderate + country_status.schools_connectivity_good
    country_status.schools_connected = schools_with_data
    if country_status.schools_total:
        country_status.schools_with_data_percentage = 1.0 * country_status.schools_connected
        country_status.schools_with_data_percentage /= country_status.schools_total
    else:
        country_status.schools_with_data_percentage = 0

    # move country status as far as we can
    if country_status.integration_status == CountryWeeklyStatus.COUNTRY_CREATED and country_status.schools_total:
        country_status.integration_status = CountryWeeklyStatus.SCHOOL_OSM_MAPPED

    if country_status.integration_status == CountryWeeklyStatus.JOINED and country_status.schools_total:
        country_status.integration_status = CountryWeeklyStatus.SCHOOL_MAPPED

    if country_status.integration_status == CountryWeeklyStatus.SCHOOL_MAPPED and any(
        [
            country_status.schools_connectivity_good,
            country_status.schools_connectivity_moderate,
            country_status.schools_connectivity_no,
            country_status.schools_coverage_good,
            country_status.schools_coverage_moderate,
            country_status.schools_coverage_no,
        ]):
        country_status.integration_status = CountryWeeklyStatus.STATIC_MAPPED

    if country_status.integration_status == CountryWeeklyStatus.STATIC_MAPPED \
            and country_status.connectivity_availability == connectivity_types.realtime_speed:
        country_status.integration_status = CountryWeeklyStatus.REALTIME_MAPPED

    country_status.avg_distance_school = country.calculate_avg_distance_school(
    )

    country_status.save()