weather_fetcher 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -5,4 +5,5 @@ group :development do
5
5
  gem "bundler", "~> 1.0.0"
6
6
  gem "jeweler", "~> 1.6.4"
7
7
  gem "rcov", ">= 0"
8
+ gem "rdoc"
8
9
  end
data/Gemfile.lock CHANGED
@@ -7,8 +7,11 @@ GEM
7
7
  bundler (~> 1.0)
8
8
  git (>= 1.2.5)
9
9
  rake
10
+ json (1.6.1)
10
11
  rake (0.9.2.2)
11
12
  rcov (0.9.11)
13
+ rdoc (3.11)
14
+ json (~> 1.4)
12
15
  rspec (2.3.0)
13
16
  rspec-core (~> 2.3.0)
14
17
  rspec-expectations (~> 2.3.0)
@@ -25,4 +28,5 @@ DEPENDENCIES
25
28
  bundler (~> 1.0.0)
26
29
  jeweler (~> 1.6.4)
27
30
  rcov
31
+ rdoc
28
32
  rspec (~> 2.3.0)
data/README.rdoc CHANGED
@@ -1,12 +1,17 @@
1
1
  = weather_fetcher
2
2
 
3
- Fetch weather from various Polish websites and via other gems
3
+ Fetch weather from various Polish websites and via other gems.
4
4
 
5
5
  == How to use
6
6
 
7
- It is very early gem. More feature coming soon.
7
+ It is very early gem. More feature coming soon. At this moment you can use 3 providers: Onet.pl,
8
+ Wp.pl and Interia.pl.
8
9
 
9
- The simplest way to use is:
10
+ There is simple 'how to use' code below. _defs_ is Hash object with proper data. Refactoring is on
11
+ the way, so read this file later.
12
+
13
+
14
+ = Onet.pl
10
15
 
11
16
  weathers = WeatherFetcher::Provider::OnetPl.new(defs).fetch
12
17
 
@@ -19,6 +24,35 @@ Where _defs_ is something like this:
19
24
  :lat: 52.799264
20
25
  :lon: 18.259935
21
26
 
27
+
28
+ == Wp.pl
29
+
30
+ weathers = WeatherFetcher::Provider::WpPl.new(defs).fetch
31
+
32
+ Where _defs_ is something like this:
33
+
34
+ - :url: 'http://pogoda.wp.pl/miasto,bydgoszcz,mid,1201023,mi.html'
35
+ :city: 'Bydgoszcz'
36
+ :country: 'Poland'
37
+ :coord:
38
+ :lat: 53.128893
39
+ :lon: 18.006363
40
+
41
+
42
+ == Interia.pl
43
+
44
+ weathers = WeatherFetcher::Provider::InteriaPl.new(defs).fetch
45
+
46
+ Where _defs_ is something like this:
47
+
48
+ - :url: 'http://pogoda.interia.pl/miasta?id=11721'
49
+ :city: 'Inowrocław'
50
+ :country: 'Poland'
51
+ :coord:
52
+ :lat: 52.799264
53
+ :lon: 18.259935
54
+
55
+
22
56
  == Contributing to weather_fetcher
23
57
 
24
58
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
data/Rakefile CHANGED
@@ -38,7 +38,8 @@ end
38
38
 
39
39
  task :default => :spec
40
40
 
41
- require 'rake/rdoctask'
41
+ require 'rdoc'
42
+ require 'rdoc/task'
42
43
  Rake::RDocTask.new do |rdoc|
