himawari 0.1.1 → 0.1.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/.circleci/config.yml +83 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +22 -1
- data/README.md +21 -8
- data/bin/setup +26 -2
- data/himawari.gemspec +10 -2
- data/lib/himawari.rb +18 -5
- data/lib/himawari/base.rb +28 -6
- data/lib/himawari/download.rb +28 -2
- data/lib/himawari/net_utils.rb +9 -3
- data/lib/himawari/no_image.png +0 -0
- data/lib/himawari/os_utils.rb +24 -4
- data/lib/himawari/process.rb +25 -4
- data/spec/test_helper.rb +2 -1
- data/spec/test_net.rb +3 -2
- metadata +22 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f67123afba6d8051481c5edee8b11cb999d21a930ae8021147e13bbbde018a02
|
|
4
|
+
data.tar.gz: 0f954a19faef8496aef9078c5c6edf6a2526cec9f623eda1ac2f56b4fd315361
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 35f60401505b46fcf262a21132d7e3f52c5c05f6872dfa661932209c1596f95cace6476b3f237163cd6f3ac36d39424c8bc4b2c2a79f1e4e156d421e221347af
|
|
7
|
+
data.tar.gz: c82c5910d7191ffee0593d34beb5be21258d42dad88f23f7f15129b07cf295024287f2e01aef4d7ae1aa1bbb335628e4a9ed0a19a5c68547d5a1ca6907139097
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
version: 2.1
|
|
2
|
+
orbs:
|
|
3
|
+
ruby: circleci/ruby@1.1.2
|
|
4
|
+
|
|
5
|
+
executors:
|
|
6
|
+
super-ruby:
|
|
7
|
+
docker:
|
|
8
|
+
- image: cimg/ruby:2.5-node
|
|
9
|
+
environment:
|
|
10
|
+
BUNDLE_PATH: vendor/bundle
|
|
11
|
+
CUSTOM_VAR: whatever
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
checkout_code:
|
|
15
|
+
executor: super-ruby
|
|
16
|
+
steps:
|
|
17
|
+
- attach_workspace:
|
|
18
|
+
at: .
|
|
19
|
+
- checkout
|
|
20
|
+
- ruby/install-deps: # aka bundle install
|
|
21
|
+
path: $BUNDLE_PATH
|
|
22
|
+
- persist_to_workspace:
|
|
23
|
+
root: .
|
|
24
|
+
paths: .
|
|
25
|
+
|
|
26
|
+
build:
|
|
27
|
+
executor: super-ruby
|
|
28
|
+
steps:
|
|
29
|
+
- attach_workspace:
|
|
30
|
+
at: .
|
|
31
|
+
- run:
|
|
32
|
+
name: Just Playing Around
|
|
33
|
+
command: mkdir $CUSTOM_VAR && touch $CUSTOM_VAR/some_special_file
|
|
34
|
+
- persist_to_workspace:
|
|
35
|
+
root: .
|
|
36
|
+
paths:
|
|
37
|
+
- whatever
|
|
38
|
+
|
|
39
|
+
bundle_audit:
|
|
40
|
+
executor: super-ruby
|
|
41
|
+
steps:
|
|
42
|
+
- attach_workspace:
|
|
43
|
+
at: .
|
|
44
|
+
- run:
|
|
45
|
+
name: Bundle Audit
|
|
46
|
+
when: always
|
|
47
|
+
command: gem install bundle-audit && bundle-audit update && bundle-audit check
|
|
48
|
+
|
|
49
|
+
rubocop:
|
|
50
|
+
executor: super-ruby
|
|
51
|
+
steps:
|
|
52
|
+
- attach_workspace:
|
|
53
|
+
at: .
|
|
54
|
+
- run: bundle exec rubocop
|
|
55
|
+
|
|
56
|
+
spec:
|
|
57
|
+
executor: super-ruby
|
|
58
|
+
steps:
|
|
59
|
+
- attach_workspace:
|
|
60
|
+
at: .
|
|
61
|
+
- run:
|
|
62
|
+
name: Test
|
|
63
|
+
command: |
|
|
64
|
+
ls -l $CUSTOM_VAR
|
|
65
|
+
./bin/setup && bundle exec rake test
|
|
66
|
+
|
|
67
|
+
workflows:
|
|
68
|
+
version: 2
|
|
69
|
+
build_and_test:
|
|
70
|
+
jobs:
|
|
71
|
+
- checkout_code
|
|
72
|
+
- build:
|
|
73
|
+
requires:
|
|
74
|
+
- checkout_code
|
|
75
|
+
- bundle_audit:
|
|
76
|
+
requires:
|
|
77
|
+
- checkout_code
|
|
78
|
+
- rubocop:
|
|
79
|
+
requires:
|
|
80
|
+
- build
|
|
81
|
+
- spec:
|
|
82
|
+
requires:
|
|
83
|
+
- build
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
# 0.1.2
|
|
2
|
+
- Updated Readme with more details
|
|
3
|
+
- Updated meta links in gemspec
|
|
4
|
+
- Fixed a crash/bug related to missing a png file (I forgot that we actually DO need one of those pngs. It is used as a control to compare downloaded images against.)
|
|
5
|
+
- ```/var/lib/gems/2.5.0/gems/himawari-0.1.1/lib/himawari/process.rb:14:in `size': No such file or directory @ rb_file_s_size - /var/lib/gems/2.5.0/gems/himawari-0.1.1/lib/himawari/no_image.png (Errno::ENOENT)```
|
|
6
|
+
|
|
1
7
|
# 0.1.1
|
|
2
8
|
- Updated Readme
|
|
3
9
|
- Added changelog
|
data/Gemfile.lock
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
himawari (0.1.
|
|
4
|
+
himawari (0.1.2)
|
|
5
5
|
httparty (~> 0.17.3)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
+
ast (2.4.1)
|
|
10
11
|
coderay (1.1.2)
|
|
11
12
|
httparty (0.17.3)
|
|
12
13
|
mime-types (~> 3.0)
|
|
@@ -17,10 +18,29 @@ GEM
|
|
|
17
18
|
mime-types-data (3.2019.1009)
|
|
18
19
|
minitest (5.14.0)
|
|
19
20
|
multi_xml (0.6.0)
|
|
21
|
+
parallel (1.19.1)
|
|
22
|
+
parser (2.7.2.0)
|
|
23
|
+
ast (~> 2.4.1)
|
|
20
24
|
pry (0.13.1)
|
|
21
25
|
coderay (~> 1.1)
|
|
22
26
|
method_source (~> 1.0)
|
|
27
|
+
rainbow (3.0.0)
|
|
23
28
|
rake (13.0.1)
|
|
29
|
+
regexp_parser (1.8.2)
|
|
30
|
+
rexml (3.2.4)
|
|
31
|
+
rubocop (1.6.1)
|
|
32
|
+
parallel (~> 1.10)
|
|
33
|
+
parser (>= 2.7.1.5)
|
|
34
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
35
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
36
|
+
rexml
|
|
37
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
|
38
|
+
ruby-progressbar (~> 1.7)
|
|
39
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
|
40
|
+
rubocop-ast (1.3.0)
|
|
41
|
+
parser (>= 2.7.1.5)
|
|
42
|
+
ruby-progressbar (1.10.1)
|
|
43
|
+
unicode-display_width (1.7.0)
|
|
24
44
|
|
|
25
45
|
PLATFORMS
|
|
26
46
|
ruby
|
|
@@ -31,6 +51,7 @@ DEPENDENCIES
|
|
|
31
51
|
minitest (~> 5.14.0)
|
|
32
52
|
pry (~> 0.13.1)
|
|
33
53
|
rake (~> 13.0.1)
|
|
54
|
+
rubocop (~> 1.6)
|
|
34
55
|
|
|
35
56
|
BUNDLED WITH
|
|
36
57
|
2.1.4
|
data/README.md
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# himawari
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
[](https://codeclimate.com/github/engura/himawari)
|
|
5
|
+
[](https://inch-ci.org/github/engura/himawari)
|
|
6
|
+
[](https://app.circleci.com/pipelines/github/engura/himawari)
|
|
7
|
+
|
|
8
|
+
[](https://rubygems.org/gems/himawari)
|
|
9
|
+
[](https://rubygems.org/gems/himawari)
|
|
10
|
+

|
|
11
|
+

|
|
12
|
+
[](https://opensource.org/licenses/MIT)
|
|
13
|
+
|
|
14
|
+
<details>
|
|
15
|
+
<summary>TOC</summary>
|
|
16
|
+
|
|
2
17
|
- [about](#himawari)
|
|
3
18
|
- [installing](#installation)
|
|
4
19
|
- [using](#usage)
|
|
@@ -6,8 +21,8 @@
|
|
|
6
21
|
- [development](#development)
|
|
7
22
|
- [contributing](#contributing)
|
|
8
23
|
- [license](#license)
|
|
24
|
+
</details>
|
|
9
25
|
|
|
10
|
-
# himawari
|
|
11
26
|
Access images from the [himawari8 weather satellite](https://himawari8.nict.go.jp)] (courtesy of NICT) and compose near real-time desktop backgrounds of Earth or use the high-res images for other personal uses. For example....
|
|
12
27
|

|
|
13
28
|

|
|
@@ -26,12 +41,10 @@ Or install it yourself as:
|
|
|
26
41
|
gem install himawari
|
|
27
42
|
```
|
|
28
43
|
## Install CLI Dependencies
|
|
29
|
-
Mac:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
or Linux: run `bin/setup`
|
|
44
|
+
Mac/Linux: run `bin/setup`
|
|
45
|
+
On other systems, please try to install `imagemagick` and `parallel` utilities manually...
|
|
46
|
+
https://linux.die.net/man/1/parallel
|
|
47
|
+
https://github.com/minimagick/minimagick
|
|
35
48
|
|
|
36
49
|
# Usage
|
|
37
50
|
|
data/bin/setup
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
echo 'Installing CLI Dependencies'
|
|
3
|
-
sudo apt-get install -y parallel imagemagick
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
ERR_MESSG="Didn't test under this environment; nothing installed.\nPlease try to install parallel && imagemagick utils manually!"
|
|
5
|
+
|
|
6
|
+
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
7
|
+
sudo apt-get update && sudo apt-get install -y parallel imagemagick wireless-tools
|
|
8
|
+
yes 'will cite' | parallel --citation
|
|
9
|
+
bundle install
|
|
10
|
+
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
|
11
|
+
brew install imagemagick parallel
|
|
12
|
+
yes 'will cite' | parallel --citation
|
|
13
|
+
bundle install
|
|
14
|
+
elif [[ "$OSTYPE" == "cygwin" ]]; then
|
|
15
|
+
# POSIX compatibility layer and Linux environment emulation for Windows
|
|
16
|
+
echo $ERR_MESSG
|
|
17
|
+
elif [[ "$OSTYPE" == "msys" ]]; then
|
|
18
|
+
# Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
|
|
19
|
+
echo $ERR_MESSG
|
|
20
|
+
elif [[ "$OSTYPE" == "win32" ]]; then
|
|
21
|
+
# I'm not sure this can happen.
|
|
22
|
+
echo $ERR_MESSG
|
|
23
|
+
elif [[ "$OSTYPE" == "freebsd"* ]]; then
|
|
24
|
+
# ...
|
|
25
|
+
echo $ERR_MESSG
|
|
26
|
+
else
|
|
27
|
+
# Unknown.
|
|
28
|
+
echo $ERR_MESSG
|
|
29
|
+
fi
|
data/himawari.gemspec
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = 'himawari'
|
|
5
|
-
s.version = '0.1.
|
|
5
|
+
s.version = '0.1.2'
|
|
6
6
|
s.date = '2020-12-15'
|
|
7
7
|
s.summary = 'Grabs latest images from the himawari8 weather satellite'
|
|
8
8
|
s.description = 'Makes pretty, high-res backgrounds from the real-time photos of Earth by Himawari8, ' \
|
|
@@ -12,12 +12,19 @@ Gem::Specification.new do |s|
|
|
|
12
12
|
s.homepage = 'https://github.com/engura/himawari'
|
|
13
13
|
s.license = 'MIT'
|
|
14
14
|
|
|
15
|
-
s.files = `git ls-files -- . ':!:*.png'`.split
|
|
15
|
+
s.files = `git ls-files -- . ':!:*.png'`.split + ['lib/himawari/no_image.png']
|
|
16
16
|
s.bindir = 'exe'
|
|
17
17
|
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
18
18
|
s.test_files = s.files.grep(%r{^(tests|spec|features)/})
|
|
19
19
|
s.require_paths = ['lib']
|
|
20
20
|
|
|
21
|
+
s.metadata = {
|
|
22
|
+
'homepage_uri' => 'https://github.com/engura/himawari',
|
|
23
|
+
'changelog_uri' => 'https://github.com/engura/himawari/blob/master/CHANGELOG.md',
|
|
24
|
+
'source_code_uri' => 'https://github.com/engura/himawari',
|
|
25
|
+
'bug_tracker_uri' => 'https://github.com/engura/himawari/issues'
|
|
26
|
+
}
|
|
27
|
+
|
|
21
28
|
s.required_ruby_version = '>= 2.5'
|
|
22
29
|
|
|
23
30
|
s.add_runtime_dependency 'httparty', '~> 0.17.3'
|
|
@@ -26,6 +33,7 @@ Gem::Specification.new do |s|
|
|
|
26
33
|
s.add_development_dependency 'minitest', '~> 5.14.0'
|
|
27
34
|
s.add_development_dependency 'pry', '~> 0.13.1'
|
|
28
35
|
s.add_development_dependency 'rake', '~> 13.0.1'
|
|
36
|
+
s.add_development_dependency 'rubocop', '~> 1.6'
|
|
29
37
|
|
|
30
38
|
s.requirements << 'Mac OSX or Linux... Windows `not supported yet` due to the lack of the following:'
|
|
31
39
|
s.requirements << 'parallel, ~>20161222 (Let\'s download in parallel)'
|
data/lib/himawari.rb
CHANGED
|
@@ -1,28 +1,41 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
|
-
require_relative './himawari/base
|
|
4
|
-
require_relative './himawari/os_utils
|
|
5
|
-
require_relative './himawari/net_utils
|
|
6
|
-
require_relative './himawari/process
|
|
7
|
-
require_relative './himawari/download
|
|
3
|
+
require_relative './himawari/base'
|
|
4
|
+
require_relative './himawari/os_utils'
|
|
5
|
+
require_relative './himawari/net_utils'
|
|
6
|
+
require_relative './himawari/process'
|
|
7
|
+
require_relative './himawari/download'
|
|
8
8
|
|
|
9
9
|
# encapsulates all the functions pertaining to acquiring images from the himawari8 satellite in near real-time
|
|
10
10
|
# from HIMAWARI_URL (defined in the Base Class)
|
|
11
11
|
module Himawari
|
|
12
|
+
# all-in-one method. downloads images, sets backgrounds, crontabs, whatever
|
|
13
|
+
# @param params [Hash] any combination of the acceptable command line args you can throw at it.
|
|
14
|
+
# Plz see README for the list/description
|
|
15
|
+
# @return nothing useful
|
|
12
16
|
def self.autorun(params = {})
|
|
13
17
|
h = Download.new(params)
|
|
14
18
|
h.cron_action ? h.crontab : h.update_backgrnd ^ h.start
|
|
15
19
|
end
|
|
16
20
|
|
|
21
|
+
# downloads 1 picture from himawari website, closest (but in the past of) the `:datetime` provided in the params
|
|
22
|
+
# @param [Hash] any combination of the acceptable command line args + THE REQUIRED `:datetime` additional stamp
|
|
23
|
+
# @return [true, false] on success/failure
|
|
17
24
|
def self.get_pic(params = {})
|
|
18
25
|
t = validate(params[:datetime])
|
|
19
26
|
Download.new(params).pic(t, OsUtils.tenmin(t.min, t.min))
|
|
20
27
|
end
|
|
21
28
|
|
|
29
|
+
# downloads many pictures from himawari website, in the range of [:from, :to] provided in the params
|
|
30
|
+
# @param [Hash] any combination of the acceptable command line args + THE REQUIRED `:from` && `:to` timestamps
|
|
31
|
+
# @return [true, false] on success/failure
|
|
22
32
|
def self.get_pics(params = {})
|
|
23
33
|
Download.new(params).pics(validate(params[:from]), validate(params[:to]))
|
|
24
34
|
end
|
|
25
35
|
|
|
36
|
+
# validates the user-provided timestamps coming from `get_pic` or `get_pics` methods
|
|
37
|
+
# @param stamp [DateTime, String]
|
|
38
|
+
# @return [DateTime] of the stamp, or the most recent round 10-minute mark to Time.now - 10.minutes
|
|
26
39
|
def self.validate(stamp)
|
|
27
40
|
return stamp if stamp.is_a? Time
|
|
28
41
|
return Time.parse("#{stamp}+00:00") if stamp.is_a? String
|
data/lib/himawari/base.rb
CHANGED
|
@@ -7,8 +7,12 @@ require 'optparse'
|
|
|
7
7
|
# require 'pry'
|
|
8
8
|
|
|
9
9
|
module Himawari
|
|
10
|
+
# This Aspect Ratio is used to try and download the most appropriate Tiles from Himawari,
|
|
11
|
+
# while omitting those that won't be visible. (used by the :focus param)
|
|
10
12
|
MONITOR_ASPECT = 16.0 / 9
|
|
11
|
-
|
|
13
|
+
# int; update the pic once every `UPDATE_RATE` minutes
|
|
14
|
+
UPDATE_RATE = 2
|
|
15
|
+
# Yep, that's the big one. Where we actually download everything from
|
|
12
16
|
HIMAWARI_URL = 'https://himawari8-dl.nict.go.jp/himawari8/img/D531106'
|
|
13
17
|
|
|
14
18
|
# Local (JST) midnight happens @14:10 UTC, so we have to use pics in interval of [2.days.ago@14:40 .. 1.day.ago@14:40]
|
|
@@ -21,8 +25,6 @@ module Himawari
|
|
|
21
25
|
attr_reader :now, :app_root, :work_path, :data_path, :destination_path, :focus, :mode, :resolution,
|
|
22
26
|
:latest_local, :latest_remote, :verbose, :by_schedule, :blacklist_wifi, :cron_action
|
|
23
27
|
|
|
24
|
-
# relative to the location of the script: Pathname.new(File.expand_path('../', __FILE__))
|
|
25
|
-
# relative to the current working dir: Dir.pwd
|
|
26
28
|
def initialize(params = {})
|
|
27
29
|
init_paths(params[:workdir])
|
|
28
30
|
@destination_path = params[:destination]
|
|
@@ -39,6 +41,7 @@ module Himawari
|
|
|
39
41
|
@cron_action = params[:cron]
|
|
40
42
|
end
|
|
41
43
|
|
|
44
|
+
# @return [true, false] whether our local pics are up to date w/ himawari website
|
|
42
45
|
def up_to_date?
|
|
43
46
|
puts "Latest local: #{latest_local[:timestamp]}" if verbose
|
|
44
47
|
if now - latest_local[:timestamp] < 10 * 60
|
|
@@ -48,6 +51,9 @@ module Himawari
|
|
|
48
51
|
false
|
|
49
52
|
end
|
|
50
53
|
|
|
54
|
+
# sets sleeps for a bit, and then copies a selected picture to the `destination_path`
|
|
55
|
+
# from where the OS can use it to set a background pic
|
|
56
|
+
# @param img [String] full path to the picture
|
|
51
57
|
def background(img)
|
|
52
58
|
return false unless img && params_valid?
|
|
53
59
|
|
|
@@ -57,6 +63,9 @@ module Himawari
|
|
|
57
63
|
system(cmd)
|
|
58
64
|
end
|
|
59
65
|
|
|
66
|
+
# useful for the "cycle through our downloaded pics and pic one for background" mode
|
|
67
|
+
# checks that we have enough pictures for a whole :day of rotation, and calls the `background` method
|
|
68
|
+
# with the appropriate picture's path based on current timestamp
|
|
60
69
|
def update_backgrnd
|
|
61
70
|
return false unless mode == :day && params_valid?
|
|
62
71
|
|
|
@@ -66,10 +75,12 @@ module Himawari
|
|
|
66
75
|
return false unless sexy_pics
|
|
67
76
|
|
|
68
77
|
i = (now.hour * 60 + now.min) / UPDATE_RATE % sexy_pics.count
|
|
69
|
-
puts "#{i} :: #{
|
|
78
|
+
puts "#{i} :: #{now.hour * 60 + now.min} % #{sexy_pics.count} switching to #{sexy_pics[i]}" if verbose
|
|
70
79
|
background(sexy_pics[i])
|
|
71
80
|
end
|
|
72
81
|
|
|
82
|
+
# public method exposing setting/clearing the crontab
|
|
83
|
+
# @param action [Symbol] should we set the cron, or clear it?
|
|
73
84
|
def crontab(action = nil)
|
|
74
85
|
@cron_action = action if action
|
|
75
86
|
return false unless cron_action && params_valid?
|
|
@@ -80,6 +91,8 @@ module Himawari
|
|
|
80
91
|
cmd
|
|
81
92
|
end
|
|
82
93
|
|
|
94
|
+
# verifies the required params that user might have messed up.
|
|
95
|
+
# @return [true, false] depending on the validity of the parameters supplied
|
|
83
96
|
def params_valid?
|
|
84
97
|
unless %i[full top mid low].include?(focus) && %i[live day].include?(mode) &&
|
|
85
98
|
[2, 4, 8, 16, 20].include?(resolution) && blacklist_wifi.is_a?(Array) &&
|
|
@@ -92,7 +105,8 @@ module Himawari
|
|
|
92
105
|
|
|
93
106
|
private
|
|
94
107
|
|
|
95
|
-
#
|
|
108
|
+
# @return [Array <String>] of pic_names to choose a `background` from, or
|
|
109
|
+
# false if we do not have enough pictures for a full 24hr rotation
|
|
96
110
|
def full_24hrs_available
|
|
97
111
|
prev_pic = ''
|
|
98
112
|
sexy_pics = []
|
|
@@ -107,6 +121,12 @@ module Himawari
|
|
|
107
121
|
false
|
|
108
122
|
end
|
|
109
123
|
|
|
124
|
+
# relative to the location of the script: Pathname.new(File.expand_path('../', __FILE__))
|
|
125
|
+
# relative to the current working dir: Dir.pwd
|
|
126
|
+
# sets the paths for the script
|
|
127
|
+
# @param workdir [String] is taken from the param that the user supplied (or defaults to pwd)
|
|
128
|
+
# (it's where we want to save the images from himawari)
|
|
129
|
+
# the directory will be created if it doesn't exist yet
|
|
110
130
|
def init_paths(workdir)
|
|
111
131
|
@app_root = workdir && File.directory?(workdir) ? workdir : Dir.pwd
|
|
112
132
|
@work_path = @app_root
|
|
@@ -116,6 +136,8 @@ module Himawari
|
|
|
116
136
|
Dir.mkdir(@data_path) unless File.exist?(@data_path)
|
|
117
137
|
end
|
|
118
138
|
|
|
139
|
+
# scans the `workdir` and
|
|
140
|
+
# @return [DateTime] of the most recent picture saved in `workdir`
|
|
119
141
|
def find_latest_local
|
|
120
142
|
# we can't select by timestamp, because those could be messed up. Instead, just search for "latest" by filename
|
|
121
143
|
# latest_pic = `ls -t #{data_path}/h_* | head -1`
|
|
@@ -124,7 +146,7 @@ module Himawari
|
|
|
124
146
|
failsafe = { filename: nil, timestamp: Time.new(twodays_ago.year, twodays_ago.month, twodays_ago.day, 0, 0, 0, '+00:00') }
|
|
125
147
|
|
|
126
148
|
Dir["#{data_path}/h_*.png"].each do |pic|
|
|
127
|
-
stamp = Time.parse(pic[0..-5].insert(-3, ':')
|
|
149
|
+
stamp = Time.parse("#{pic[0..-5].insert(-3, ':')}:00+00:00")
|
|
128
150
|
`touch -t #{stamp.strftime('%Y%m%d%H%M.%S')} #{pic}`
|
|
129
151
|
latest = { filename: pic, timestamp: stamp } if !latest[:timestamp] || latest[:timestamp] < stamp
|
|
130
152
|
end
|
data/lib/himawari/download.rb
CHANGED
|
@@ -11,6 +11,8 @@ module Himawari
|
|
|
11
11
|
include NetUtils
|
|
12
12
|
include Process
|
|
13
13
|
|
|
14
|
+
# go go go
|
|
15
|
+
# @return nothing useful
|
|
14
16
|
def start
|
|
15
17
|
return false unless everything_ok && pics_updated?
|
|
16
18
|
|
|
@@ -19,6 +21,10 @@ module Himawari
|
|
|
19
21
|
`find #{data_path} -name \"*.png\" -type f -mtime +2 -exec rm -f {} \\;`
|
|
20
22
|
end
|
|
21
23
|
|
|
24
|
+
# the public method to download pics in w/in the datetime range
|
|
25
|
+
# @param from_datetime [DateTime]
|
|
26
|
+
# @param to_datetime [DateTime]
|
|
27
|
+
# @return [true, false] depending on the success/failure of the download operation
|
|
22
28
|
def pics(from_datetime, to_datetime)
|
|
23
29
|
# returns true if any new pictures were downloaded from the web, false otherwise
|
|
24
30
|
pic_dwnlded = false
|
|
@@ -50,6 +56,12 @@ module Himawari
|
|
|
50
56
|
pic_dwnlded
|
|
51
57
|
end
|
|
52
58
|
|
|
59
|
+
# Sometimes is called from the `pics` method. Downloads one pic from himawari
|
|
60
|
+
# (in many tiles) and then reassembles the pieces back into one image
|
|
61
|
+
# @param timestamp [DateTime]
|
|
62
|
+
# @param tenmin [String] this is the crucial ending bit for himawari website that is used by parallel.
|
|
63
|
+
# 10 minutes gets converted into 1; 40mins -> 4, etc.
|
|
64
|
+
# @return [true, false] depending on the success/failure of the download
|
|
53
65
|
# `parallel --header : 'montage -mode concatenate -tile 2x {00,10,01,11}/{year}-{mo}-{dy}T{hr}{tenmin}000-*.png
|
|
54
66
|
# full/{year}-{mo}-{dy}T{hr}{tenmin}000.png' ::: year 2015 ::: mo 11 ::: dy {27..28} ::: hr {00..23} ::: tenmin {0..5}`
|
|
55
67
|
def pic(timestamp, tenmin = '{0..5}')
|
|
@@ -94,10 +106,18 @@ module Himawari
|
|
|
94
106
|
|
|
95
107
|
private
|
|
96
108
|
|
|
109
|
+
# verifies the params passed from user and the various internet-related checks
|
|
110
|
+
# @return [true, false]
|
|
97
111
|
def everything_ok
|
|
98
112
|
@everything_ok ||= params_valid? && checks_passed?
|
|
99
113
|
end
|
|
100
114
|
|
|
115
|
+
# internet-related checks:
|
|
116
|
+
# black listed wifi!!!
|
|
117
|
+
# don't spam himawari's website more than once every 10 minutes!!! (they only take pics so frequently after all)
|
|
118
|
+
# don't start downloading stuff if something is STILL downloading from before (check by presense of Tiles in the data dir)
|
|
119
|
+
# oh, yeah, and check if we even have internet connection at all
|
|
120
|
+
# @return [true, false]
|
|
101
121
|
def checks_passed?
|
|
102
122
|
if blacklisted_wifi?
|
|
103
123
|
puts "Blacklisted Network; Won't go online"
|
|
@@ -120,19 +140,25 @@ module Himawari
|
|
|
120
140
|
true
|
|
121
141
|
end
|
|
122
142
|
|
|
143
|
+
# had to take this check out of pics method due to "complexity"
|
|
123
144
|
def last_iter?(from, to)
|
|
124
145
|
from.day == to.day && from.hour == to.hour
|
|
125
146
|
end
|
|
126
147
|
|
|
148
|
+
# checks whether our local pics are actually up-to-date w/ what's available on himawari's website
|
|
127
149
|
def pics_updated?
|
|
128
150
|
pics(latest_local[:timestamp], latest_remote) unless up_to_date?
|
|
129
151
|
end
|
|
130
152
|
|
|
153
|
+
# let's calculate the region of tiles that we need to download from himawari based on
|
|
154
|
+
# what the user's :focus setting is
|
|
155
|
+
# @return [Array] x, y coordinates (dimensions?) of the tiles that we need to download
|
|
131
156
|
def download_region
|
|
132
157
|
x = "{0..#{resolution - 1}}"
|
|
133
|
-
y =
|
|
158
|
+
y = case focus # :full :mid :low
|
|
159
|
+
when :top
|
|
134
160
|
"{0..#{(resolution / MONITOR_ASPECT).ceil - 1}}"
|
|
135
|
-
|
|
161
|
+
when :low
|
|
136
162
|
"{#{resolution - (resolution / MONITOR_ASPECT).ceil}..#{resolution - 1}}"
|
|
137
163
|
else # full / mid
|
|
138
164
|
"{0..#{resolution - 1}}"
|
data/lib/himawari/net_utils.rb
CHANGED
|
@@ -4,13 +4,16 @@ module Himawari
|
|
|
4
4
|
# Network-related methods to help establish whether there is network access and
|
|
5
5
|
# figure out if we are on a possibly "metered" connection (via a hard-coded SSID blacklist)
|
|
6
6
|
module NetUtils
|
|
7
|
+
# Checks our connection and as a bonus...
|
|
8
|
+
# @return [DateTime] timestamp of the latest himawari image; also as a side-efffect:
|
|
9
|
+
# true, false whether we even have connection to the website
|
|
7
10
|
def internet_connection?
|
|
8
11
|
uid = now.to_i * 1_000
|
|
9
12
|
r = HTTParty.get("#{HIMAWARI_URL}/latest.json?uid=#{uid}", { timeout: 10 })
|
|
10
13
|
# puts "#{HIMAWARI_URL}/latest.json?uid=#{uid}" if verbose
|
|
11
14
|
if r.code == 200
|
|
12
15
|
puts "Latest Himawari: #{r['date']}" if verbose
|
|
13
|
-
@latest_remote = Time.parse(r['date']
|
|
16
|
+
@latest_remote = Time.parse("#{r['date']}+00:00")
|
|
14
17
|
return true
|
|
15
18
|
end
|
|
16
19
|
false
|
|
@@ -18,10 +21,13 @@ module Himawari
|
|
|
18
21
|
|
|
19
22
|
private
|
|
20
23
|
|
|
24
|
+
# Sometimes we don't want to use a particular network to download large amounts of data...
|
|
25
|
+
# @return [true, false] whether the current (wifi) network is blacklisted in the blacklist_wifi [Array]
|
|
21
26
|
def blacklisted_wifi?
|
|
22
|
-
current_wifi =
|
|
27
|
+
current_wifi = case OsUtils.os
|
|
28
|
+
when :mac
|
|
23
29
|
`networksetup -getairportnetwork en0`
|
|
24
|
-
|
|
30
|
+
when :linux
|
|
25
31
|
`iwgetid -r`
|
|
26
32
|
end
|
|
27
33
|
puts current_wifi if verbose
|
|
Binary file
|
data/lib/himawari/os_utils.rb
CHANGED
|
@@ -3,14 +3,17 @@
|
|
|
3
3
|
module Himawari
|
|
4
4
|
# all the misc. functions for dealing with CLI and/or OS...
|
|
5
5
|
module OsUtils
|
|
6
|
+
# we gotta know what the user's OS is! (because we rely on command line utils to process images)
|
|
7
|
+
# @return [Symbol] representing the OS being used
|
|
6
8
|
def self.os
|
|
7
|
-
|
|
9
|
+
case RUBY_PLATFORM
|
|
10
|
+
when /win32/
|
|
8
11
|
:win
|
|
9
|
-
|
|
12
|
+
when /linux/
|
|
10
13
|
:linux
|
|
11
|
-
|
|
14
|
+
when /darwin/
|
|
12
15
|
:mac
|
|
13
|
-
|
|
16
|
+
when /freebsd/
|
|
14
17
|
:freebsd
|
|
15
18
|
else
|
|
16
19
|
:unknown
|
|
@@ -18,6 +21,8 @@ module Himawari
|
|
|
18
21
|
end
|
|
19
22
|
|
|
20
23
|
# rubocop:disable Metrics/MethodLength, Metrics/BlockLength
|
|
24
|
+
# This is just a list of args that the CLI can accept
|
|
25
|
+
# @return [Hash] of cleaned/verified params
|
|
21
26
|
def self.parse_cli_args
|
|
22
27
|
params = {}
|
|
23
28
|
|
|
@@ -80,12 +85,23 @@ module Himawari
|
|
|
80
85
|
end
|
|
81
86
|
# rubocop:enable Metrics/MethodLength, Metrics/BlockLength
|
|
82
87
|
|
|
88
|
+
# Ok, this is a weird method. On Mac, `script` just ran normally through ruby. But, on linux...
|
|
89
|
+
# It is refusing to interpolate variables within the `script` string properly.
|
|
90
|
+
# So, we'll make a temporary bash script, execute it, and then delete it.
|
|
91
|
+
# @param script [String] the temp script's filename
|
|
92
|
+
# @param command [String] what we actually want to be done... (probably process pics in parallel)
|
|
93
|
+
# @return nothing useful (true on success)
|
|
83
94
|
def self.scriptify_sys(script, command)
|
|
84
95
|
`echo "#!/bin/bash\n#{command}" > #{script}`
|
|
85
96
|
`chmod +x #{script} && #{script}`
|
|
86
97
|
`rm #{script}`
|
|
87
98
|
end
|
|
88
99
|
|
|
100
|
+
# tiny helper method. converts normal minutes into the closest (floored) round ten-minutes.
|
|
101
|
+
# (ie like 10, 20, 30, 40, 50). Himawari website uses these in the tile filenames...
|
|
102
|
+
# @param from [Integer]
|
|
103
|
+
# @param to [Integer] these should be pretty self-explanatory. should be positive and w/in 0-59 range.
|
|
104
|
+
# @return [String] the formatted minute range string for `parallel` to use to download this range of pics
|
|
89
105
|
def self.tenmin(from = 0, to = 59)
|
|
90
106
|
"{#{from / 10}..#{to / 10}}"
|
|
91
107
|
end
|
|
@@ -117,6 +133,10 @@ module Himawari
|
|
|
117
133
|
# end tell
|
|
118
134
|
|
|
119
135
|
# to silence the status mails, add MAILTO='' at the top of the crontab manually
|
|
136
|
+
# Sets or clears the crontab!
|
|
137
|
+
# @param cmd [String] the himawari script + all the passed args for it
|
|
138
|
+
# @param action [Symbol] what to do? :set the cron? or :clear the cron?
|
|
139
|
+
# @return nothing useful
|
|
120
140
|
def self.crontab(cmd, action)
|
|
121
141
|
if action == :set
|
|
122
142
|
`(crontab -l ; echo \"#{cmd}\") 2>&1 | grep -v \"no crontab\" | sort | uniq | crontab -`
|
data/lib/himawari/process.rb
CHANGED
|
@@ -10,6 +10,9 @@ module Himawari
|
|
|
10
10
|
module Process
|
|
11
11
|
private
|
|
12
12
|
|
|
13
|
+
# Checks all the tiles downloaded for valid content.
|
|
14
|
+
# Aims to throw out either empty tiles, or the weird "no-image" pngs
|
|
15
|
+
# @return true on success
|
|
13
16
|
def check_tiles
|
|
14
17
|
@control_size ||= File.size("#{app_root}/no_image.png")
|
|
15
18
|
bad_tiles = {}
|
|
@@ -19,11 +22,17 @@ module Himawari
|
|
|
19
22
|
recover_bad_sectors(bad_tiles)
|
|
20
23
|
end
|
|
21
24
|
|
|
25
|
+
# Called from the loop in `check_tiles`. Does the dirty work of actually checking each tile
|
|
26
|
+
# @param bad_tiles [Array <String>] the array that gets supplemented w/ any new tiles
|
|
27
|
+
# @param tile [String] the yet-unknown-to-be-good tile image we just downloaded from the net
|
|
28
|
+
# @return [Array <String>] of bad tile filenames
|
|
29
|
+
# bad_tiles structure:
|
|
30
|
+
# { "t_2019-11-11T0240": [ [ [tile_url_1, tile_url_2, tile_url_3] ], [array_of_tiles], [array_of_tiles] ] }
|
|
22
31
|
def process_bad_tiles(bad_tiles, tile)
|
|
23
32
|
i = File.basename(tile[0..-9])
|
|
24
33
|
ending = tile[-7, 3]
|
|
25
|
-
stamp = Time.parse(i.dup.insert(-3, ':')
|
|
26
|
-
bad_tiles[i] = [] unless bad_tiles
|
|
34
|
+
stamp = Time.parse("#{i.dup.insert(-3, ':')}:00+00:00")
|
|
35
|
+
bad_tiles[i] = [] unless bad_tiles[i]
|
|
27
36
|
bad_tiles[i] << [
|
|
28
37
|
himawari_format(stamp, ending),
|
|
29
38
|
himawari_format(stamp - 600, ending),
|
|
@@ -36,20 +45,32 @@ module Himawari
|
|
|
36
45
|
bad_tiles
|
|
37
46
|
end
|
|
38
47
|
|
|
48
|
+
# @param stamp [DateTime]
|
|
49
|
+
# @param tile_end [String] the tail of the tile's filename. its extension?
|
|
50
|
+
# @return [String] the format of how the images are named on the himawari website
|
|
39
51
|
def himawari_format(stamp, tile_end)
|
|
40
52
|
"#{stamp.year}/#{stamp.month}/#{stamp.day}/#{stamp.hour}#{stamp.min}00_#{tile_end}"
|
|
41
53
|
end
|
|
42
54
|
|
|
55
|
+
# verifies `file` to be an actual png
|
|
56
|
+
# @param file [String]
|
|
57
|
+
# @return true if the file provided is a PNG; false otherwise
|
|
43
58
|
def png?(file)
|
|
44
59
|
File.size(file).positive? && IO.read(file, 4).force_encoding('utf-8') == "\x89PNG"
|
|
45
60
|
end
|
|
46
61
|
|
|
62
|
+
# verifies the `tile` to be a good png and not a "no_image.png"
|
|
63
|
+
# @param tile [String] filename
|
|
64
|
+
# @return true if the tile is ok; false otherwise
|
|
47
65
|
def bad_tile?(tile)
|
|
48
66
|
!png?(tile) || File.size(tile) == @control_size && system("cmp #{tile} #{app_root}/no_image.png")
|
|
49
67
|
end
|
|
50
68
|
|
|
51
|
-
# bad_tiles
|
|
52
|
-
#
|
|
69
|
+
# attempts to recover the tiles in the `bad_tiles` array by downloading them again
|
|
70
|
+
# or downloading a slightly older tile in the same position as the problem tile
|
|
71
|
+
# @param bad_tiles [Array]
|
|
72
|
+
# @return a message to the user of the conditional success of the tiles' recovery
|
|
73
|
+
# usually it deletes the whole image upon recovery failure... :(
|
|
53
74
|
def recover_bad_sectors(bad_tiles)
|
|
54
75
|
bad_tiles.each do |bad_pic_name, sectors|
|
|
55
76
|
pic_not_good = true
|
data/spec/test_helper.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
3
|
require 'minitest/autorun'
|
|
4
|
-
require_relative '../lib/himawari
|
|
4
|
+
require_relative '../lib/himawari'
|
|
5
5
|
|
|
6
6
|
class HimawariTest < Minitest::Test
|
|
7
7
|
# rubocop:disable Style/ClassVars
|
|
@@ -34,6 +34,7 @@ class HimawariTest < Minitest::Test
|
|
|
34
34
|
|
|
35
35
|
def self.cleanup
|
|
36
36
|
puts "Cleanup: Removing #{@@workdir}/data"
|
|
37
|
+
puts `ls -la #{@@workdir}/data`
|
|
37
38
|
`rm -r #{@@workdir}/data*` if File.directory?("#{@@workdir}/data")
|
|
38
39
|
end
|
|
39
40
|
end
|
data/spec/test_net.rb
CHANGED
|
@@ -10,9 +10,10 @@ class TestNet < HimawariTest
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def test_get_pic_blacklisted_wifi
|
|
13
|
-
current_wifi =
|
|
13
|
+
current_wifi = case Himawari::OsUtils.os
|
|
14
|
+
when :mac
|
|
14
15
|
`networksetup -getairportnetwork en0`
|
|
15
|
-
|
|
16
|
+
when :linux
|
|
16
17
|
`iwgetid -r`
|
|
17
18
|
end
|
|
18
19
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: himawari
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- engura
|
|
@@ -80,6 +80,20 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: 13.0.1
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rubocop
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '1.6'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '1.6'
|
|
83
97
|
description: Makes pretty, high-res backgrounds from the real-time photos of Earth
|
|
84
98
|
by Himawari8, or is intended for similar personal usage. Please see the readme for
|
|
85
99
|
more!
|
|
@@ -90,6 +104,7 @@ executables:
|
|
|
90
104
|
extensions: []
|
|
91
105
|
extra_rdoc_files: []
|
|
92
106
|
files:
|
|
107
|
+
- ".circleci/config.yml"
|
|
93
108
|
- ".gitignore"
|
|
94
109
|
- ".rubocop.yml"
|
|
95
110
|
- CHANGELOG.md
|
|
@@ -105,6 +120,7 @@ files:
|
|
|
105
120
|
- lib/himawari/base.rb
|
|
106
121
|
- lib/himawari/download.rb
|
|
107
122
|
- lib/himawari/net_utils.rb
|
|
123
|
+
- lib/himawari/no_image.png
|
|
108
124
|
- lib/himawari/os_utils.rb
|
|
109
125
|
- lib/himawari/process.rb
|
|
110
126
|
- spec/test_base.rb
|
|
@@ -113,7 +129,11 @@ files:
|
|
|
113
129
|
homepage: https://github.com/engura/himawari
|
|
114
130
|
licenses:
|
|
115
131
|
- MIT
|
|
116
|
-
metadata:
|
|
132
|
+
metadata:
|
|
133
|
+
homepage_uri: https://github.com/engura/himawari
|
|
134
|
+
changelog_uri: https://github.com/engura/himawari/blob/master/CHANGELOG.md
|
|
135
|
+
source_code_uri: https://github.com/engura/himawari
|
|
136
|
+
bug_tracker_uri: https://github.com/engura/himawari/issues
|
|
117
137
|
post_install_message: |-
|
|
118
138
|
Thanks for installing! Have fun with the amazing pics of our Home made
|
|
119
139
|
accessible to us for FREE by NICT. And please, don't break their website!!
|