weather_fetcher 0.0.0 → 0.0.1

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/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