concerto_weather 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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