eorzea_weather 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c70b8657e2e0554c20bb27533b0c417a68e07d93bd98ac44854f4bca6faa8e18
4
+ data.tar.gz: dd912f4e3e1bd4a95d6e0a713d227848c82fd9ed6234b555c09e63fe87580b14
5
+ SHA512:
6
+ metadata.gz: e1dab474c54467eedaee4db7f1ba34a298146beba3a8e4146f58fa00954730dea1ab3cf6a66ddbab2d85f7bf82337fb6db42887e2d59e1ac5b9b384e69d160d5
7
+ data.tar.gz: f946fff6aaa60cf86e6c2bd364366ec7069945d7b03d81b9f0e92b75147064c3c952f86a9e9dc74009e4d5f51c1c6c8e308e461ccab6109249647a46afe714df
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.6.0
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in eorzea_weather.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Sorah Fukumori
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # EorzeaWeather: Eorzean weather forecast
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'eorzea_weather'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install eorzea_weather
18
+
19
+ ## Usage
20
+
21
+ ``` ruby
22
+ require 'eorzea_weather'
23
+
24
+ ## Get single forecast
25
+ # Pick zone
26
+ forecast = EorzeaWeather.forecast(EorzeaWeather::Data::Zones::EurekaAnemos)
27
+ forecast = EorzeaWeather.forecast('Eureka Anemos')
28
+ forecast = EorzeaWeather.forecast('エウレカ:アネモス帯')
29
+ forecast = EorzeaWeather.forecast(:eureka_anemos)
30
+ # Specify date
31
+ forecast = EorzeaWeather.forecast(:eureka_anemos, Time.utc(2018,4,17,7,0,0))
32
+
33
+ ## Using a forecast
34
+ # Weather
35
+ p weather
36
+ p forecast.weather
37
+ p forecast.start_time
38
+ p forecast.end_time
39
+ # Enumerate
40
+ p forecast.prev
41
+ p forecast.succ
42
+
43
+ ## Upcoming and past
44
+ p EorzeaWeather.forecasts(:eureka_anemos)
45
+ p EorzeaWeather.history(:eureka_anemos)
46
+ # Need more?
47
+ p EorzeaWeather.forecasts(:eureka_anemos, count: 10)
48
+ p EorzeaWeather.history(:eureka_anemos, count: 10)
49
+
50
+ ## Find next specific weather in a zone
51
+ p EorzeaWeather.find_next(:gales, :eureka_anemos)
52
+ p EorzeaWeather.find_next('暴風', :eureka_anemos)
53
+ p EorzeaWeather.find_next('Gales', :eureka_anemos)
54
+ # From specific time?
55
+ p EorzeaWeather.find_next(:gales, :eureka_anemos, time: Time.utc(2018,4,16,16,0,0))
56
+ # Need to dig more? (Default to 60 times, next 3 days in earth)
57
+ p EorzeaWeather.find_next(:gales, :eureka_anemos, max_attempts: 120)
58
+
59
+ ## Find specific weather in zone
60
+ p EorzeaWeather.find(:gales, :eureka_anemos)
61
+ # From specific time?
62
+ p EorzeaWeather.find(:gales, :eureka_anemos, time: Time.utc(2018,4,16,16,0,0))
63
+ # Need to dig more? (Default to 60 times, next 3 days in earth)
64
+ p EorzeaWeather.find(:gales, :eureka_anemos, max_attempts: 120)
65
+ ```
66
+
67
+ ### Localized string
68
+
69
+ ``` ruby
70
+ p EorzeaWeather::Localizer.new(:zone, :eureka_anemos).to_h
71
+ p EorzeaWeather::Localizer.new(:zone, :eureka_anemos)[:en]
72
+ p EorzeaWeather::Localizer.new(:zone, :eureka_anemos)[:ja]
73
+
74
+ p EorzeaWeather::Localizer.new(:weather, :gales).to_h
75
+ p EorzeaWeather::Localizer.new(:weather, :gales)[:en]
76
+ p EorzeaWeather::Localizer.new(:weather, :gales)[:ja]
77
+ ```
78
+
79
+ ## Development
80
+
81
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
82
+
83
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
84
+
85
+ ## Contributing
86
+
87
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sorah/eorzea_weather.
88
+
89
+ ## License
90
+
91
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
92
+
93
+ ## Credit
94
+
95
+ - Implementation idea based on
96
+ - https://github.com/Rogueadyn/SaintCoinach/blob/f969b441584688c02dde2fadac548c4a5aaa3faa/SaintCoinach/Xiv/WeatherRate.cs
97
+ - https://github.com/flowercartelet/eorzea-weather
98
+ - FINAL FANTASY is a registered trademark of Square Enix Holdings Co., Ltd.
99
+ - FINAL FANTASY XIV (c) 2010-2018 SQUARE ENIX CO., LTD. All Rights Reserved.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "eorzea_weather"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,28 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "eorzea_weather/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "eorzea_weather"
8
+ spec.version = EorzeaWeather::VERSION
9
+ spec.authors = ["Sorah Fukumori"]
10
+ spec.email = ["her@sorah.jp"]
11
+
12
+ spec.summary = %q{Eorzean Weather Forecast}
13
+ spec.homepage = "https://github.com/sorah/eorzea_weather"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency 'eorzea_time', '>= 0.2.0'
24
+
25
+ spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
+ end
@@ -0,0 +1,78 @@
1
+ require 'eorzea_weather/version'
2
+ require 'eorzea_weather/locale'
3
+ require 'eorzea_weather/zone'
4
+ require 'eorzea_weather/data/weathers'
5
+ require 'eorzea_weather/data/zones'
6
+ require 'eorzea_weather/data/locales'
7
+ require 'eorzea_weather/calculator'
8
+ require 'eorzea_weather/localizer'
9
+
10
+ module EorzeaWeather
11
+ def self.zones
12
+ Data::Zones::MAP
13
+ end
14
+
15
+ def self.zone(o)
16
+ case o
17
+ when Zone
18
+ o
19
+ when String
20
+ o = Data::Locales::ZONE_MAP[o] || o
21
+ Data::Zones::MAP.fetch o.to_sym
22
+ else
23
+ Data::Zones::MAP.fetch o.to_sym
24
+ end
25
+ end
26
+
27
+ def self.weather(o)
28
+ if o.kind_of?(String)
29
+ o = Data::Locales::WEATHER_MAP[o] || o
30
+ o = o.to_sym
31
+ end
32
+ if Data::Weathers::LIST.include?(o)
33
+ return o
34
+ else
35
+ raise KeyError, "#{o} is not valid weather"
36
+ end
37
+ end
38
+
39
+
40
+ def self.find_next(weather, zone, time: Time.now, max_attempts: 60)
41
+ find(weather, zone, time: time, max_attempts: max_attempts, count: 1)[0]
42
+ end
43
+
44
+ def self.find(weather, zone, time: Time.now, max_attempts: 60, count: 1)
45
+ weather = self.weather(weather)
46
+
47
+ result = []
48
+ forecast = self.forecast(zone, time)
49
+ max_attempts.times do
50
+ if forecast.weather == weather
51
+ result << forecast
52
+ end
53
+ forecast = forecast.succ
54
+ end
55
+
56
+ result
57
+ end
58
+
59
+ def self.forecast(zone, time = Time.now)
60
+ Calculator.new(self.zone(zone), time)
61
+ end
62
+
63
+ def self.forecasts(zone, time: Time.now, count: 6)
64
+ [forecast(zone, time)].tap do |result|
65
+ [0, count - 1].max.times do
66
+ result << result.last.succ
67
+ end
68
+ end
69
+ end
70
+
71
+ def self.history(zone, time: Time.now, count: 6)
72
+ [forecast(zone, time)].tap do |result|
73
+ [0, count - 1].max.times do
74
+ result << result.last.prev
75
+ end
76
+ end.reverse
77
+ end
78
+ end
@@ -0,0 +1,66 @@
1
+ require 'eorzea_time'
2
+
3
+ # https://github.com/Rogueadyn/SaintCoinach/blob/f969b441584688c02dde2fadac548c4a5aaa3faa/SaintCoinach/Xiv/WeatherRate.cs
4
+ module EorzeaWeather
5
+ class Calculator
6
+ def initialize(zone, time)
7
+ @zone = zone
8
+ @time = time.utc
9
+ end
10
+
11
+ def prev
12
+ self.class.new(@zone, start_time - 1)
13
+ end
14
+
15
+ def succ
16
+ self.class.new(@zone, end_time)
17
+ end
18
+
19
+ attr_reader :zone, :time
20
+
21
+ def inspect
22
+ "#<#{self.class.name}: #{zone.id}, #{time} (#{start_hour}-#{end_hour}: #{weather})>"
23
+ end
24
+
25
+ def weather
26
+ @weather ||= @zone.find_rate(rate)
27
+ end
28
+
29
+ def start_time
30
+ EorzeaTime.new(start_hour * 3600).last_occurrence(time: @time)
31
+ end
32
+
33
+ def end_time
34
+ EorzeaTime.new(end_hour * 3600).next_occurrence(time: @time)
35
+ end
36
+
37
+ # Eorzean Hour (1 eorzean hour is 175 seconds in local time)
38
+ def hour
39
+ @hour ||= @time.to_i / 175 % 24
40
+ end
41
+
42
+ # Number of days passed in Eorzea (1 eorzean day is 4200 seconds in local time)
43
+ def days
44
+ @days ||= @time.to_i / 4200
45
+ end
46
+
47
+ def start_hour
48
+ # 0..7 => 0, 8..15 => 8, 16..23 => 16
49
+ hour - (hour % 8)
50
+ end
51
+
52
+ def end_hour
53
+ # 0..7 => 8, 8..15 => 16, 16..23 => 0
54
+ ((hour + 8) - (hour % 8)) % 24
55
+ end
56
+
57
+ def rate
58
+ @rate ||= begin
59
+ base = (days * 0x64) + end_hour
60
+ step1 = (base << 0xb & 0xffffffff) ^ base
61
+ step2 = (step1 >> 8 & 0xffffffff) ^ step1
62
+ step2 % 0x64
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,141 @@
1
+ require 'eorzea_weather/locale'
2
+
3
+ module EorzeaWeather
4
+ module Data
5
+ module Locales
6
+ En = Locale.new(:en,
7
+ {
8
+ blizzards: "Blizzards",
9
+ clear_skies: "Clear Skies",
10
+ clouds: "Clouds",
11
+ dust_storms: "Dust Storms",
12
+ fair_skies: "Fair Skies",
13
+ fog: "Fog",
14
+ gales: "Gales",
15
+ gloom: "Gloom",
16
+ heat_waves: "Heat Waves",
17
+ rain: "Rain",
18
+ showers: "Showers",
19
+ snow: "Snow",
20
+ thunder: "Thunder",
21
+ thunderstorms: "Thunderstorms",
22
+ umbral_static: "Umbral Static",
23
+ umbral_wind: "Umbral Wind",
24
+ wind: "Wind",
25
+ },
26
+ {
27
+ azys_lla: "Azys Lla",
28
+ central_shroud: "Central Shroud",
29
+ central_thanalan: "Central Thanalan",
30
+ coerthas_central_highlands: "Coerthas Central Highlands",
31
+ coerthas_western_highlands: "Coerthas Western Highlands",
32
+ eastern_la_noscea: "Eastern La Noscea",
33
+ eastern_thanalan: "Eastern Thanalan",
34
+ east_shroud: "East Shroud",
35
+ eureka_anemos: "Eureka Anemos",
36
+ gridania: "Gridania",
37
+ idyllshire: "Idyllshire",
38
+ ishgard: "Ishgard",
39
+ kugane: "Kugane",
40
+ limsa_lominsa: "Limsa Lominsa",
41
+ lower_la_noscea: "Lower La Noscea",
42
+ middle_la_noscea: "Middle La Noscea",
43
+ mist: "Mist",
44
+ mor_dhona: "Mor Dhona",
45
+ northern_thanalan: "Northern Thanalan",
46
+ north_shroud: "North Shroud",
47
+ outer_la_noscea: "Outer La Noscea",
48
+ rhalgrs_reach: "Rhalgr's Reach",
49
+ shirogane: "Shirogane",
50
+ southern_thanalan: "Southern Thanalan",
51
+ south_shroud: "South Shroud",
52
+ the_azim_steppe: "The Azim Steppe",
53
+ the_churning_mists: "The Churning Mists",
54
+ the_dravanian_forelands: "The Dravanian Forelands",
55
+ the_dravanian_hinterlands: "The Dravanian Hinterlands",
56
+ the_fringes: "The Fringes",
57
+ the_goblet: "The Goblet",
58
+ the_lavender_beds: "The Lavender Beds",
59
+ the_lochs: "The Lochs",
60
+ the_peaks: "The Peaks",
61
+ the_ruby_sea: "The Ruby Sea",
62
+ the_sea_of_clouds: "The Sea of Clouds",
63
+ uldah: "Ul'dah",
64
+ upper_la_noscea: "Upper La Noscea",
65
+ western_la_noscea: "Western La Noscea",
66
+ western_thanalan: "Western Thanalan",
67
+ yanxia: "Yanxia",
68
+ },
69
+ )
70
+
71
+ Ja = Locale.new(:ja,
72
+ {
73
+ blizzards: "吹雪",
74
+ clear_skies: "快晴",
75
+ clouds: "曇り",
76
+ dust_storms: "砂塵",
77
+ fair_skies: "晴れ",
78
+ fog: "霧",
79
+ gales: "暴風",
80
+ gloom: "妖霧",
81
+ heat_waves: "灼熱波",
82
+ rain: "雨",
83
+ showers: "暴雨",
84
+ snow: "雪",
85
+ thunder: "雷",
86
+ thunderstorms: "雷雨",
87
+ umbral_static: "放電",
88
+ umbral_wind: "霊風",
89
+ wind: "風",
90
+ },
91
+ {
92
+ azys_lla: "アジス・ラー",
93
+ central_shroud: "黒衣森:中央森林",
94
+ central_thanalan: "中央ザナラーン",
95
+ coerthas_central_highlands: "クルザス中央高地",
96
+ coerthas_western_highlands: "クルザス西部高地",
97
+ eastern_la_noscea: "東ラノシア",
98
+ eastern_thanalan: "東ザナラーン",
99
+ east_shroud: "黒衣森:東部森林",
100
+ eureka_anemos: "エウレカ:アネモス帯",
101
+ gridania: "グリダニア",
102
+ idyllshire: "イデルシャイア",
103
+ ishgard: "イシュガルド",
104
+ kugane: "クガネ",
105
+ limsa_lominsa: "リムサ・ロミンサ",
106
+ lower_la_noscea: "低地ラノシア",
107
+ middle_la_noscea: "中央ラノシア",
108
+ mist: "ミスト・ヴィレッジ",
109
+ mor_dhona: "モードゥナ",
110
+ northern_thanalan: "北ザナラーン",
111
+ north_shroud: "黒衣森:北部森林",
112
+ outer_la_noscea: "外地ラノシア",
113
+ rhalgrs_reach: "ラールガーズリーチ",
114
+ shirogane: "シロガネ",
115
+ southern_thanalan: "南ザナラーン",
116
+ south_shroud: "黒衣森:南部森林",
117
+ the_azim_steppe: "アジムステップ",
118
+ the_churning_mists: "ドラヴァニア雲海",
119
+ the_dravanian_forelands: "高地ドラヴァニア",
120
+ the_dravanian_hinterlands: "低地ドラヴァニア",
121
+ the_fringes: "ギラバニア辺境地帯",
122
+ the_goblet: "ゴブレットビュート",
123
+ the_lavender_beds: "ラベンダーベッド",
124
+ the_lochs: "ギラバニア湖畔地帯",
125
+ the_peaks: "ギラバニア山岳地帯",
126
+ the_ruby_sea: "紅玉海",
127
+ the_sea_of_clouds: "アバラシア雲海",
128
+ uldah: "ウルダハ",
129
+ upper_la_noscea: "高地ラノシア",
130
+ western_la_noscea: "西ラノシア",
131
+ western_thanalan: "西ザナラーン",
132
+ yanxia: "ヤンサ",
133
+ },
134
+ )
135
+
136
+ MAP = (self.constants - [:MAP]).map(&self.method(:const_get)).map{ |_| [_.id, _] }.to_h
137
+ WEATHER_MAP = self.constants.map(&self.method(:const_get)).grep(Locale).map(&:weather).flat_map { |l| l.map { |i,v| [v,i] } }.to_h
138
+ ZONE_MAP = self.constants.map(&self.method(:const_get)).grep(Locale).map(&:zone).flat_map { |l| l.map { |i,v| [v,i] } }.to_h
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,25 @@
1
+ module EorzeaWeather
2
+ module Data
3
+ module Weathers
4
+ LIST = %i(
5
+ blizzards
6
+ clear_skies
7
+ clouds
8
+ dust_storms
9
+ fair_skies
10
+ fog
11
+ gales
12
+ gloom
13
+ heat_waves
14
+ rain
15
+ showers
16
+ snow
17
+ thunder
18
+ thunderstorms
19
+ umbral_static
20
+ umbral_wind
21
+ wind
22
+ )
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,319 @@
1
+ module EorzeaWeather
2
+ module Data
3
+ module Zones
4
+ AzysLla = Zone.new(:azys_lla, [
5
+ [35, :fair_skies],
6
+ [70, :clouds],
7
+ [nil, :thunder],
8
+ ])
9
+ CentralShroud = Zone.new(:central_shroud, [
10
+ [5, :thunder],
11
+ [20, :rain],
12
+ [30, :fog],
13
+ [40, :clouds],
14
+ [55, :fair_skies],
15
+ [85, :clear_skies],
16
+ [nil, :fair_skies],
17
+ ])
18
+ CentralThanalan = Zone.new(:central_thanalan, [
19
+ [15, :dust_storms],
20
+ [55, :clear_skies],
21
+ [75, :fair_skies],
22
+ [85, :clouds],
23
+ [95, :fog],
24
+ [nil, :rain],
25
+ ])
26
+ CoerthasCentralHighlands = Zone.new(:coerthas_central_highlands, [
27
+ [20, :blizzards],
28
+ [60, :snow],
29
+ [70, :fair_skies],
30
+ [75, :clear_skies],
31
+ [90, :clouds],
32
+ [nil, :fog],
33
+ ])
34
+ CoerthasWesternHighlands = Zone.new(:coerthas_western_highlands, [
35
+ [20, :blizzards],
36
+ [60, :snow],
37
+ [70, :fair_skies],
38
+ [75, :clear_skies],
39
+ [90, :clouds],
40
+ [nil, :fog],
41
+ ])
42
+ EasternLaNoscea = Zone.new(:eastern_la_noscea, [
43
+ [5, :fog],
44
+ [50, :clear_skies],
45
+ [80, :fair_skies],
46
+ [90, :clouds],
47
+ [95, :rain],
48
+ [nil, :showers],
49
+ ])
50
+ EasternThanalan = Zone.new(:eastern_thanalan, [
51
+ [40, :clear_skies],
52
+ [60, :fair_skies],
53
+ [70, :clouds],
54
+ [80, :fog],
55
+ [85, :rain],
56
+ [nil, :showers],
57
+ ])
58
+ EastShroud = Zone.new(:east_shroud, [
59
+ [5, :thunder],
60
+ [20, :rain],
61
+ [30, :fog],
62
+ [40, :clouds],
63
+ [55, :fair_skies],
64
+ [85, :clear_skies],
65
+ [nil, :fair_skies],
66
+ ])
67
+ EurekaAnemos = Zone.new(:eureka_anemos, [
68
+ [30, :fair_skies],
69
+ [60, :gales],
70
+ [90, :showers],
71
+ [nil, :snow],
72
+ ])
73
+ Gridania = Zone.new(:gridania, [
74
+ [20, :rain],
75
+ [30, :fog],
76
+ [40, :clouds],
77
+ [55, :fair_skies],
78
+ [85, :clear_skies],
79
+ [nil, :fair_skies],
80
+ ])
81
+ Idyllshire = Zone.new(:idyllshire, [
82
+ [10, :clouds],
83
+ [20, :fog],
84
+ [30, :rain],
85
+ [40, :showers],
86
+ [70, :clear_skies],
87
+ [nil, :fair_skies],
88
+ ])
89
+ Ishgard = Zone.new(:ishgard, [
90
+ [60, :snow],
91
+ [70, :fair_skies],
92
+ [75, :clear_skies],
93
+ [90, :clouds],
94
+ [nil, :fog],
95
+ ])
96
+ Kugane = Zone.new(:kugane, [
97
+ [10, :rain],
98
+ [20, :fog],
99
+ [40, :clouds],
100
+ [80, :fair_skies],
101
+ [nil, :clear_skies],
102
+ ])
103
+ LimsaLominsa = Zone.new(:limsa_lominsa, [
104
+ [20, :clouds],
105
+ [50, :clear_skies],
106
+ [80, :fair_skies],
107
+ [90, :fog],
108
+ [nil, :rain],
109
+ ])
110
+ LowerLaNoscea = Zone.new(:lower_la_noscea, [
111
+ [20, :clouds],
112
+ [50, :clear_skies],
113
+ [70, :fair_skies],
114
+ [80, :wind],
115
+ [90, :fog],
116
+ [nil, :rain],
117
+ ])
118
+ MiddleLaNoscea = Zone.new(:middle_la_noscea, [
119
+ [20, :clouds],
120
+ [50, :clear_skies],
121
+ [70, :fair_skies],
122
+ [80, :wind],
123
+ [90, :fog],
124
+ [nil, :rain],
125
+ ])
126
+ Mist = Zone.new(:mist, [
127
+ [20, :clouds],
128
+ [50, :clear_skies],
129
+ [70, :fair_skies],
130
+ [80, :fog],
131
+ [nil, :rain],
132
+ ])
133
+ MorDhona = Zone.new(:mor_dhona, [
134
+ [15, :clouds],
135
+ [30, :fog],
136
+ [60, :gloom],
137
+ [75, :clear_skies],
138
+ [nil, :fair_skies],
139
+ ])
140
+ NorthernThanalan = Zone.new(:northern_thanalan, [
141
+ [5, :clear_skies],
142
+ [20, :fair_skies],
143
+ [50, :clouds],
144
+ [nil, :fog],
145
+ ])
146
+ NorthShroud = Zone.new(:north_shroud, [
147
+ [5, :fog],
148
+ [10, :showers],
149
+ [25, :rain],
150
+ [30, :fog],
151
+ [40, :clouds],
152
+ [70, :fair_skies],
153
+ [nil, :clear_skies],
154
+ ])
155
+ OuterLaNoscea = Zone.new(:outer_la_noscea, [
156
+ [30, :clear_skies],
157
+ [50, :fair_skies],
158
+ [70, :clouds],
159
+ [85, :fog],
160
+ [nil, :rain],
161
+ ])
162
+ RhalgrsReach = Zone.new(:rhalgrs_reach, [
163
+ [15, :clear_skies],
164
+ [60, :fair_skies],
165
+ [80, :clouds],
166
+ [90, :fog],
167
+ [nil, :thunder],
168
+ ])
169
+ Shirogane = Zone.new(:shirogane, [
170
+ [10, :rain],
171
+ [20, :fog],
172
+ [40, :clouds],
173
+ [80, :fair_skies],
174
+ [nil, :clear_skies],
175
+ ])
176
+ SouthernThanalan = Zone.new(:southern_thanalan, [
177
+ [20, :heat_waves],
178
+ [60, :clear_skies],
179
+ [80, :fair_skies],
180
+ [90, :clouds],
181
+ [nil, :fog],
182
+ ])
183
+ SouthShroud = Zone.new(:south_shroud, [
184
+ [5, :fog],
185
+ [10, :thunderstorms],
186
+ [25, :thunder],
187
+ [30, :fog],
188
+ [40, :clouds],
189
+ [70, :fair_skies],
190
+ [nil, :clear_skies],
191
+ ])
192
+ TheAzimSteppe = Zone.new(:the_azim_steppe, [
193
+ [5, :gales],
194
+ [10, :wind],
195
+ [17, :rain],
196
+ [25, :fog],
197
+ [35, :clouds],
198
+ [75, :fair_skies],
199
+ [nil, :clear_skies],
200
+ ])
201
+ TheChurningMists = Zone.new(:the_churning_mists, [
202
+ [10, :clouds],
203
+ [20, :gales],
204
+ [40, :umbral_static],
205
+ [70, :clear_skies],
206
+ [nil, :fair_skies],
207
+ ])
208
+ TheDravanianForelands = Zone.new(:the_dravanian_forelands, [
209
+ [10, :clouds],
210
+ [20, :fog],
211
+ [30, :thunder],
212
+ [40, :dust_storms],
213
+ [70, :clear_skies],
214
+ [nil, :fair_skies],
215
+ ])
216
+ TheDravanianHinterlands = Zone.new(:the_dravanian_hinterlands, [
217
+ [10, :clouds],
218
+ [20, :fog],
219
+ [30, :rain],
220
+ [40, :showers],
221
+ [70, :clear_skies],
222
+ [nil, :fair_skies],
223
+ ])
224
+ TheFringes = Zone.new(:the_fringes, [
225
+ [15, :clear_skies],
226
+ [60, :fair_skies],
227
+ [80, :clouds],
228
+ [90, :fog],
229
+ [nil, :thunder],
230
+ ])
231
+ TheGoblet = Zone.new(:the_goblet, [
232
+ [40, :clear_skies],
233
+ [60, :fair_skies],
234
+ [85, :clouds],
235
+ [95, :fog],
236
+ [nil, :rain],
237
+ ])
238
+ TheLavenderBeds = Zone.new(:the_lavender_beds, [
239
+ [5, :clouds],
240
+ [20, :rain],
241
+ [30, :fog],
242
+ [40, :clouds],
243
+ [55, :fair_skies],
244
+ [85, :clear_skies],
245
+ [nil, :fair_skies],
246
+ ])
247
+ TheLochs = Zone.new(:the_lochs, [
248
+ [20, :clear_skies],
249
+ [60, :fair_skies],
250
+ [80, :clouds],
251
+ [90, :fog],
252
+ [nil, :thunderstorms],
253
+ ])
254
+ ThePeaks = Zone.new(:the_peaks, [
255
+ [10, :clear_skies],
256
+ [60, :fair_skies],
257
+ [75, :clouds],
258
+ [85, :fog],
259
+ [95, :wind],
260
+ [nil, :dust_storms],
261
+ ])
262
+ TheRubySea = Zone.new(:the_ruby_sea, [
263
+ [10, :thunder],
264
+ [20, :wind],
265
+ [35, :clouds],
266
+ [75, :fair_skies],
267
+ [nil, :clear_skies],
268
+ ])
269
+ TheSeaOfClouds = Zone.new(:the_sea_of_clouds, [
270
+ [30, :clear_skies],
271
+ [60, :fair_skies],
272
+ [70, :clouds],
273
+ [80, :fog],
274
+ [90, :wind],
275
+ [nil, :umbral_wind],
276
+ ])
277
+ Uldah = Zone.new(:uldah, [
278
+ [40, :clear_skies],
279
+ [60, :fair_skies],
280
+ [85, :clouds],
281
+ [95, :fog],
282
+ [nil, :rain],
283
+ ])
284
+ UpperLaNoscea = Zone.new(:upper_la_noscea, [
285
+ [30, :clear_skies],
286
+ [50, :fair_skies],
287
+ [70, :clouds],
288
+ [80, :fog],
289
+ [90, :thunder],
290
+ [nil, :thunderstorms],
291
+ ])
292
+ WesternLaNoscea = Zone.new(:western_la_noscea, [
293
+ [10, :fog],
294
+ [40, :clear_skies],
295
+ [60, :fair_skies],
296
+ [80, :clouds],
297
+ [90, :wind],
298
+ [nil, :gales],
299
+ ])
300
+ WesternThanalan = Zone.new(:western_thanalan, [
301
+ [40, :clear_skies],
302
+ [60, :fair_skies],
303
+ [85, :clouds],
304
+ [95, :fog],
305
+ [nil, :rain],
306
+ ])
307
+ Yanxia = Zone.new(:yanxia, [
308
+ [5, :showers],
309
+ [15, :rain],
310
+ [25, :fog],
311
+ [40, :clouds],
312
+ [80, :fair_skies],
313
+ [nil, :clear_skies],
314
+ ])
315
+
316
+ MAP = (self.constants - [:MAP]).map(&self.method(:const_get)).map{ |_| [_.id, _] }.to_h
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,7 @@
1
+ module EorzeaWeather
2
+ Locale = Struct.new(:id, :weather, :zone) do
3
+ def inspect
4
+ "#<#{self.class}: #{id}>"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ require 'eorzea_weather/locale'
2
+ require 'eorzea_weather/data/locales'
3
+
4
+ module EorzeaWeather
5
+ class Localizer
6
+ def initialize(kind, id)
7
+ @kind = kind
8
+ @id = id
9
+ end
10
+
11
+ attr_reader :kind, :id
12
+
13
+ def [](locale)
14
+ to_h[locale] || id.to_s
15
+ end
16
+
17
+ def to_h
18
+ @hash ||= Data::Locales::MAP.map { |lid, locale| [lid, locale.__send__(kind)[id]] }.select { |(_,v)| v }.to_h
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module EorzeaWeather
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,7 @@
1
+ module EorzeaWeather
2
+ Zone = Struct.new(:id, :rates) do
3
+ def find_rate(rate)
4
+ rates.find { |(threshold, _weather)| threshold.nil? || rate < threshold }[1]
5
+ end
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eorzea_weather
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sorah Fukumori
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-04-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eorzea_time
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description:
70
+ email:
71
+ - her@sorah.jp
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/console
84
+ - bin/setup
85
+ - eorzea_weather.gemspec
86
+ - lib/eorzea_weather.rb
87
+ - lib/eorzea_weather/calculator.rb
88
+ - lib/eorzea_weather/data/locales.rb
89
+ - lib/eorzea_weather/data/weathers.rb
90
+ - lib/eorzea_weather/data/zones.rb
91
+ - lib/eorzea_weather/locale.rb
92
+ - lib/eorzea_weather/localizer.rb
93
+ - lib/eorzea_weather/version.rb
94
+ - lib/eorzea_weather/zone.rb
95
+ homepage: https://github.com/sorah/eorzea_weather
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.7.6
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: Eorzean Weather Forecast
119
+ test_files: []