class GouvCalendarCompilator::France::SchoolHolidaysDataCompilator

Manages the compilation of different school holidays data sources and compile them into a new, properly formatted one

Public Class Methods

new() click to toggle source

Initializer for School Holidays data compiler

# File lib/gouv_calendar_compilator/data_compilators/france/school_holidays_data_compilator.rb, line 14
def initialize
  @data_fetcher = ::GouvCalendarCompilator::DataFetcher.new
end

Public Instance Methods

compile() click to toggle source

This is the method you want to call to compile the school holidays into a proper dataset. It returns a ruby Array of Hashes

# File lib/gouv_calendar_compilator/data_compilators/france/school_holidays_data_compilator.rb, line 20
def compile
  school_holidays_data_full = @data_fetcher.fetch_school_holidays_data
  school_holidays_data_trimmed = sh_trim_not_necessary_data(school_holidays_data_full)
  zones = sh_define_possible_zones(school_holidays_data_trimmed)
  sh_format_zones_data(school_holidays_data_trimmed, zones, school_holidays_data_full)
end

Private Instance Methods

calculate_approximate_end_date(trimmed_dataset, raw_dataset, vacation_index) click to toggle source

Calculates an approximate end date based on same vacations, for same region of the world, from an other year

# File lib/gouv_calendar_compilator/data_compilators/france/school_holidays_data_compilator.rb, line 30
def calculate_approximate_end_date(trimmed_dataset, raw_dataset, vacation_index)
  vacation_type = trimmed_dataset[vacation_index]['fields']['description']
  vacation_location = trimmed_dataset[vacation_index]['fields']['location']

  filtered_data =
    raw_dataset.select do |record|
      record['fields']['description'] == vacation_type && record['fields']['location'] == vacation_location
    end
  date_range = nil

  filtered_data.each do |vacation|
    next unless vacation['fields']['end_date']

    start_date = ::Date.parse(vacation['fields']['start_date'])
    end_date = ::Date.parse(vacation['fields']['end_date'])
    date_range = (start_date...end_date)
    break
  end

  approximate_end_date = ::Date.parse(trimmed_dataset[vacation_index]['fields']['start_date']) + date_range.count
  approximate_end_date.to_date.to_s
end
calculate_approximate_start_date(trimmed_dataset, raw_dataset, vacation_index) click to toggle source

Calculates an approximate start date based on same vacations, for same region of the world, from an other year

# File lib/gouv_calendar_compilator/data_compilators/france/school_holidays_data_compilator.rb, line 54
def calculate_approximate_start_date(trimmed_dataset, raw_dataset, vacation_index)
  vacation_type = trimmed_dataset[vacation_index]['fields']['description']
  vacation_location = trimmed_dataset[vacation_index]['fields']['location']

  filtered_data =
    raw_dataset.select do |record|
      record['fields']['description'] == vacation_type && record['fields']['location'] == vacation_location
    end
  date_range = nil

  filtered_data.each do |vacation|
    next unless vacation['fields']['start_date'] && vacation['fields']['description'] == vacation_type

    start_date = ::Date.parse(vacation['fields']['start_date'])
    end_date = ::Date.parse(vacation['fields']['end_date'])
    date_range = (start_date...end_date)
    break
  end

  approximate_start_date = ::Date.parse(trimmed_dataset[vacation_index]['fields']['end_date']) - date_range.count
  approximate_start_date.to_date.to_s
end
sh_define_possible_zones(school_holidays) click to toggle source

Returns an array of strings corresponding to each of the existing zones in the school holidays dataset

# File lib/gouv_calendar_compilator/data_compilators/france/school_holidays_data_compilator.rb, line 104
def sh_define_possible_zones(school_holidays)
  zones = []
  school_holidays.each do |record|
    zones << record['fields']['zones']
  end
  zones.uniq
end
sh_format_zones_data(school_holidays, zones, sh_data_full) click to toggle source

Returns the formatted school holidays data for all zones

# File lib/gouv_calendar_compilator/data_compilators/france/school_holidays_data_compilator.rb, line 113
def sh_format_zones_data(school_holidays, zones, sh_data_full)
  formatted_zones_data = {}
  zones.each do |zone_name|
    zone_specific_holidays_data = school_holidays.select { |record| record['fields']['zones'] == zone_name }
    zone_specific_holidays_data_full = sh_data_full.select { |record| record['fields']['zones'] == zone_name }
    records_contianer = []
    zone_specific_holidays_data.each_with_index do |holiday_record, index|
      holiday_start_date = (if holiday_record['fields']['start_date'].nil?
                              calculate_approximate_start_date(
                                zone_specific_holidays_data,
                                zone_specific_holidays_data_full,
                                index
                              )
                            else
                              ::Date.parse(holiday_record['fields']['start_date']).to_s
                            end)
      holiday_end_date = (if holiday_record['fields']['end_date'].nil?
                            calculate_approximate_end_date(
                              zone_specific_holidays_data,
                              zone_specific_holidays_data_full,
                              index
                            )
                          else
                            ::Date.parse(holiday_record['fields']['end_date']).to_s
                          end)
      records_contianer.push(
        {
          start: holiday_start_date,
          end: holiday_end_date,
          coefficient: ::GouvCalendarCompilator::SCHOOL_HOLIDAYS
        }
      )
    end
    formatted_zones_data[zone_name] = records_contianer
  end
  formatted_zones_data
end
sh_trim_not_necessary_data(raw_sh_dataset) click to toggle source

Trims dataset to desired time era and remove possibly wrong data.

Example of bad data: “end_date”=>“2023-07-08T00:00:00+02:00”, “start_date”=>“2023-07-08T00:00:00+02:00”, “zones”=>“Zone C”, “description”=>“Debut des Vacances d’ete”

Almost “OK” data but not needed here, and that should appear as a national day off somewhere else. “end_date”=>“2020-03-19T00:00:00+01:00”, “start_date”=>“2020-03-19T00:00:00+01:00”, “zones”=>“Guadeloupe”, “description”=>“Mi-careme”

# File lib/gouv_calendar_compilator/data_compilators/france/school_holidays_data_compilator.rb, line 86
def sh_trim_not_necessary_data(raw_sh_dataset)
  date_range = ::GouvCalendarCompilator::DATETIME_START...::GouvCalendarCompilator::DATETIME_END
  filtered_data =
    raw_sh_dataset.select do |record|
      date_range.include?(::Date.parse(record['fields']['start_date'])) &&
        (record['fields']['end_date'] ? date_range.include?(::Date.parse(record['fields']['end_date'])) : true) &&
        record['fields']['start_date'] != record['fields']['end_date']
    end
  filtered_data.uniq do |record|
    [
      record['fields']['start_date'],
      record['fields']['description'],
      record['fields']['zones']
    ].join(':')
  end
end