Module: Radiotagmap

Defined in:
lib/radiotagmap.rb

Class Method Summary collapse

Class Method Details

.get_map_color(weights = [0.5, 0.2]) ⇒ Object

Returns the color with which to represent a U.S. state on a map depending on the most played genre/tag in its FM radios.

Parameters

state

The 2-letters code of the U.S. state where to search

among

Array of arrays of admitted genres/tags. Each sub-array indicates equivalent words. The result is the index of the most played family of genres/tags in this array.

Examples

get_map_color "CA", [['Rock', 'Indie Rock'], ['Country', 'Alt Country']]

– TODO: Parametrize, allowing users to specify among and colors



96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/radiotagmap.rb', line 96

def self.get_map_color(weights = [0.5, 0.2])
  a = "aa"
  if weights.nil?
    a << "999999"
  else
    value = weights[0]
    @max_weight = [@max_weight, value].max
    value = value/@max_weight unless @max_weight.zero?
    r = "ff" # "%02x" % (255*weights[0]).round
    b = "%02x" % (255*(1-value)).round
    g = "ff" #"%02x" % (255*(1-weights.sum)).round
    a << b << b << r # The more country, the more red
  end
end

.get_tags_weight(state = "CA", among = [['Country'], ['Rock']]) ⇒ Object

Returns the index of the family of genres/tags that is currently most playing on the FM radios of a given U.S. state.

Parameters

state

The 2-letters code of the U.S. state where to search

among

Array of arrays of admitted genres/tags. Each sub-array indicates equivalent words. The result is the index of the most played family of genres/tags in this array.

Examples

get_main_tag "CA", [['Rock', 'Indie Rock'], ['Country', 'Alt Country']]



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/radiotagmap.rb', line 29

def self.get_tags_weight(state = "CA", among = [['Country'], ['Rock']])
  among = among.collect{|family| family.collect(&:downcase)}
  
  # stations = Yesradio::search_stations(:loc => state) 
  stations = Yesradio::search_stations(:match => ", #{state}")
  return if stations.nil?
  @log.debug "#{state} | #{stations.length} stations"

  threads = []
  for station in stations
    threads << Thread.new(station) do |st|
      Yesradio::get_station :name => st.name
    end
  end
  artists = threads.collect{|aThread| aThread.join.value.array_artist}.compact
  return if artists.nil?
  @log.debug "#{state} | #{artists.length} artists"
  @log.debug "#{state} | #{artists.join(' ')}"
  
  # The same function as above, but without threads, would be:
  # artists = stations.collect do |station| 
  #   Yesradio::get_station :name => station.name
  # end.collect(&:array_artist).compact
  # return if artists.nil?
  
  threads = []
  for artist in artists
    threads << Thread.new(artist) do |ar|
      ar_tags = Scrobbler::Artist.new(artist).top_tags.first(10).collect do |tag|
        tag.name.downcase
      end
      top_tag = (ar_tags & among.flatten).first
      among.collect {|family| family.include?(top_tag)}.index(true)
    end
  end
  tags = threads.collect{|aThread| aThread.join.value}
  return if tags.nil?
  @log.debug "#{state} | #{tags.length} tags"
  @log.debug "#{state} | #{tags.join(' ')}"

  # The same function as above, but without threads, would be:
  # tags = artists.collect do |artist| 
  #   ar_tags = Scrobbler::Artist.new(artist).top_tags.first(10).map do |tag|
  #     tag.name.downcase
  #   end
  #   top_tag = (ar_tags & among.flatten).first
  #   among.collect {|family| family.include?(top_tag)}.index(true)
  # end # .compact to remove other tags

  weights = (0...among.size).collect do |index|
    tags.select{|x| x == index}.size/tags.size.to_f
  end
end

.update_kml(kml_path = "./overlay.kml", among = [['Country']], forever = true) ⇒ Object

Update a KML file (or create if inexistent) with the overlays of the U.S. states, colored according to the most played genres/tags in their FM radios.

Parameters

among

Array of arrays of admitted genres/tags. Each sub-array indicates equivalent words. The result is the index of the most played family of genres/tags in this array.

forever

If true, the updating process continues forever

Examples

update_kml



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/radiotagmap.rb', line 123

def self.update_kml(kml_path = "./overlay.kml", among = [['Country']], forever = true)
  @log.level = Logger::INFO
  begin
    # TO DO: to increase contrast in color, call one get_map_color
    # passing the entire array, so that the MAX is first calculated
    # (e.g. the state with more country only has 6/10 country artists)
    # and then the contrast of colors is normalized based on that value
    STATES_COORDS.each do |state, coords|
      color = get_map_color(get_tags_weight(state, among))
      @log.debug "#{state} | The new color is #{color}"

      if File.exists?(kml_path)
        kml_file = File.open(kml_path, 'r+')
        xml = Nokogiri::XML(kml_file)
        @log.debug "#{state} | KML map created"
      else
        kml_file = File.new(kml_path, 'w') # TODO: create ancestor folders
        xml = create_kml
        @log.debug "#{state} | KML map loaded"
      end

      xml.xpath("kml/Document/Style[@id='#{state}']/PolyStyle/color").first.content = color
      @log.debug "#{state} | Color updated"
    
      kml_file.rewind
      kml_file.write(xml)
      kml_file.close
    end
    @log.info "Updated KML with all the states"
  end while forever  
end