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.
- data/app/assets/javascripts/weather.js +76 -0
- data/app/models/weather.rb +45 -3
- data/app/views/contents/weather/_form_top.html +23 -6
- data/app/views/contents/weather/_render_default.html.erb +4 -2
- data/app/views/contents/weather/_render_tile.html.erb +1 -1
- data/lib/concerto_weather/version.rb +1 -1
- metadata +7 -6
@@ -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);
|
data/app/models/weather.rb
CHANGED
@@ -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?
|
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 => [:
|
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
|
-
|
4
|
-
<div class=
|
5
|
-
|
6
|
-
<div class="
|
7
|
-
<%= config.
|
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
|
-
|
27
|
+
</div>
|
11
28
|
</fieldset>
|
@@ -1,6 +1,8 @@
|
|
1
1
|
<dl>
|
2
|
-
<dt>
|
3
|
-
<dd><%= content.config['
|
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['
|
1
|
+
<h1>Weather for <%= content.config['woeid'] %> - <%= content.config['name'] %></h1>
|
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.
|
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-
|
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: &
|
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: *
|
25
|
+
version_requirements: *70160991282920
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: sqlite3
|
28
|
-
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: *
|
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
|