<commit_before># coding: utf-8
namespace :import do
  desc 'Add rinks from donnees.ville.montreal.qc.ca'
  task montreal: :environment do
    flip = 1
    Nokogiri::XML(RestClient.get('http://www2.ville.montreal.qc.ca/services_citoyens/pdf_transfert/L29_PATINOIRE.xml')).css('patinoire').each do |node|
      # Add m-dash, except for Ahuntsic-Cartierville.
      nom_arr = node.at_css('nom_arr').text.
        sub('Ahuntsic - Cartierville', 'Ahuntsic-Cartierville').
        sub('Villeray-Saint-Michel - Parc-Extension', 'Villeray—Saint-Michel—Parc-Extension').
        sub('L\'Île-Bizard - Sainte-Geneviève', "L'Île-Bizard—Sainte-Geneviève").
        gsub(' - ', '—')

      arrondissement = Arrondissement.find_or_initialize_by_nom_arr(nom_arr)
      arrondissement.cle = node.at_css('cle').text
      arrondissement.date_maj = Time.parse node.at_css('date_maj').text
      arrondissement.source = 'donnees.ville.montreal.qc.ca'

      begin
        arrondissement.save!

        patinoire = Patinoire.find_or_initialize_by_nom_and_arrondissement_id(node.at_css('nom').text, arrondissement.id)
        %w(ouvert deblaye arrose resurface condition).each do |attribute|
          patinoire[attribute] = node.at_css(attribute).text
        end

        description = case patinoire.nom
        when 'Patinoire bandes Pierre-Bédard (PSE)', 'patinoire extérieure (PSE)'
          'Patinoire avec bandes'
        when 'Patinoire B<NAME>, <NAME> (PSE)', 'Patinoire Bleu-Blanc-Bouge (PSE)', 'Patinoire Bleu Blanc Bouge, François-Perrault-réfr (PSE)', 'Patinoire Bleu Blanc Bouge du parc Hayward (PSE)'
          'Patinoire réfrigérée Bleu-Blanc-Bouge'
        when 'lalancette (PPL)', 'Patinoire extérieure Domaine Chartier (PPL)', 'Patinoire du Glacis (PP)'
          'Patinoire de patin libre'
        when 'Patinoire décorative Toussaint-Louverture (PP)'
          'Patinoire décorative'
        else
          patinoire.nom[/\A(.+?) ?(?:no [1-3]|nord|sud)?(?:,|-| du parc\b)/, 1] || patinoire.nom
        end

        patinoire.description = {
          'Anneau à patiner'           => 'Anneau de glace',
          'Pat. avec bandes'           => 'Patinoire avec bandes',
          'Pati déco'                  => 'Patinoire décorative',
          'Patinoire à bandes'         => 'Patinoire avec bandes',
          'Patinoire avec bande'       => 'Patinoire avec bandes',
          'Patinoire bandes'           => 'Patinoire avec bandes',
          'Patinoire ext. avec bandes' => 'Patinoire avec bandes',
        }.reduce(description) do |string,(from,to)|
          string.sub(/#{Regexp.escape from}\z/, to)
        end

        patinoire.genre = patinoire.nom[/\((PP|PPL|PSE)\)\z/, 1]

        patinoire.disambiguation = (patinoire.nom[/\A(Petite|Grande)\b/i, 1] || patinoire.nom[/[^-]\b(nord|sud|no \d)\b/i, 1]).andand.downcase
#        patinoire.disambiguation ||= "bbb-canadiens" if patinoire.nom[/(Bleu(\W)?Blanc(\W)?Bouge\b)|(\bBBB\b)\b/i, 1]
        patinoire.disambiguation ||= "no #{$1}" if patinoire.nom[/ (\d),/, 1]
        patinoire.disambiguation ||= 'réfrigérée' if patinoire.description == 'Patinoire réfrigérée' || patinoire.description == 'Patinoire réfrigérée Bleu-Blanc-Bouge'

        # Expand/correct park names.
        parc = patinoire.nom[/, ([^(]+?)(?: no \d)? \(/, 1] || patinoire.nom[/ du parc (.+) \(/, 1] || patinoire.nom[/(.+) \(/, 1]
        patinoire.parc = {
          'C-de-la-Rousselière'              => '<NAME>',
          'Cité-Jardin'                      => 'de la Cité Jardin',
          'de la Rive-Boisé'                 => 'de la Rive-Boisée',
          'De la Petite-Italie'              => 'Petite Italie',
          'Des Hirondelles'                  => 'des Hirondelles',
          'Duff court'                       => '<NAME>',
          'François-Perrault-réfr'           => 'François-Perrault',
          'Ignace-Bourget-anneau de vitesse' => 'Ignace-Bourget',
          'lalancette'                       => 'Lalancette',
          'Lac aux Castors'                  => 'Lac aux Castors',
          'Lac aux castors'                  => 'Lac aux Castors',
          'Lac des castors'                  => 'Lac aux Castors',
          'Marc-Aurèle-Fortin'               => 'Hans-Selye',
          'Patinoire bandes Pierre-Bédard'   => 'Pierre-Bédard',
          'Saint-Aloysis'                    => 'Saint-Aloysius',
          'Sainte-Maria-Goretti'             => 'Maria-Goretti',
          'Y-Thériault/Sherbrooke'           => 'Yves-Thériault/Sherbrooke',
          'Patinoire extérieure <NAME>'=> '<NAME>',
          # Need to do independent research to find where these are.
          'patinoire extérieure'             => '',
          'Patino<NAME> du parc Hayward (PSE)'=> 'Hayward',
          'Patinoire décorative Toussaint-Louverture'=> 'Toussaint-Louverture',
          'Patinoire du Glacis'=> 'du Glacis',
          '<NAME>'=> 'Roger-Rousseau',
        }.reduce(parc) do |string,(from,to)|
          string.sub(/#{Regexp.escape from}\z/, to)
        end
        patinoire.parc.slice!(/\AParc /i)

        # Remove disambiguation from description.
        patinoire.description.slice!(/ (\d|Nord|Sud)\z/)

        # "Aire de patinage libre" with "PSE" is nonsense.
        if patinoire.nom == 'Aire de patinage libre, Kent (sud) (PSE)'
          patinoire.genre = 'PPL'
        end

        # There is no "no 2".
        if patinoire.nom == 'Patinoire de patin libre, Le Prévost no 1 (PPL)'
          patinoire.parc = 'Le Prévost'
          patinoire.disambiguation = nil
        end
        
        # There is no "no 2", also require a valid description
        if ['Patinoire # 1, <NAME> (PSE)', 'Patinoire # 1, <NAME> (PSE)', 'Patinoire # 1, <NAME> (PSE)'].include? patinoire.nom
          patinoire.disambiguation = nil
          patinoire.description = 'Patinoire de hockey'
        end
        
        # Require a valid description
        if ['Patinoire # 2 , <NAME>ne-Dostie (PSE)', 'Patinoire # 1 , Parc Eugène-Dostie (PSE)'].include? patinoire.nom
          patinoire.description = 'Patinoire de hockey'
        end

        # There are identical lines.
        if patinoire.parc == 'LaSalle' && patinoire.genre == 'PSE'
          patinoire.disambiguation = "no #{flip}"
          flip = flip == 1 ? 2 : 1
        end

        # CDN Bleu-Blanc-Bouge rink 
        if patinoire.description == 'Patinoire réfrigérée Bleu-Blanc-Bouge'
          # CDN BBB rink is missing the Park name
          if arrondissement.cle == 'cdn'
            patinoire.parc = 'de la Confédération'
            # Following line is to have a clean name in the API output
            patinoire.nom = 'Patinoire réfrigérée Bleu-Blanc-Bouge, parc de la Confédération (PSE)'
            patinoire.disambiguation = 'réfrigérée'
          end            
          # Temporary solution (early december) for refrigerated rinks
#           patinoire.ouvert = true
#           patinoire.condition = 'N/A'
        end
        
        patinoire.source = 'donnees.ville.montreal.qc.ca'
        begin
          patinoire.save!
        rescue => e
          puts "#{e.inspect}: #{patinoire.inspect}"
        end
      rescue => e
        puts "#{e.inspect}: #{arrondissement.inspect}"
      end
    end
  end

  desc 'Add rinks from montreal-west.ca'
  task montrealwest: :environment do
    arrondissement = Arrondissement.find_or_initialize_by_nom_arr('Montréal-Ouest')
    arrondissement.source = 'montreal-west.ca'
    arrondissement.date_maj = Time.now
    arrondissement.save!

    # http://www.montreal-west.ca/en/outdoor-rinks/
    Nokogiri::HTML(RestClient.get('http://www.montreal-west.ca/fr/patinoires-exterieur/')).css('table[border] tr:gt(1)').each do |tr|
      text = tr.at_css('td:eq(1)').text.gsub(/[[:space:]]/, ' ').strip
      attributes = case text
      when 'Terrain Hodgson - Patinoire'
        {
          parc: 'Hodgson',
          genre: 'PPL',
          arrondissement_id: arrondissement.id,
        }
      when 'Terrain Hodgson - Patinoire de hockey'
        {
          parc: 'Hodgson',
          genre: 'PSE',
          arrondissement_id: arrondissement.id,
        }
      when 'Parc Rugby'
        {
          parc: 'Rugby',
          genre: 'PPL',
          arrondissement_id: arrondissement.id,
        }
      else
        puts "Unknown rink '#{text}'"
        next
      end

      attributes.merge!({
        ouvert: tr.at_css('td:eq(2)').text.gsub(/[[:space:]]/, ' ').strip == 'oui',
        deblaye: tr.at_css('td:eq(3)').text.gsub(/[[:space:]]/, ' ').strip == 'oui',
        arrose: tr.at_css('td:eq(4)').text.gsub(/[[:space:]]/, ' ').strip == 'oui',
        source: 'montreal-west.ca',
      })

      condition = tr.at_css('td:eq(5)').text.gsub(/[[:space:]]/, ' ').strip
      attributes[:condition] = case condition
      when 'excellente'
        'Excellente'
      when 'bonne'
        'Bonne'
      when 'mauvaise'
        'Mauvaise'
      else
        puts "Unknown condition '#{condition}'" unless condition.blank?
        'N/A'
      end

      patinoire = Patinoire.find_or_initialize_by_parc_and_genre_and_arrondissement_id attributes[:parc], attributes[:genre], arrondissement.id
      patinoire.attributes = attributes
      patinoire.save!
    end
  end

  # Dorval changed the location and layout of their page.
  # desc 'Add rinks from ville.dorval.qc.ca'
  # task dorval: :environment do
  #   arrondissement = Arrondissement.find_or_initialize_by_nom_arr('Dorval')
  #   arrondissement.source = 'ville.dorval.qc.ca'
  #   arrondissement.date_maj = Time.now
  #   arrondissement.save!

  #   Nokogiri::HTML(RestClient.get('http://www.ville.dorval.qc.ca/loisirs/fr/default.asp?contentID=808')).css('tr:gt(2)').each do |tr|
  #     condition = 'N/A'<commit_msg>Updates names for winter 2016<commit_after># coding: utf-8
namespace :import do
  desc 'Add rinks from donnees.ville.montreal.qc.ca'
  task montreal: :environment do
    flip = 1
    Nokogiri::XML(RestClient.get('http://www2.ville.montreal.qc.ca/services_citoyens/pdf_transfert/L29_PATINOIRE.xml')).css('patinoire').each do |node|
      # Add m-dash, except for Ahuntsic-Cartierville.
      nom_arr = node.at_css('nom_arr').text.
        sub('Ahuntsic - Cartierville', 'Ahuntsic-Cartierville').
        sub('Villeray-Saint-Michel - Parc-Extension', 'Villeray—Saint-Michel—Parc-Extension').
        sub('Côte-des-Neiges - Notre-Dame-de-Grâce', 'Côte-des-Neiges—Notre-Dame-de-Grâce').
        sub('L\'Île-Bizard - Sainte-Geneviève', "L'Île-Bizard—Sainte-Geneviève").
        gsub(' - ', '—')

      arrondissement = Arrondissement.find_or_initialize_by_nom_arr(nom_arr)
      arrondissement.cle = node.at_css('cle').text
      arrondissement.date_maj = Time.parse node.at_css('date_maj').text
      arrondissement.source = 'donnees.ville.montreal.qc.ca'

      begin
        arrondissement.save!

        patinoire = Patinoire.find_or_initialize_by_nom_and_arrondissement_id(node.at_css('nom').text, arrondissement.id)
        %w(ouvert deblaye arrose resurface condition).each do |attribute|
          patinoire[attribute] = node.at_css(attribute).text
        end

        description = case patinoire.nom
        when 'Patinoire bandes Pierre-Bédard (PSE)', 'patinoire extérieure (PSE)', 'Patinoire De Gaspé/Bernard (PSE)'
          'Patinoire avec bandes'
        when 'Patinoire Bleu Blanc Bouge, Parc Willibrord (PSE)', 'Patinoire Bleu-Blanc-Bouge (PSE)', 'Patinoire Bleu Blanc Bouge, François-Perrault-réfr (PSE)', 'Patinoire Bleu Blanc Bouge du parc Hayward (PSE)', 'Patinoire Bleu, Blanc, Bouge du parc Le Carignan (PSE)'
          'Patinoire réfrigérée Bleu-Blanc-Bouge'
        when 'lalancette (PPL)', 'Patinoire extérieure Domaine Chartier (PPL)', 'Patinoire du Glacis (PP)', 'Patinoire de parin libre du parc Sauvé (PPL)'
          'Patinoire de patin libre'
        when 'Patinoire décorative Toussaint-Louverture (PP)', 'Patinoire décorative Parc Arthur-Therrien (PP)', 'Patinoire du parc Aimé-Léonard (PP)', 'Centre comm R-Goupil, Patinoire décorative (PP)'
          'Patinoire décorative'
        else
          patinoire.nom[/\A(.+?) ?(?:no [1-3]|nord|sud)?(?:,|-| du parc\b)/, 1] || patinoire.nom
        end

        patinoire.description = {
          'Anneau à patiner'           => 'Anneau de glace',
          'Pat. avec bandes'           => 'Patinoire avec bandes',
          'Pati déco'                  => 'Patinoire décorative',
          'Patinoire à bandes'         => 'Patinoire avec bandes',
          'Patnoire à bandes'          => 'Patinoire avec bandes',
          'Patinoire avec bande'       => 'Patinoire avec bandes',
          'Patinoire bandes'           => 'Patinoire avec bandes',
          'Patinoire ext. avec bandes' => 'Patinoire avec bandes',
        }.reduce(description) do |string,(from,to)|
          string.sub(/#{Regexp.escape from}\z/, to)
        end

        patinoire.genre = patinoire.nom[/\((PP|PPL|PSE)\)\z/, 1]

        patinoire.disambiguation = (patinoire.nom[/\A(Petite|Grande)\b/i, 1] || patinoire.nom[/[^-]\b(nord|sud|no \d)\b/i, 1]).andand.downcase
#        patinoire.disambiguation ||= "bbb-canadiens" if patinoire.nom[/(Bleu(\W)?Blanc(\W)?Bouge\b)|(\bBBB\b)\b/i, 1]
        patinoire.disambiguation ||= "no #{$1}" if patinoire.nom[/ (\d),/, 1]
        patinoire.disambiguation ||= 'réfrigérée' if patinoire.description == 'Patinoire réfrigérée' || patinoire.description == 'Patinoire réfrigérée Bleu-Blanc-Bouge'

        # Expand/correct park names.
        parc = patinoire.nom[/, ([^(]+?)(?: no \d)? \(/, 1] || patinoire.nom[/ du parc (.+) \(/, 1] || patinoire.nom[/(.+) \(/, 1]
        patinoire.parc = {
          'C-de-la-Rousselière'              => '<NAME>',
          'Cité-Jardin'                      => 'de la Cité Jardin',
          'de la Rive-Boisé'                 => 'de la Rive-Boisée',
          'De la Petite-Italie'              => 'Petite Italie',
          'Des Hirondelles'                  => 'des Hirondelles',
          'Duff court'                       => '<NAME>',
          'François-Perrault-réfr'           => 'François-Perrault',
          'Ignace-Bourget-anneau de vitesse' => 'Ignace-Bourget',
          'lalancette'                       => 'Lalancette',
          'Lac aux Castors'                  => 'Lac aux Castors',
          'Lac aux castors'                  => 'Lac aux Castors',
          'Lac des castors'                  => 'Lac aux Castors',
          'Marc-Aurèle-Fortin'               => 'Hans-Selye',
          'Patinoire bandes Pierre-Bédard'   => 'Pierre-Bédard',
          'Saint-Aloysis'                    => 'Saint-Aloysius',
          'Sainte-Maria-Goretti'             => 'Maria-Goretti',
          'Y-Thériault/Sherbrooke'           => 'Yves-Thériault/Sherbrooke',
          'Patinoire extérieure <NAME>'=> '<NAME>',
          # Need to do independent research to find where these are.
          'patinoire extérieure'             => '',
          'Patinoire Bleu Blanc Bouge du parc Hayward'=> 'Hayward',
          'Blanc, Bouge du parc Le Carignan'=> 'Le Carignan',
          'Patinoire décorative Toussaint-Louverture'=> 'Toussaint-Louverture',
          'Patinoire du Glacis'=> 'du Glacis',
          '<NAME>'=> 'Roger-Rousseau',
#           'Centre comm R-Goupil, Patinoire décorative'=> 'Centre communautaire René-Goupil',
          'Patinoire décorative Parc Arthur-Therrien'=> 'Arthur-Therrien',
          'Patinoire du parc Aimé-Léonard'=> 'Aimé-Léonard',
          'Patinoire <NAME>/Bernard'=> 'Champ des possibles'
        }.reduce(parc) do |string,(from,to)|
          string.sub(/#{Regexp.escape from}\z/, to)
        end
        patinoire.parc.slice!(/\AParc /i)

        # Remove disambiguation from description.
        patinoire.description.slice!(/ (\d|Nord|Sud)\z/)

        # "Aire de patinage libre" with "PSE" is nonsense.
        if patinoire.nom == 'Aire de patinage libre, Kent (sud) (PSE)'
          patinoire.genre = 'PPL'
        end

        # There is no "no 2".
        if patinoire.nom == 'Patinoire de patin libre, Le Prévost no 1 (PPL)'
          patinoire.parc = 'Le Prévost'
          patinoire.disambiguation = nil
        end
        
        # There is no "no 2", also require a valid description
        if ['Patinoire # 1, <NAME> (PSE)', 'Patinoire # 1, <NAME> (PSE)', 'Patinoire # 1, <NAME> (PSE)'].include? patinoire.nom
          patinoire.disambiguation = nil
          patinoire.description = 'Patinoire de hockey'
        end
        
        # Require a valid description
        if ['Patinoire # 2 , <NAME>ostie (PSE)', 'Patinoire # 1 , Parc Eugène-Dostie (PSE)'].include? patinoire.nom
          patinoire.description = 'Patinoire de hockey'
        end

        # There are identical lines.
        if patinoire.parc == 'LaSalle' && patinoire.genre == 'PSE'
          patinoire.disambiguation = "no #{flip}"
          flip = flip == 1 ? 2 : 1
        end

        # CDN Bleu-Blanc-Bouge rink 
        if patinoire.description == 'Patinoire réfrigérée Bleu-Blanc-Bouge'
          # CDN BBB rink is missing the Park name
          if arrondissement.cle == 'cdn'
            patinoire.parc = 'de la Confédération'
            # Following line is to have a clean name in the API output
            patinoire.nom = 'Patinoire réfrigérée Bleu-Blanc-Bouge, parc de la Confédération (PSE)'
            patinoire.disambiguation = 'réfrigérée'
          end            
          # Temporary solution (early december) for refrigerated rinks
#           patinoire.ouvert = true
#           patinoire.condition = 'N/A'
        end
        
        patinoire.source = 'donnees.ville.montreal.qc.ca'
        begin
          patinoire.save!
        rescue => e
          puts "#{e.inspect}: #{patinoire.inspect}"
        end
      rescue => e
        puts "#{e.inspect}: #{arrondissement.inspect}"
      end
    end
  end

  desc 'Add rinks from montreal-west.ca'
  task montrealwest: :environment do
    arrondissement = Arrondissement.find_or_initialize_by_nom_arr('Montréal-Ouest')
    arrondissement.source = 'montreal-west.ca'
    arrondissement.date_maj = Time.now
    arrondissement.save!

    # http://www.montreal-west.ca/en/outdoor-rinks/
    Nokogiri::HTML(RestClient.get('http://www.montreal-west.ca/fr/patinoires-exterieur/')).css('table[border] tr:gt(1)').each do |tr|
      text = tr.at_css('td:eq(1)').text.gsub(/[[:space:]]/, ' ').strip
      attributes = case text
      when 'Terrain Hodgson - Patinoire'
        {
          parc: 'Hodgson',
          genre: 'PPL',
          arrondissement_id: arrondissement.id,
        }
      when 'Terrain Hodgson - Patinoire de hockey'
        {
          parc: 'Hodgson',
          genre: 'PSE',
          arrondissement_id: arrondissement.id,
        }
      when 'Terrain Hodgson - Patinoire de hockey Mini'
        {
          parc: 'Hodgson',
          genre: 'PSE',
          arrondissement_id: arrondissement.id,
        }
      when '<NAME>'
        {
          parc: 'Rugby',
          genre: 'PPL',
          arrondissement_id: arrondissement.id,
        }
      else
        puts "Unknown rink '#{text}'"
        next
      end

      attributes.merge!({
        ouvert: tr.at_css('td:eq(2)').text.gsub(/[[:space:]]/, ' ').strip == 'oui',
        deblaye: tr.at_css('td:eq(3)').text.gsub(/[[:space:]]/, ' ').strip == 'oui',
        arrose: tr.at_css('td:eq(4)').text.gsub(/[[:space:]]/, ' ').strip == 'oui',
        source: 'montreal-west.ca',
      })

      condition = tr.at_css('td:eq(5)').text.gsub(/[[:space:]]/, ' ').strip
      attributes[:condition] = case condition
      when 'excellente', 'Excellent'
        'Excellente'
      when 'bonne', 'Bon'
        'Bonne'
      when 'mauvaise'
        'Mauvaise'
      else
        puts "Unknown condition '#{condition}'" unless condition.blank?
        'N/A'
      end

      patinoire = Patinoire.find_or_initialize_by_parc_and_genre_and_arrondissement_id attributes[:parc], attributes[:genre], arrondissement.id
      patinoire.attributes = attributes
      patinoire.save!
    end
  end

  # Dorval changed the location and layout of their page.
  # desc 'Add rinks from ville.dorval.qc.ca'
  # task dorval: :environment do
  #   arrondissement = Arrondissement.find_or_initialize_by_nom_arr('Dorval')
  #   arrondissement.source = 'ville.dorval.qc.ca'
  #   arrondissement.date_maj = Time.now
  #   arrondissement.save!

  #   Nokogiri::HTML(RestClient.get('http://www.ville.dorval.qc.ca/loisirs/fr/default.asp?contentID=808')).css('tr:gt(2)').each do |tr|
  #     condition = 'N/A'
{'fraction_non_alphanumeric': 0.14058923788653518, 'fraction_numerical': 0.0038957876795714633, 'mean_word_length': 2.231979855209317, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 8, 'xml': 2}, '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': '4295717', 'n_tokens_mistral': 7227, 'n_tokens_neox': 7081, 'n_words': 1439}