concerto_weather 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,76 @@
1
+
2
+ // attach handler to woeid so when it loses focus we can look it up
3
+ // not dry, but no middle man
4
+ function attachWoeidHandlers() {
5
+ $('input#weather_config_woeid').on('blur', getWoeidInfo);
6
+
7
+ function getWoeidInfo() {
8
+ // will place name, district-county, province-state, country, woeid into 'div.woeid-info'
9
+
10
+ var info = '<p>WOEID details could not be determined.</p>';
11
+ var woeid = $('input#weather_config_woeid').val();
12
+ var info_el = $('.woeid-info');
13
+ var woeidName = $('i.woeid-name');
14
+
15
+ // something was changed, so wipe out the pre-existing woeid name
16
+ if (woeidName.length != 0) {
17
+ $(woeidName).text('');
18
+ }
19
+
20
+ if (info_el.length != 0) {
21
+ // we found the summary box
22
+ $(info_el).empty().html('searching...');
23
+ $.ajax({
24
+ url: "http://query.yahooapis.com/v1/public/yql?q=" + encodeURIComponent("select woeid, placeTypeName, name, admin1, admin2, country from geo.places where (text = \"" + woeid + "\" or woeid = \"" + woeid + "\") limit 5") + "&format=json",
25
+ dataType: 'jsonp',
26
+ timeout: 4000,
27
+ success: function (data) {
28
+
29
+ function htmlEncode(value){
30
+ //create a in-memory div, set it's inner text(which jQuery automatically encodes)
31
+ //then grab the encoded contents back out. The div never exists on the page.
32
+ return $('<div/>').text(value).html();
33
+ }
34
+
35
+ if (data.query && data.query.count > 0 && typeof(data.query.results.place) != "undefined") {
36
+ j = data.query.results.place;
37
+ if (!(j instanceof Array)) {
38
+ j = [ data.query.results.place ];
39
+ }
40
+
41
+ // we got something, should use jq datatables with js array load
42
+ // places = []
43
+ // j.forEach(function(item) {
44
+ // places.push([item.name, item.placeTypeName.content, (item.admin1 ? item.admin1.content : ''),
45
+ // (item.admin2 ? item.admin2.content : ''), item.country.content, item.woeid]);
46
+ // });
47
+
48
+ // icky html table construction (with classes for bootstrap)
49
+ places = "<table class=\"table table-striped table-condensed table-bordered\">";
50
+ places += "<thead><tr><th>Name</th><th>Type</th><th>District/County/Region</th><th>Province/State</th><th>Country</th><th>WOEID</th></th></thead>";
51
+ places += "<tbody>";
52
+ tbody = "";
53
+ j.forEach(function(item) {
54
+ // todo: need htmlencoding
55
+ tbody += "<tr><td>" + htmlEncode(item.name) + "</td><td>" +
56
+ htmlEncode(item.placeTypeName.content) + "</td><td>" +
57
+ htmlEncode((item.admin1 ? item.admin1.content : '')) + "</td><td>" +
58
+ htmlEncode((item.admin2 ? item.admin2.content : '')) + "</td><td>" +
59
+ htmlEncode((item.country ? item.country.content : '')) + "</td><td>" +
60
+ item.woeid + "</td></tr>";
61
+ });
62
+ places += tbody + "</tbody></table>";
63
+ info = places;
64
+ }
65
+ $(info_el).empty().html(info);
66
+ },
67
+ error: function (xoptions, textStatus) {
68
+ $(info_el).empty().html(info);
69
+ }
70
+ });
71
+ }
72
+ }
73
+ }
74
+
75
+ $(document).ready(attachWoeidHandlers);
76
+ $(document).on('page:change', attachWoeidHandlers);
@@ -1,11 +1,18 @@
1
1
  class Weather < DynamicContent
2
2
  DISPLAY_NAME = 'Weather'
3
3
 
4
+ UNITS = {
5
+ 'c' => 'Celsius',
6
+ 'f' => 'Fahrenheit'
7
+ }
8
+
9
+ validate :woeid_must_exist
10
+
4
11
  def build_content
5
12
  require 'rss'
6
13
  require 'net/http'
7
14
 
8
- url = "http://weather.yahooapis.com/forecastrss?p=#{self.config['zip_code']}"
15
+ url = "http://weather.yahooapis.com/forecastrss?w=#{self.config['woeid']}&u=#{self.config['units']}"
9
16
 
10
17
  feed = Net::HTTP.get_response(URI.parse(url)).body
11
18
 
@@ -21,9 +28,44 @@ class Weather < DynamicContent
21
28
  return [htmltext]
22
29
  end
23
30
 
24
- # Weather needs a location.
31
+ # Weather needs a location. Also allow specification of units
25
32
  def self.form_attributes
26
33
  attributes = super()
