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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24e2776864e4a10f4b535404d68c4d8127591e09c8306adbbddf3af19b768127
4
- data.tar.gz: e1ca4f76fef147be6ec75ab71ddacd907339671bb981c16d9c25387c366d70b5
3
+ metadata.gz: f67123afba6d8051481c5edee8b11cb999d21a930ae8021147e13bbbde018a02
4
+ data.tar.gz: 0f954a19faef8496aef9078c5c6edf6a2526cec9f623eda1ac2f56b4fd315361
5
5
  SHA512:
6
- metadata.gz: 556fc58c1a432621795de4dfded079dfffa163a24624abee86aa45158105abae73caa1741f1c33583141712e83781e54a5a9e738ec7df613d84dc8045cba8e1f
7
- data.tar.gz: 6c0e72388df69ce752e839d9d54eabf011c7a03b2c5f59767e9f7d3e3b3a452877fba2f2818139fda24677d1bfda340e7ff8941ff291ed80954fcea5abb667d4
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/.gitignore CHANGED
@@ -1,2 +1,5 @@
1
1
  **/data/*
2
2
  *.gem
3
+ .yardoc/
4
+ doc/
5
+ !doc/img/
@@ -1,9 +1,11 @@
1
1
  AllCops:
2
+ NewCops: enable
2
3
  DisplayCopNames: true
3
4
  StyleGuideCopsOnly: false
4
5
  TargetRubyVersion: 2.5
5
6
  Exclude:
6
7
  - data/**/*
8
+ - vendor/**/* # needed for CircleCI runtime (gems are installed here)
7
9
 
8
10
  Layout/LineLength:
9
11
  Enabled: true
@@ -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
@@ -1,12 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- himawari (0.1.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
- # TOC
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
- brew install imagemagick # https://github.com/minimagick/minimagick
32
- brew install parallel # https://linux.die.net/man/1/parallel
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
- bundle install
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'himawari'
5
- s.version = '0.1.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)'
@@ -1,28 +1,41 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- require_relative './himawari/base.rb'
4
- require_relative './himawari/os_utils.rb'
5
- require_relative './himawari/net_utils.rb'
6
- require_relative './himawari/process.rb'
7
- require_relative './himawari/download.rb'
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
@@ -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
- UPDATE_RATE = 2 # int; update the pic once every `UPDATE_RATE` minutes
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} :: #{(now.hour * 60 + now.min)} % #{sexy_pics.count} switching to #{sexy_pics[i]}" if verbose
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
- # returns array of pic_names to choose a background from, or false if we do not have enough pictures for a full 24hr rotation
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, ':') + ':00+00:00')
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
@@ -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 = if focus == :top # :full :mid :low
158
+ y = case focus # :full :mid :low
159
+ when :top
134
160
  "{0..#{(resolution / MONITOR_ASPECT).ceil - 1}}"
135
- elsif focus == :low
161
+ when :low
136
162
  "{#{resolution - (resolution / MONITOR_ASPECT).ceil}..#{resolution - 1}}"
137
163
  else # full / mid
138
164
  "{0..#{resolution - 1}}"
@@ -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'] + '+00:00')
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 = if OsUtils.os == :mac
27
+ current_wifi = case OsUtils.os
28
+ when :mac
23
29
  `networksetup -getairportnetwork en0`
24
- elsif OsUtils.os == :linux
30
+ when :linux
25
31
  `iwgetid -r`
26
32
  end
27
33
  puts current_wifi if verbose
Binary file
@@ -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
- if RUBY_PLATFORM =~ /win32/
9
+ case RUBY_PLATFORM
10
+ when /win32/
8
11
  :win
9
- elsif RUBY_PLATFORM =~ /linux/
12
+ when /linux/
10
13
  :linux
11
- elsif RUBY_PLATFORM =~ /darwin/
14
+ when /darwin/
12
15
  :mac
13
- elsif RUBY_PLATFORM =~ /freebsd/
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 -`
@@ -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, ':') + ':00+00:00')
26
- bad_tiles[i] = [] unless bad_tiles.dig(i)
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 structure:
52
- # { "t_2019-11-11T0240": [ [ [tile_url_1, tile_url_2, tile_url_3] ], [array_of_tiles], [array_of_tiles] ] }
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
@@ -1,7 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  require 'minitest/autorun'
4
- require_relative '../lib/himawari.rb'
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
@@ -10,9 +10,10 @@ class TestNet < HimawariTest
10
10
  end
11
11
 
12
12
  def test_get_pic_blacklisted_wifi
13
- current_wifi = if Himawari::OsUtils.os == :mac
13
+ current_wifi = case Himawari::OsUtils.os
14
+ when :mac
14
15
  `networksetup -getairportnetwork en0`
15
- elsif Himawari::OsUtils.os == :linux
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.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!!