meteo_pl 2.0.0 → 2.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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +13 -0
- data/.rspec +2 -0
- data/.rubocop.yml +32 -0
- data/.travis.yml +6 -0
- data/Gemfile +2 -0
- data/README.md +60 -0
- data/Rakefile +4 -0
- data/lib/meteo_pl/io/file_handler.rb +13 -0
- data/lib/meteo_pl/io/image_opener.rb +18 -0
- data/lib/meteo_pl/net/http.rb +22 -0
- data/lib/meteo_pl/utility/command.rb +82 -0
- data/lib/meteo_pl/utility/forecast.rb +22 -0
- data/lib/meteo_pl/utility/graph.rb +62 -0
- data/lib/meteo_pl/utility/presenter.rb +25 -0
- data/lib/meteo_pl/version.rb +3 -0
- data/lib/meteo_pl.rb +0 -1
- data/meteo_pl.gemspec +23 -0
- data/spec/io/file_handler_spec.rb +16 -0
- data/spec/io/image_opener_spec.rb +32 -0
- data/spec/net/http_spec.rb +25 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/1px.png +0 -0
- data/spec/support/shared_helper.rb +16 -0
- data/spec/utility/command_spec.rb +60 -0
- data/spec/utility/forecast_spec.rb +37 -0
- data/spec/utility/graph_spec.rb +29 -0
- data/spec/utility/presenter_spec.rb +50 -0
- metadata +68 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8f5c7a1b5099be45a9390ba4b5b2112650ee4b5
|
4
|
+
data.tar.gz: 4150a1eb57ee22d1e6bf5eafb7382f5a6da70f56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d7ad37d42803a4d5468af014f5af1ac29cac53fff851d7024a79cc65b5453426b02a6ae15259876e5ee3d0430d00e1f78c62b7f634c9f404d2da8b8ff72edf7
|
7
|
+
data.tar.gz: ea83a301f670ae8a795f8fc9c7e6b2c7a4a72c836ced67b46fd35d98ab7fac1aaa95e6acc6eea7eb381802b05cb84a9497992b85dab9e8b459c067cff677be9b
|
data/.codeclimate.yml
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
AllCops:
|
2
|
+
Include:
|
3
|
+
- '**/Gemfile'
|
4
|
+
- '**/Rakefile'
|
5
|
+
- '**/*.gemspec'
|
6
|
+
Exclude:
|
7
|
+
- 'spec/**/*'
|
8
|
+
DisplayCopNames: true
|
9
|
+
TargetRubyVersion: 2.1
|
10
|
+
|
11
|
+
ClassLength:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
MethodLength:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Documentation:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Style/FrozenStringLiteralComment:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Style/Send:
|
24
|
+
Enabled: true
|
25
|
+
|
26
|
+
PercentLiteralDelimiters:
|
27
|
+
PreferredDelimiters:
|
28
|
+
'%r': '{}'
|
29
|
+
'%i': '[]'
|
30
|
+
'%w': '[]'
|
31
|
+
'%W': '[]'
|
32
|
+
'%Q': '{}'
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# meteo_pl
|
2
|
+
|
3
|
+
[](https://rubygems.org/gems/meteo_pl)
|
4
|
+
[](https://travis-ci.org/kotu-pl/meteo_pl)
|
5
|
+
[](https://codeclimate.com/github/kotu-pl/meteo_pl/maintainability)
|
6
|
+
|
7
|
+
This gem fetches and manipulates on weather forecast graphs from http://www.meteo.pl service.
|
8
|
+
It allows to fetch coamps and um diagrams separately and open open them in your default image viewer.
|
9
|
+
|
10
|
+
**Usage example:**
|
11
|
+
|
12
|
+
Install gem in system-wide context, than create executable `meteo` named script:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
#!/usr/bin/env ruby
|
16
|
+
|
17
|
+
require 'meteo_pl'
|
18
|
+
|
19
|
+
command_line = MeteoPl::Utility::Command.new(ARGV)
|
20
|
+
|
21
|
+
if command_line.call
|
22
|
+
MeteoPl::Utility::Forecast.for(
|
23
|
+
command_line.location,
|
24
|
+
timeout: command_line.options[:timeout],
|
25
|
+
period: command_line.options[:period]
|
26
|
+
)
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
Than you'll be able to generate the weather forecast diagram from your command line:
|
31
|
+
|
32
|
+
```
|
33
|
+
/some_path/meteo Warszawa -p long
|
34
|
+
```
|
35
|
+
or directly when script's directory is within your $PATH:
|
36
|
+
|
37
|
+
```
|
38
|
+
meteo Warszawa -p long
|
39
|
+
```
|
40
|
+
|
41
|
+
To check all available options just run a script w/o arguments or with -h flag.
|
42
|
+
|
43
|
+
### Versions
|
44
|
+
|
45
|
+
* 2.0.2 Increased code quality
|
46
|
+
* 2.0.1 Minor code improvements, add TravisCI
|
47
|
+
* 2.0.0 Gem has been written from scratch, all external dependencies removed
|
48
|
+
* 1.0.0 converted to gem, option to choose um/coamps diagrams separetely and merge multiple diagrams with location labeling
|
49
|
+
* 0.2.0 Custom city selection, code reorganization
|
50
|
+
* 0.1.0 Initial version, fetches diagrams for Warsaw only. Tested on Ubuntu 12.04 LTS.
|
51
|
+
|
52
|
+
### Contributing to meteo_pl
|
53
|
+
* Fork the project.
|
54
|
+
* Start a feature/bugfix branch.
|
55
|
+
* Submit pull request
|
56
|
+
|
57
|
+
### Copyright
|
58
|
+
|
59
|
+
Copyright (c) 2014-2017 Marcin Kot. See LICENSE.txt for
|
60
|
+
further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module MeteoPl
|
2
|
+
module IO
|
3
|
+
class ImageOpener
|
4
|
+
attr_accessor :path
|
5
|
+
|
6
|
+
def open
|
7
|
+
case RbConfig::CONFIG['host_os']
|
8
|
+
when /mswin|mingw|cygwin/
|
9
|
+
`start #{path}`
|
10
|
+
when /darwin/
|
11
|
+
`open #{path}`
|
12
|
+
when /linux|bsd/
|
13
|
+
`xdg-open #{path}`
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module MeteoPl
|
4
|
+
module Net
|
5
|
+
class Http
|
6
|
+
def initialize(timeout)
|
7
|
+
@timeout = timeout
|
8
|
+
end
|
9
|
+
|
10
|
+
def fetch(uri)
|
11
|
+
raise ArgumentError unless block_given?
|
12
|
+
|
13
|
+
::Net::HTTP.start(
|
14
|
+
uri.host, uri.port,
|
15
|
+
use_ssl: uri.scheme == 'https',
|
16
|
+
open_timeout: @timeout,
|
17
|
+
read_tieout: @timeout
|
18
|
+
) { |http| yield http.request(::Net::HTTP::Get.new(uri)) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module MeteoPl
|
4
|
+
module Utility
|
5
|
+
class Command
|
6
|
+
PERIODS = { short: 60, long: 84 }.freeze
|
7
|
+
DEFAULT_PERIOD = :short
|
8
|
+
DEFAULT_TIMEOUT = 2
|
9
|
+
|
10
|
+
attr_reader :location, :options
|
11
|
+
|
12
|
+
def initialize(args)
|
13
|
+
@args = args
|
14
|
+
@options = {
|
15
|
+
timeout: DEFAULT_TIMEOUT,
|
16
|
+
period: PERIODS[DEFAULT_PERIOD]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
parse_input
|
22
|
+
set_location
|
23
|
+
valid?
|
24
|
+
ensure
|
25
|
+
print_help unless valid?
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :args
|
31
|
+
|
32
|
+
def valid?
|
33
|
+
!@invalid
|
34
|
+
end
|
35
|
+
|
36
|
+
def print_help
|
37
|
+
puts "\n"
|
38
|
+
option_parser.parse!(%w[--help])
|
39
|
+
end
|
40
|
+
|
41
|
+
def parse_input
|
42
|
+
option_parser.parse!(args)
|
43
|
+
rescue OptionParser::InvalidArgument, OptionParser::MissingArgument => e
|
44
|
+
@invalid = true
|
45
|
+
puts e.message
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_location
|
49
|
+
return unless valid?
|
50
|
+
@location = args.join(' ')
|
51
|
+
return unless @location.empty?
|
52
|
+
@invalid = true
|
53
|
+
puts 'LOCATION is not provided'
|
54
|
+
end
|
55
|
+
|
56
|
+
def option_parser
|
57
|
+
@option_parser ||= OptionParser.new do |opts|
|
58
|
+
opts.banner = 'Usage: LOCATION [options]'
|
59
|
+
|
60
|
+
opts.on(
|
61
|
+
'-t', '--timeout TIMEOUT', /^([1-9]|[1-5][0-9]|60)$/,
|
62
|
+
'Provide request timeout, value from 1s to 60s, default: 2s'
|
63
|
+
) do |timeout|
|
64
|
+
options[:timeout] = timeout.first.to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
opts.on(
|
68
|
+
'-p', '--period PERIOD', /short|long/,
|
69
|
+
'Provide forecast period, either short (60h) or long (84h),' \
|
70
|
+
' default: short'
|
71
|
+
) do |period|
|
72
|
+
options[:period] = PERIODS[period.to_sym]
|
73
|
+
end
|
74
|
+
|
75
|
+
opts.on('-h', '--help', 'Prints this help') do
|
76
|
+
puts opts
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module MeteoPl
|
2
|
+
module Utility
|
3
|
+
module Forecast
|
4
|
+
def for(location, timeout:, period:)
|
5
|
+
http_fetcher = Net::Http.new(timeout)
|
6
|
+
graph = MobileMeteoGraph.new(
|
7
|
+
http_fetcher, location, period
|
8
|
+
)
|
9
|
+
|
10
|
+
unless graph.uri
|
11
|
+
puts 'Graph for given location does not exists'
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
Presenter.new(
|
16
|
+
http_fetcher, IO::FileHandler.new, IO::ImageOpener.new, graph
|
17
|
+
).show
|
18
|
+
end
|
19
|
+
module_function :for
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module MeteoPl
|
2
|
+
module Utility
|
3
|
+
class Graph
|
4
|
+
attr_reader :net_fetcher, :location, :period
|
5
|
+
|
6
|
+
def initialize(net_fetcher, location, period)
|
7
|
+
@net_fetcher = net_fetcher
|
8
|
+
@location = location
|
9
|
+
@period = period
|
10
|
+
end
|
11
|
+
|
12
|
+
def uri
|
13
|
+
raise NotImplemented
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class MobileMeteoGraph < Graph
|
18
|
+
FORM_URL = 'http://m.meteo.pl/search/pl'.freeze
|
19
|
+
|
20
|
+
def uri
|
21
|
+
@uri ||= begin
|
22
|
+
prepare_initial_request_uri
|
23
|
+
fetch_initial_data
|
24
|
+
return unless initial_response && initial_response.code == '302'
|
25
|
+
fetch_graph_page
|
26
|
+
fetch_graph_uri
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :initial_request_uri, :initial_response, :graph_page
|
33
|
+
|
34
|
+
def prepare_initial_request_uri
|
35
|
+
@initial_request_uri = begin
|
36
|
+
uri = URI(FORM_URL)
|
37
|
+
uri.query = URI.encode_www_form(
|
38
|
+
miastoPL: location,
|
39
|
+
typePL: :city,
|
40
|
+
prognozaPL: period
|
41
|
+
)
|
42
|
+
uri
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def fetch_initial_data
|
47
|
+
net_fetcher.fetch(initial_request_uri) do |response|
|
48
|
+
@initial_response = response
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def fetch_graph_page
|
53
|
+
@graph_page =
|
54
|
+
net_fetcher.fetch(URI(initial_response['location']), &:body)
|
55
|
+
end
|
56
|
+
|
57
|
+
def fetch_graph_uri
|
58
|
+
URI(graph_page.match(/http.+mgram_pict\.php([^"]+)/)[0])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MeteoPl
|
2
|
+
module Utility
|
3
|
+
class Presenter
|
4
|
+
def initialize(net_fetcher, file_handler, file_opener, graph)
|
5
|
+
@net_fetcher = net_fetcher
|
6
|
+
@file_handler = file_handler
|
7
|
+
@file_opener = file_opener
|
8
|
+
@graph = graph
|
9
|
+
end
|
10
|
+
|
11
|
+
def show
|
12
|
+
file_handler.open do |temp_file|
|
13
|
+
graph_content = net_fetcher.fetch(graph.uri, &:body)
|
14
|
+
temp_file.write(graph_content)
|
15
|
+
file_opener.path = temp_file.path
|
16
|
+
file_opener.open
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :net_fetcher, :file_handler, :file_opener, :graph
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/meteo_pl.rb
CHANGED
data/meteo_pl.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path('../lib/meteo_pl/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'meteo_pl'
|
5
|
+
spec.version = MeteoPl::VERSION
|
6
|
+
spec.summary = 'Weather forecast from http://www.meteo.pl'
|
7
|
+
spec.description = 'Fetches and manipulates on weather forecast ' \
|
8
|
+
'graphs from http://www.meteo.pl service'
|
9
|
+
spec.license = 'MIT'
|
10
|
+
spec.authors = ['Marcin Kot']
|
11
|
+
spec.email = 'marcin@kotu.pl'
|
12
|
+
spec.homepage = 'http://github.com/kotu-pl/meteo_pl'
|
13
|
+
|
14
|
+
spec.files = `git ls-files`.split("\n")
|
15
|
+
spec.test_files = spec.files.grep(%r{^spec\/})
|
16
|
+
spec.require_paths = ['lib']
|
17
|
+
|
18
|
+
spec.add_development_dependency 'rake', '~> 12.1'
|
19
|
+
spec.add_development_dependency 'rspec', '~> 3.6'
|
20
|
+
spec.add_development_dependency 'webmock', '~> 3.1'
|
21
|
+
|
22
|
+
spec.required_ruby_version = '>= 2.0'
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
describe MeteoPl::IO::FileHandler do
|
2
|
+
let(:file_handler) { MeteoPl::IO::FileHandler.new }
|
3
|
+
|
4
|
+
describe 'behaviour' do
|
5
|
+
let(:tempfile) { double('tempfile') }
|
6
|
+
before do
|
7
|
+
allow(Tempfile).to receive(:open).and_return(tempfile)
|
8
|
+
end
|
9
|
+
it 'creates tempfile and yields it' do
|
10
|
+
expect_any_instance_of(MeteoPl::IO::FileHandler).to receive(:open)
|
11
|
+
.and_yield(tempfile)
|
12
|
+
|
13
|
+
file_handler.open { |_| }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
describe MeteoPl::IO::ImageOpener do
|
2
|
+
let(:path) { '/tmp/graph.png'}
|
3
|
+
let(:image_opener) do
|
4
|
+
image_opener = described_class.new
|
5
|
+
image_opener.path = path
|
6
|
+
image_opener
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'calling proper command for given OS' do
|
10
|
+
context 'Windows' do
|
11
|
+
before { stub_const('RbConfig::CONFIG', 'host_os' => 'mswin') }
|
12
|
+
it do
|
13
|
+
expect_any_instance_of(Kernel).to receive(:`).with("start #{path}")
|
14
|
+
image_opener.open
|
15
|
+
end
|
16
|
+
end
|
17
|
+
context 'macOS' do
|
18
|
+
before { stub_const('RbConfig::CONFIG', 'host_os' => 'darwin') }
|
19
|
+
it do
|
20
|
+
expect_any_instance_of(Kernel).to receive(:`).with("open #{path}")
|
21
|
+
image_opener.open
|
22
|
+
end
|
23
|
+
end
|
24
|
+
context 'linux' do
|
25
|
+
before { stub_const('RbConfig::CONFIG', 'host_os' => 'linux') }
|
26
|
+
it do
|
27
|
+
expect_any_instance_of(Kernel).to receive(:`).with("xdg-open #{path}")
|
28
|
+
image_opener.open
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
describe MeteoPl::Net::Http do
|
2
|
+
let(:timeout) { 2 }
|
3
|
+
let(:http) { MeteoPl::Net::Http.new(timeout) }
|
4
|
+
let(:url) { URI.parse('http://example.com') }
|
5
|
+
|
6
|
+
describe 'arguments validation' do
|
7
|
+
it 'raises error when no block given' do
|
8
|
+
expect {
|
9
|
+
http.fetch(url)
|
10
|
+
}.to raise_error ArgumentError
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'return proper data' do
|
15
|
+
before do
|
16
|
+
stub_request(:get, "http://example.com/").
|
17
|
+
to_return(status: 200, body: 'Example Domain', headers: {})
|
18
|
+
end
|
19
|
+
it 'body' do
|
20
|
+
expect(
|
21
|
+
http.fetch(url) { |respone| [respone.code, respone.body] }
|
22
|
+
).to match_array ['200', /Example Domain/]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require './lib/meteo_pl'
|
2
|
+
require './spec/support/shared_helper'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.include SharedHelper
|
7
|
+
config.expect_with :rspec do |expectations|
|
8
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
9
|
+
end
|
10
|
+
|
11
|
+
config.mock_with :rspec do |mocks|
|
12
|
+
mocks.verify_partial_doubles = true
|
13
|
+
end
|
14
|
+
end
|
Binary file
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SharedHelper
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def png_file
|
5
|
+
File.open('./spec/support/1px.png')
|
6
|
+
end
|
7
|
+
|
8
|
+
def resp1
|
9
|
+
<<-HERE
|
10
|
+
<div class="contenerImgWeather">
|
11
|
+
<div class="helpImg60"><img src="http://m.meteo.pl/img/leg60.png" /></div>
|
12
|
+
<img src="https://www.meteo.pl/um/metco/mgram_pict.php?ntype=0u&fdate=2017092106&row=406&col=250&lang=pl" class="border" id="image_60" alt="miasto" />
|
13
|
+
</div>
|
14
|
+
HERE
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
describe MeteoPl::Utility::Command do
|
2
|
+
let(:command_line_parser) { MeteoPl::Utility::Command.new(args) }
|
3
|
+
before { allow($stdout).to receive(:puts) }
|
4
|
+
|
5
|
+
describe 'arguments validation' do
|
6
|
+
context 'valid arguments are provided' do
|
7
|
+
let(:args) { %w[Warszawa -t 60 -p long] }
|
8
|
+
|
9
|
+
it 'retun valid state' do
|
10
|
+
expect(command_line_parser.call).to eq true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'valid when only required arguments are passed' do
|
15
|
+
let(:args) { %w[Kostrzyn nad Odrą ] }
|
16
|
+
|
17
|
+
it 'retun valid state' do
|
18
|
+
expect(command_line_parser.call).to eq true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'invalid when timeout parameter is not valid' do
|
23
|
+
let(:args) { %w[Warszawa -t 61] }
|
24
|
+
|
25
|
+
it 'retun invalid state' do
|
26
|
+
expect(command_line_parser.call).to eq false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'invalid when period parameter is not valid' do
|
31
|
+
let(:args) { %w[Warszawa -t 1 -p other] }
|
32
|
+
|
33
|
+
it 'retun invalid state' do
|
34
|
+
expect(command_line_parser.call).to eq false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'return proper data' do
|
40
|
+
context 'return defaults' do
|
41
|
+
let(:args) { %w[Kostrzyn nad Odrą] }
|
42
|
+
|
43
|
+
it do
|
44
|
+
command_line_parser.call
|
45
|
+
expect(command_line_parser.location).to eq 'Kostrzyn nad Odrą'
|
46
|
+
expect(command_line_parser.options).to eq({ timeout: 2, period: 60 })
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'return given options' do
|
51
|
+
let(:args) { %w[Kostrzyn nad Odrą -t 15 -p long] }
|
52
|
+
|
53
|
+
it do
|
54
|
+
command_line_parser.call
|
55
|
+
expect(command_line_parser.location).to eq 'Kostrzyn nad Odrą'
|
56
|
+
expect(command_line_parser.options).to eq({ timeout: 15, period: 84 })
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
describe MeteoPl::Utility::Forecast do
|
2
|
+
describe 'proper output' do
|
3
|
+
context 'returns error message if location does not exist' do
|
4
|
+
# request mock instead
|
5
|
+
before do
|
6
|
+
allow(MeteoPl::Utility::Graph).to receive(:new).and_return(
|
7
|
+
double('graph', uri: nil)
|
8
|
+
)
|
9
|
+
end
|
10
|
+
|
11
|
+
it do
|
12
|
+
expect($stdout).to receive(:puts).with(
|
13
|
+
'Graph for given location does not exists'
|
14
|
+
)
|
15
|
+
expect_any_instance_of(MeteoPl::Utility::Presenter).not_to receive(:show)
|
16
|
+
|
17
|
+
described_class.for('Warszawa', timeout: 2, period: 60)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'tiggers graph presenter if everything went fine' do
|
22
|
+
# request mock instead
|
23
|
+
before do
|
24
|
+
allow(MeteoPl::Utility::Graph).to receive(:new).and_return(
|
25
|
+
double('graph', uri: 'http://example.com/graph.png')
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
it do
|
30
|
+
expect($stdout).not_to receive(:puts)
|
31
|
+
expect_any_instance_of(MeteoPl::Utility::Presenter).to receive(:show)
|
32
|
+
|
33
|
+
described_class.for('Warszawa', timeout: 2, period: 60)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
describe MeteoPl::Utility::MobileMeteoGraph do
|
2
|
+
let(:net_fetcher) { MeteoPl::Net::Http.new(2) }
|
3
|
+
let(:city) { 'Warszawa' }
|
4
|
+
let(:period) { 60 }
|
5
|
+
let(:graph) {
|
6
|
+
MeteoPl::Utility::MobileMeteoGraph.new(net_fetcher, city, period)
|
7
|
+
}
|
8
|
+
|
9
|
+
describe 'return proper data' do
|
10
|
+
before do
|
11
|
+
stub_request(
|
12
|
+
:get,
|
13
|
+
"http://m.meteo.pl/search/pl?miastoPL=Warszawa&prognozaPL=60&typePL=city"
|
14
|
+
).to_return(
|
15
|
+
:status => 302, :headers => { location: 'http://m.meteo.pl/warszawa/60' }
|
16
|
+
)
|
17
|
+
stub_request(
|
18
|
+
:get, "http://m.meteo.pl/warszawa/60",
|
19
|
+
).to_return(
|
20
|
+
status: 200, body: resp1
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
it do
|
25
|
+
expect(graph.uri).to be_kind_of URI
|
26
|
+
expect(graph.uri.path).to eq '/um/metco/mgram_pict.php'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
describe MeteoPl::Utility::Presenter do
|
2
|
+
let(:net_fetcher) { MeteoPl::Net::Http.new(2) }
|
3
|
+
let(:file_handler) { MeteoPl::IO::FileHandler.new }
|
4
|
+
let(:image_opener) { MeteoPl::IO::ImageOpener.new }
|
5
|
+
let(:graph) {
|
6
|
+
MeteoPl::Utility::MobileMeteoGraph.new(net_fetcher, 'Warszawa', 60)
|
7
|
+
}
|
8
|
+
let(:presenter) do
|
9
|
+
MeteoPl::Utility::Presenter.new(
|
10
|
+
net_fetcher, file_handler, image_opener, graph
|
11
|
+
)
|
12
|
+
end
|
13
|
+
let(:tempfile) do
|
14
|
+
double('tempfile', path: '/tmp/temfile_path.png')
|
15
|
+
end
|
16
|
+
before do
|
17
|
+
allow(file_handler).to receive(:open).and_yield(tempfile)
|
18
|
+
stub_const('RbConfig::CONFIG', 'host_os' => 'linux')
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'return proper data' do
|
22
|
+
before do
|
23
|
+
stub_request(
|
24
|
+
:get,
|
25
|
+
"http://m.meteo.pl/search/pl?miastoPL=Warszawa&prognozaPL=60&typePL=city"
|
26
|
+
).to_return(
|
27
|
+
:status => 302, :headers => { location: 'http://m.meteo.pl/warszawa/60' }
|
28
|
+
)
|
29
|
+
stub_request(
|
30
|
+
:get, "http://m.meteo.pl/warszawa/60",
|
31
|
+
).to_return(
|
32
|
+
status: 200, body: resp1
|
33
|
+
)
|
34
|
+
stub_request(
|
35
|
+
:get, /mgram_pict\.php/,
|
36
|
+
).to_return(
|
37
|
+
status: 200, body: png_file.read, headers: { 'Content-type' => 'image/png'}
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'opens file with OS supported image browser' do
|
42
|
+
expect_any_instance_of(Kernel).to receive(:`).with(
|
43
|
+
"xdg-open /tmp/temfile_path.png"
|
44
|
+
)
|
45
|
+
expect(tempfile).to receive(:write).with(png_file.read)
|
46
|
+
|
47
|
+
presenter.show
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meteo_pl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcin Kot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '12.1'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '12.1'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rspec
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +38,20 @@ dependencies:
|
|
24
38
|
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '3.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: webmock
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
27
55
|
description: Fetches and manipulates on weather forecast graphs from http://www.meteo.pl
|
28
56
|
service
|
29
57
|
email: marcin@kotu.pl
|
@@ -31,7 +59,33 @@ executables: []
|
|
31
59
|
extensions: []
|
32
60
|
extra_rdoc_files: []
|
33
61
|
files:
|
62
|
+
- ".codeclimate.yml"
|
63
|
+
- ".rspec"
|
64
|
+
- ".rubocop.yml"
|
65
|
+
- ".travis.yml"
|
66
|
+
- Gemfile
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
34
69
|
- lib/meteo_pl.rb
|
70
|
+
- lib/meteo_pl/io/file_handler.rb
|
71
|
+
- lib/meteo_pl/io/image_opener.rb
|
72
|
+
- lib/meteo_pl/net/http.rb
|
73
|
+
- lib/meteo_pl/utility/command.rb
|
74
|
+
- lib/meteo_pl/utility/forecast.rb
|
75
|
+
- lib/meteo_pl/utility/graph.rb
|
76
|
+
- lib/meteo_pl/utility/presenter.rb
|
77
|
+
- lib/meteo_pl/version.rb
|
78
|
+
- meteo_pl.gemspec
|
79
|
+
- spec/io/file_handler_spec.rb
|
80
|
+
- spec/io/image_opener_spec.rb
|
81
|
+
- spec/net/http_spec.rb
|
82
|
+
- spec/spec_helper.rb
|
83
|
+
- spec/support/1px.png
|
84
|
+
- spec/support/shared_helper.rb
|
85
|
+
- spec/utility/command_spec.rb
|
86
|
+
- spec/utility/forecast_spec.rb
|
87
|
+
- spec/utility/graph_spec.rb
|
88
|
+
- spec/utility/presenter_spec.rb
|
35
89
|
homepage: http://github.com/kotu-pl/meteo_pl
|
36
90
|
licenses:
|
37
91
|
- MIT
|
@@ -44,7 +98,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
98
|
requirements:
|
45
99
|
- - ">="
|
46
100
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
101
|
+
version: '2.0'
|
48
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
103
|
requirements:
|
50
104
|
- - ">="
|
@@ -56,4 +110,14 @@ rubygems_version: 2.6.11
|
|
56
110
|
signing_key:
|
57
111
|
specification_version: 4
|
58
112
|
summary: Weather forecast from http://www.meteo.pl
|
59
|
-
test_files:
|
113
|
+
test_files:
|
114
|
+
- spec/io/file_handler_spec.rb
|
115
|
+
- spec/io/image_opener_spec.rb
|
116
|
+
- spec/net/http_spec.rb
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
- spec/support/1px.png
|
119
|
+
- spec/support/shared_helper.rb
|
120
|
+
- spec/utility/command_spec.rb
|
121
|
+
- spec/utility/forecast_spec.rb
|
122
|
+
- spec/utility/graph_spec.rb
|
123
|
+
- spec/utility/presenter_spec.rb
|