43
44
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
45
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
@@ -0,0 +1,9 @@
1
+ module WeatherFetcher
2
+ class ProviderList
3
+ def self.providers
4
+ classes = WeatherFetcher::Provider.constants - ['TYPE']
5
+ classes.collect{|c| WeatherFetcher::Provider.const_get c}
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,129 @@
1
+ #encoding: utf-8
2
+
3
+ module WeatherFetcher
4
+ class Provider::InteriaPl < HtmlBased
5
+
6
+ def self.provider_name
7
+ "Interia.pl"
8
+ end
9
+
10
+ def process(string)
11
+ @weathers += _process(string)
12
+ end
13
+
14
+ # Process response body and rip out weather data
15
+ def _process(body_raw)
16
+
17
+ body = body_raw.downcase
18
+
19
+ hours_first = body.scan(/(\d{2})\s*do\s*(\d{2})/)
20
+ #puts hours_first.inspect
21
+ hours_add = body.scan(/<td height=\"40\">.*(\d{2})-(\d{2}).*<\/td>/)
22
+ #puts hours_add.inspect
23
+ hours = hours_first + hours_add
24
+ #puts hours.inspect
25
+
26
+ # interia uses min/aesthes./max temperatures, aesth. used
27
+ temperatures = body.scan(/<span\s*class=\"tex2b\"\s*style=\"font-size:\s*14px;\">(-?\d+)<\/span>/)
28
+ # there is 'sample' temperature which should be deleted
29
+ temperatures.delete_at(2) # if temperatures[2] == 5
30
+ #puts temperatures.inspect
31
+
32
+ winds = body.scan(/wiatr:\D*(\d+)\D*km\/h\s*</)
33
+ #puts winds.inspect
34
+
35
+ rains = body.scan(/deszcz:\D*(\d+\.?\d*)\D*mm\s*</)
36
+ #puts rains.inspect
37
+
38
+ snows = body.scan(/nieg:\D*(\d+\.?\d*)\D*mm\s*</)
39
+ #puts snows.inspect
40
+
41
+ pressures = body.scan(/<b>(\d{3,4})<\/b>.*hpa/)
42
+ #puts pressures.inspect
43
+
44
+ # TODO fix it better!
45
+ #puts rains.inspect
46
+ #puts snows.inspect
47
+ if snows.nil? or snows.size < 2
48
+ snows = [[nil], [nil], [nil]]
49
+ end
50
+ if rains.nil? or rains.size < 2
51
+ rains = [[nil], [nil], [nil]]
52
+ end
53
+
54
+ unix_time_today = Time.mktime(
55
+ Time.now.year,
56
+ Time.now.month,
57
+ Time.now.day,
58
+ 0, 0, 0, 0)
59
+
60
+ unix_time_now_from = unix_time_today + 3600 * hours[0][0].to_i
61
+ unix_time_now_to = unix_time_today + 3600 * hours[0][1].to_i
62
+ if hours[0][1].to_i < hours[0][0].to_i
63
+ # next day
64
+ unix_time_now_to += 24 * 3600
65
+ end
66
+
67
+ unix_time_soon_from = unix_time_today + 3600 * hours[1][0].to_i
68
+ unix_time_soon_to = unix_time_today + 3600 * hours[1][1].to_i
69
+ if hours[1][1].to_i < hours[1][0].to_i
70
+ # next day
71
+ unix_time_soon_to += 24 * 3600
72
+ end
73
+ if hours[1][0].to_i > hours[1][0].to_i
74
+ # time soon is whole new day
75
+ unix_time_soon_from += 24 * 3600
76
+ unix_time_soon_to += 24 * 3600
77
+ end
78
+
79
+ # if 1 data is for next day morning
80
+ if hours[0][1].to_i < Time.now.hour
81
+ unix_time_now_to += 24 * 3600
82
+ unix_time_now_from += 24 * 3600
83
+
84
+ unix_time_soon_to += 24 * 3600
85
+ unix_time_soon_from += 24 * 3600
86
+ end
87
+
88
+ # TODO zrób auto testy dla innych typów
89
+ # TODO i dodaj inkrementacje dnia po
90
+ # if 1 data is for next day morning
91
+ if unix_time_now_to > unix_time_soon_to
92
+ unix_time_soon_to += 24 * 3600
93
+ unix_time_soon_from += 24 * 3600
94
+ end
95
+
96
+ data = [
97
+ {
98
+ :time_created => Time.now,
99
+ :time_from => unix_time_now_from,
100
+ :time_to => unix_time_now_to,
101
+ :temperature => temperatures[0][0].to_f,
102
+ :pressure => pressures[0][0].to_f,
103
+ :wind_kmh => winds[0][0].to_f,
104
+ :wind => winds[0][0].to_f / 3.6,
105
+ :snow => snows[0][0].to_f,
106
+ :rain => rains[0][0].to_f,
107
+ :provider => self.class.provider_name
108
+ },
109
+ {
110
+ :time_created => Time.now,
111
+ :time_from => unix_time_soon_from,
112
+ :time_to => unix_time_soon_to,
113
+ :temperature => temperatures[1][0].to_f,
114
+ :pressure => pressures[1][0].to_f,
115
+ :wind_kmh => winds[1][0].to_f,
116
+ :wind => winds[1][0].to_f / 3.6,
117
+ :snow => snows[1][0].to_f,
118
+ :rain => rains[1][0].to_f,
119
+ :provider => self.class.provider_name
120
+ }
121
+ ]
122
+
123
+ return data
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+
@@ -150,8 +150,7 @@ module WeatherFetcher
150
150
  :wind => winds[i],
151
151
  :snow => snows[i],
152
152
  :rain => rains[i],
153
- :provider => self.class.provider_name,
154
- :weather_provider_id => id
153
+ :provider => self.class.provider_name
155
154
  }
156
155
  data << h
157
156
  end
@@ -160,4 +159,6 @@ module WeatherFetcher
160
159
  end
161
160
 
162
161
  end
162
+
163
163
  end
164
+
@@ -0,0 +1,119 @@
1
+ #encoding: utf-8
2
+
3
+ module WeatherFetcher
4
+ class Provider::WpPl < HtmlBased
5
+
6
+ def self.provider_name
7
+ "Interia.pl"
8
+ end
9
+
10
+ def process(string)
11
+ @weathers += _process(string)
12
+ end
13
+
14
+ # Process response body and rip out weather data
15
+ def _process(body_raw)
16
+
17
+ body = body_raw.downcase
18
+
19
+ # days from detailed weather
20
+ days = body.scan(/(\d{1,2})\.(\d{1,2})\.(\d{4})/)
21
+ #puts days.inspect
22
+ #puts days.size
23
+
24
+ hours = body.scan(/(\d{2})-(\d{2})/)
25
+ hours = hours.select { |h| h[0].to_i <= 24 and h[1].to_i <= 24 }
26
+ #puts hours.inspect
27
+ #puts hours.size
28
+
29
+ # create times
30
+ i_day = 0
31
+ times = Array.new
32
+
33
+ (0...(hours.size)).each do |ih|
34
+ # next day
35
+ if ih > 0 and hours[ih][0].to_i < hours[ih - 1][0].to_i
36
+ i_day += 1
37
+ end
38
+
39
+ # can not create time with hour 24
40
+ hour_from = hours[ih][0].to_i
41
+ hour_from = 0 if hour_from == 24
42
+ time_from = Time.mktime(
43
+ days[i_day][2].to_i,
44
+ days[i_day][1].to_i,
45
+ days[i_day][0].to_i,
46
+ hour_from,
47
+ 0,
48
+ 0,
49
+ 0
50
+ )
51
+ time_from += 24*3600 if hours[ih][0].to_i == 24
52
+
53
+ hour_to = hours[ih][1].to_i
54
+ hour_to = 0 if hour_to == 24
55
+ time_to = Time.mktime(
56
+ days[i_day][2].to_i,
57
+ days[i_day][1].to_i,
58
+ days[i_day][0].to_i,
59
+ hour_to,
60
+ 0,
61
+ 0,
62
+ 0
63
+ )
64
+ time_to += 24*3600 if hours[ih][1].to_i == 24
65
+
66
+ h = { :time_from => time_from, :time_to => time_to }
67
+ times << h
68
+ end
69
+ # puts times.to_yaml
70
+ #puts times.size
71
+
72
+ temperatures = body.scan(/temperatura:\s*<strong>(-?\d+)[^<]*<\/strong>/)
73
+ #puts temperatures.inspect
74
+ #puts temperatures.size
75
+
76
+ #winds = body.scan(/<strong>(\d*\.?\d*)\s*km\/h<\/strong>/)
77
+ #winds.slice!(0,5)
78
+ winds = body.scan(/<td width=\"30%\">[^<]*<strong>(\d*\.?\d*)\s*km\/h<\/strong>/)
79
+ #puts winds.inspect
80
+ #puts winds.size
81
+
82
+ data = Array.new
83
+
84
+ (0...(temperatures.size)).each do |i|
85
+ t = temperatures[i][0]
86
+ t = t.to_f unless t.nil?
87
+
88
+ wind_speed_km_per_h = winds[i][0]
89
+ if t.nil?
90
+ wind_speed_km_per_h = nil
91
+ w = nil
92
+ else
93
+ wind_speed_km_per_h = wind_speed_km_per_h.to_f
94
+ w = wind_speed_km_per_h / 3.6
95
+ end
96
+
97
+ h = {
98
+ :time_created => Time.now,
99
+ :time_from => times[i][:time_from],
100
+ :time_to => times[i][:time_to],
101
+ :temperature => t,
102
+ #:pressure => nil,
103
+ :wind_kmh => wind_speed_km_per_h,
104
+ :wind => w,
105
+ #:snow => snows[0][0].to_f,
106
+ #:rain => rains[0][0].to_f,
107
+ :provider => self.class.provider_name
108
+ }
109
+
110
+ data << h
111
+ end
112
+
113
+ return data
114
+ end
115
+
116
+
117
+ end
118
+
119
+ end
@@ -3,4 +3,6 @@ $:.unshift(File.dirname(__FILE__))
3
3
  require 'providers/provider'
4
4
  require 'providers/html_based'
5
5
 
6
- require 'providers/onet_pl'
6
+ require 'providers/html_based/onet_pl'
7
+ require 'providers/html_based/interia_pl'
8
+ require 'providers/html_based/wp_pl'
@@ -1,6 +1,7 @@
1
1
  $:.unshift(File.dirname(__FILE__))
2
2
 
3
3
  require 'weather_fetcher/providers'
4
+ require 'weather_fetcher/provider_list'
4
5
 
5
6
  module WeatherFetcher
6
7
  end
@@ -0,0 +1,6 @@
1
+ - :url: 'http://pogoda.interia.pl/miasta?id=11721'
2
+ :city: 'Inowrocław'
3
+ :country: 'Poland'
4
+ :coord:
5
+ :lat: 52.799264
6
+ :lon: 18.259935
@@ -0,0 +1,8 @@
1
+ - :url:
2
+ Interia.pl: 'http://pogoda.interia.pl/miasta?id=11721'
3
+ Onet.pl: 'http://pogoda.onet.pl/0,846,38,,,inowroclaw,miasto.html'
4
+ :city: 'Inowrocław'
5
+ :country: 'Poland'
6
+ :coord:
7
+ :lat: 52.799264
8
+ :lon: 18.259935
@@ -0,0 +1,6 @@
1
+ - :url: 'http://pogoda.wp.pl/miasto,bydgoszcz,mid,1201023,mi.html'
2
+ :city: 'Bydgoszcz'
3
+ :country: 'Poland'
4
+ :coord:
5
+ :lat: 53.128893
6
+ :lon: 18.006363
@@ -0,0 +1,14 @@
1
+ describe "WeatherFetcher::Provider::InteriaPl", :html => true do
2
+ before :each do
3
+ @defs = load_fixture('interia_pl')
4
+ @defs.size.should > 0
5
+ end
6
+
7
+ it "simple fetch" do
8
+ f = WeatherFetcher::Provider::InteriaPl.new(@defs)
9
+ weathers = f.fetch
10
+ weathers.should == f.weathers
11
+
12
+ # puts weathers.to_yaml
13
+ end
14
+ end
@@ -1,4 +1,4 @@
1
- describe "WeatherFetcher::Provider::OnetPl" do
1
+ describe "WeatherFetcher::Provider::OnetPl", :html => true do
2
2
  before :each do
3
3
  @defs = load_fixture('onet_pl')
4
4
  @defs.size.should > 0
@@ -9,7 +9,6 @@ describe "WeatherFetcher::Provider::OnetPl" do
9
9
  weathers = f.fetch
10
10
  weathers.should == f.weathers
11
11
 
12
- puts weathers.to_yaml
13
-
12
+ # puts weathers.to_yaml
14
13
  end
15
14
  end
@@ -0,0 +1,14 @@
1
+ describe "WeatherFetcher::Provider::WpPl", :html => true do
2
+ before :each do
3
+ @defs = load_fixture('wp_pl')
4
+ @defs.size.should > 0
5
+ end
6
+
7
+ it "simple fetch" do
8
+ f = WeatherFetcher::Provider::WpPl.new(@defs)
9
+ weathers = f.fetch
10
+ weathers.should == f.weathers
11
+
12
+ # puts weathers.to_yaml
13
+ end
14
+ end
data/spec/spec_helper.rb CHANGED
@@ -8,7 +8,8 @@ require 'weather_fetcher'
8
8
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
9
 
10
10
  RSpec.configure do |config|
11
-
11
+ #config.filter_run :html => false
12
+ #config.filter_run_excluding :html => true
12
13
  end
13
14
 
14
15
  def load_fixture(f)
@@ -13,4 +13,14 @@ describe "WeatherFetcher" do
13
13
  lambda { WeatherFetcher::Provider.new({}) }.should_not raise_error
14
14
  end
15
15
 
16
+ it "should return provider classes list" do
17
+ providers = WeatherFetcher::ProviderList.providers
18
+ providers.each do |p|
19
+ p.should be_kind_of(Class)
20
+
21
+ instance = p.new
22
+ instance.should respond_to(:fetch)
23
+ end
24
+ end
25
+
16
26
  end
@@ -0,0 +1,77 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "weather_fetcher"
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Aleksander Kwiatkowski"]
12
+ s.date = "2011-12-25"
13
+ s.description = "Fetch weather from various Polish websites and via other gems. At the moment it is only polish portal Onet.pl but more providers will come soon."
14
+ s.email = "bobikx@poczta.fm"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/weather_fetcher.rb",
29
+ "lib/weather_fetcher/provider_list.rb",
30
+ "lib/weather_fetcher/providers.rb",
31
+ "lib/weather_fetcher/providers/html_based.rb",
32
+ "lib/weather_fetcher/providers/html_based/interia_pl.rb",
33
+ "lib/weather_fetcher/providers/html_based/onet_pl.rb",
34
+ "lib/weather_fetcher/providers/html_based/wp_pl.rb",
35
+ "lib/weather_fetcher/providers/provider.rb",
36
+ "spec/fixtures/interia_pl.yml",
37
+ "spec/fixtures/onet_pl.yml",
38
+ "spec/fixtures/weather.yml",
39
+ "spec/fixtures/wp_pl.yml",
40
+ "spec/providers/interia_pl_spec.rb",
41
+ "spec/providers/onet_pl_spec.rb",
42
+ "spec/providers/wp_pl_spec.rb",
43
+ "spec/spec_helper.rb",
44
+ "spec/weather_fetcher_spec.rb",
45
+ "weather_fetcher.gemspec"
46
+ ]
47
+ s.homepage = "http://github.com/akwiatkowski/weather_fetcher"
48
+ s.licenses = ["LGPLv3"]
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = "1.8.10"
51
+ s.summary = "Fetch weather from various Polish websites and via other gems"
52
+
53
+ if s.respond_to? :specification_version then
54
+ s.specification_version = 3
55
+
56
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
57
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
58
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
59
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
60
+ s.add_development_dependency(%q<rcov>, [">= 0"])
61
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
62
+ else
63
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
64
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
65
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
66
+ s.add_dependency(%q<rcov>, [">= 0"])
67
+ s.add_dependency(%q<rdoc>, [">= 0"])
68
+ end
69
+ else
70
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
71
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
72
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
73
+ s.add_dependency(%q<rcov>, [">= 0"])
74
+ s.add_dependency(%q<rdoc>, [">= 0"])
75
+ end
76
+ end
77
+
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weather_fetcher
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 0
10
- version: 0.0.0
9
+ - 1
10
+ version: 0.0.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Aleksander Kwiatkowski
@@ -79,6 +79,20 @@ dependencies:
79
79
  name: rcov
80
80
  prerelease: false
81
81
  type: :development
82
+ - !ruby/object:Gem::Dependency
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ version_requirements: *id005
93
+ name: rdoc
94
+ prerelease: false
95
+ type: :development
82
96
  description: Fetch weather from various Polish websites and via other gems. At the moment it is only polish portal Onet.pl but more providers will come soon.
83
97
  email: bobikx@poczta.fm
84
98
  executables: []
@@ -98,14 +112,23 @@ files:
98
112
  - Rakefile
99
113
  - VERSION
100
114
  - lib/weather_fetcher.rb
115
+ - lib/weather_fetcher/provider_list.rb
101
116
  - lib/weather_fetcher/providers.rb
102
117
  - lib/weather_fetcher/providers/html_based.rb
103
- - lib/weather_fetcher/providers/onet_pl.rb
118
+ - lib/weather_fetcher/providers/html_based/interia_pl.rb
119
+ - lib/weather_fetcher/providers/html_based/onet_pl.rb
120
+ - lib/weather_fetcher/providers/html_based/wp_pl.rb
104
121
  - lib/weather_fetcher/providers/provider.rb
122
+ - spec/fixtures/interia_pl.yml
105
123
  - spec/fixtures/onet_pl.yml
124
+ - spec/fixtures/weather.yml
125
+ - spec/fixtures/wp_pl.yml
126
+ - spec/providers/interia_pl_spec.rb
106
127
  - spec/providers/onet_pl_spec.rb
128
+ - spec/providers/wp_pl_spec.rb
107
129
  - spec/spec_helper.rb
108
130
  - spec/weather_fetcher_spec.rb
131
+ - weather_fetcher.gemspec
109
132
  homepage: http://github.com/akwiatkowski/weather_fetcher
110
133
  licenses:
111
134
  - LGPLv3