27
- attributes.concat([:config => [:zip_code]])
34
+ attributes.concat([:config => [:woeid, :units]])
35
+ end
36
+
37
+ def woeid_must_exist
38
+ if !self.config.nil? # had to add thius because rake dynamic_content:refresh was blowing up on nil object
39
+ if self.config['woeid'].empty?
40
+ errors.add(:woeid, 'must be specified')
41
+ else
42
+ data = []
43
+ #begin
44
+ woeid = URI.escape(self.config['woeid'])
45
+ url = URI.escape("http://query.yahooapis.com/v1/public/yql?q=select * from geo.places where woeid = #{woeid} limit 1&format=json")
46
+ uri = URI.parse(url)
47
+ http = Net::HTTP.new(uri.host, uri.port)
48
+ request = Net::HTTP::Get.new(uri.request_uri)
49
+ response = http.request(request)
50
+ if response.code == '200' #ok
51
+ json = response.body
52
+ data = ActiveSupport::JSON.decode(json)
53
+ end
54
+ #rescue
55
+ # Rails.logger.debug("Yahoo not reachable @ #{url}.")
56
+ # return
57
+ #end
58
+ if data.empty? || data['query']['count'] == 0
59
+ errors.add(:woeid, 'not valid')
60
+ else
61
+ results = data['query']['results']['place']
62
+ info = results['name']
63
+ info = info + ', ' + results['admin1']['content'] if !results['admin1']['content'].empty? if !results['admin1'].nil?
64
+ info = info + ', ' + results['admin2']['content'] if !results['admin2']['content'].empty? if !results['admin2'].nil?
65
+ info = info + ', ' + results['country']['content'] if !results['country']['content'].empty? if !results['country'].nil?
66
+ self.config['name'] = info
67
+ end
68
+ end
69
+ end
28
70
  end
29
71
  end
@@ -1,11 +1,28 @@
1
+ <%= javascript_include_tag "weather" %>
2
+
1
3
  <fieldset>
2
4
  <legend><span>Weather</span></legend>
3
- <%= form.fields_for :config do |config| %>
4
- <div class="clearfix">
5
- <%= config.label :zip_code %>
6
- <div class="input">
7
- <%= config.text_field 'zip_code', :placeholder => '12180', :size => 10 %>
5
+ <div class="row-fluid">
6
+ <div class='span4'>
7
+ <%= form.fields_for :config do |config| %>
8
+ <div class="clearfix">
9
+ <%= config.label :woeid, "Where On Earth ID (WOEID)" %>
10
+ <div class="input">
11
+ <%= config.text_field :woeid, :placeholder => '12180', :class => "input-small", :value => @content.config['woeid'] %>
12
+ <br/>
13
+ <i class="woeid-name"><%= @content.config['name'] %></i>
14
+ </div>
8
15
  </div>
16
+ <div class="clearfix">
17
+ <%= config.label :units %>
18
+ <div class="input">
19
+ <%= config.select :units, Weather::UNITS.map {|k,v| [v, k]}, :selected => @content.config['units'] %>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ <% end %>
24
+ <div>
25
+ <div class='woeid-info span8'></div>
9
26
  </div>
10
- <% end %>
27
+ </div>
11
28
  </fieldset>
@@ -1,6 +1,8 @@
1
1
  <dl>
2
- <dt>Zip Code</dt>
3
- <dd><%= content.config['zip_code'] %></dd>
2
+ <dt>WOEID</dt>
3
+ <dd><%= content.config['woeid'] %> - <%= content.config['name'] %></dd>
4
+ <dt>Units</dt>
5
+ <dd><%= Weather::UNITS[content.config['units']] %></dd>
4
6
  <dt>Last Successful Update</dt>
5
7
  <dd><%= content.config.include?('last_ok_refresh') ? Time.at(content.config['last_ok_refresh']).strftime('%c') : 'Never' %></dd>
6
8
  <dt>Last Attempted Update</dt>
@@ -1 +1 @@
1
- <h1>Weather for <%= content.config['zip_code'] %></h1>
1
+ <h1>Weather for <%= content.config['woeid'] %> - <%= content.config['name'] %></h1>
@@ -1,3 +1,3 @@
1
1
  module ConcertoWeather
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concerto_weather
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-19 00:00:00.000000000 -07:00
12
+ date: 2013-05-30 00:00:00.000000000 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
- requirement: &70183968575400 !ruby/object:Gem::Requirement
17
+ requirement: &70160991282920 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 3.2.12
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70183968575400
25
+ version_requirements: *70160991282920
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: sqlite3
28
- requirement: &70183968574960 !ruby/object:Gem::Requirement
28
+ requirement: &70160991282400 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70183968574960
36
+ version_requirements: *70160991282400
37
37
  description: Show the current weather and a short forecast in the sidebar of Concerto
38
38
  2.
39
39
  email:
@@ -42,6 +42,7 @@ executables: []
42
42
  extensions: []
43
43
  extra_rdoc_files: []
44
44
  files:
45
+ - app/assets/javascripts/weather.js
45
46
  - app/assets/stylesheets/concerto_weather/application.css
46
47
  - app/controllers/concerto_weather/application_controller.rb
47
48
  - app/helpers/concerto_weather/application_helper.rb