himawari 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![tech-debt](https://img.shields.io/codeclimate/tech-debt/engura/himawari)
|
4
|
+
[![maintainability](https://img.shields.io/codeclimate/maintainability-percentage/engura/himawari)](https://codeclimate.com/github/engura/himawari)
|
5
|
+
[![Inline docs](https://inch-ci.org/github/engura/himawari.svg?branch=main)](https://inch-ci.org/github/engura/himawari)
|
6
|
+
[![build](https://img.shields.io/circleci/build/github/engura/himawari)](https://app.circleci.com/pipelines/github/engura/himawari)
|
7
|
+
|
8
|
+
[![gem_version](https://img.shields.io/gem/v/himawari)](https://rubygems.org/gems/himawari)
|
9
|
+
[![gem_dl](https://img.shields.io/gem/dt/himawari)](https://rubygems.org/gems/himawari)
|
10
|
+
![lines](https://img.shields.io/tokei/lines/github/engura/himawari)
|
11
|
+
![size](https://img.shields.io/github/languages/code-size/engura/himawari)
|
12
|
+
[![license](https://img.shields.io/github/license/engura/himawari)](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
|
![full globe](doc/img/h_2020-06-01T0100.png)
|
13
28
|
![high res section](doc/img/h_2020-11-29T0110.png)
|
@@ -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!!
|