mooncal 0.0.1

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.
Files changed (6) hide show
  1. checksums.yaml +7 -0
  2. data/bin/moon +24 -0
  3. data/lib/moon.rb +101 -0
  4. data/lib/moon_calc.rb +78 -0
  5. data/lib/moon_date.rb +51 -0
  6. metadata +75 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3a899696eeec601a7712c4bcb1fe60d4e1c0d1d267e7755cff408a365f23547f
4
+ data.tar.gz: 810a2c50960ea370404cd0f95e225aba64e8f61a376432781844c5c5ec8dfdef
5
+ SHA512:
6
+ metadata.gz: 4f1674ac492560531d7652114e0e192adcf7244240971f63b2adca8b729842a5e7237f742bf80876a8cbe7d897983a2e564a7fd11b99860b9e3cc0a821a3d32b
7
+ data.tar.gz: 42f8a6a342ed82802c110de618127931a7942bed2fcf08aa9b9e4908ef540e83be4579d6298e5424d98647f6831b4ab8955939c908d8c86815d94287c0ee25c7
data/bin/moon ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'moon'
5
+
6
+ ### PARSE ARGS ###
7
+
8
+ arg, *other_args = ARGV
9
+
10
+ case arg
11
+ when "today"
12
+ puts MoonTerm.new.moon_day
13
+ when "week"
14
+ puts MoonTerm.new.moon_week
15
+ when "month"
16
+ puts MoonTerm.new.moon_month
17
+ when "-h"
18
+ puts MoonTerm.new.help_text
19
+ when "help"
20
+ puts MoonTerm.new.help_text
21
+ else
22
+ puts MoonTerm.new.moon_month
23
+ end
24
+
data/lib/moon.rb ADDED
@@ -0,0 +1,101 @@
1
+ require 'tty-table'
2
+ require 'pastel'
3
+ require_relative 'moon_date'
4
+
5
+ $pastel = Pastel.new
6
+
7
+ ### MAIN ###
8
+
9
+ class MoonTerm
10
+ attr_reader :date
11
+
12
+ ### CONSTANTS ###
13
+ TERM_HEIGHT, TERM_WIDTH = TTY::Screen.size
14
+
15
+ DAY_NAMES = [
16
+ "Monday",
17
+ "Tuesday",
18
+ "Wednesday",
19
+ "Thursday",
20
+ "Friday",
21
+ "Saturday",
22
+ "Sunday"
23
+ ]
24
+
25
+ MOONS = {
26
+ new: ["\u{1F311}", "New Moon", "New"],
27
+ waxing_crescent: ["\u{1F312}", "Waxing Crescent", "WxC"],
28
+ first_quarter: ["\u{1F313}", "First Quarter", "FQ"],
29
+ waxing_gibbous: ["\u{1F314}", "Waxing Gibbous", "WxG"],
30
+ full: ["\u{1F315}", "Full Moon", "Full"],
31
+ waning_gibbous: ["\u{1F316}", "Waning Gibbous", "WnG"],
32
+ last_quarter: ["\u{1F317}", "Last Quarter", "LQ"],
33
+ waning_crescent: ["\u{1F318}", "Waning Crescent", "WnC"]
34
+ }
35
+
36
+ def initialize(date=MoonDate.today)
37
+ @date = date
38
+ end
39
+
40
+ def moon_day
41
+ header_string = "\n" + center_string("The Moon today (#{@date.strftime("%a, %b %e")}):") + "\n\n"
42
+ phase_string = center_string($pastel.bold(MOONS[@date.moon_phase][1])) + "\n"
43
+ moon_icon = center_string(MOONS[@date.moon_phase][0]) + "\n"
44
+
45
+ header_string + phase_string + moon_icon
46
+ end
47
+
48
+ def moon_week
49
+ table = TTY::Table.new(DAY_NAMES, [])
50
+ title = "\n" + center_string($pastel.bold("Moon Phases for the #{number_ord(@date.current_week)} week of #{@date.strftime("%B")}")) + "\n\n"
51
+
52
+ table << @date.month_days(true).each_slice(7).to_a[@date.current_week - 1].map do |day|
53
+ if day == @date then $pastel.bold(day.strftime("%b %e"))
54
+ elsif !day.nil? then day.strftime("%b %e")
55
+ else nil
56
+ end
57
+ end
58
+ table << @date.week_days(true).map { |day| day.nil? ? day : MOONS[day.moon_phase][0] }
59
+
60
+ title + center_table(table.render(multiline: true, alignment: [:center], padding: [0, 2, 0, 2])) + "\n"
61
+ end
62
+
63
+ def moon_month
64
+ table = TTY::Table.new(DAY_NAMES, [])
65
+ days = @date.month_days(true).map do |day|
66
+ day.nil? ? day : (day == @date) ? "#{$pastel.bold(day.strftime("%d"))}\n#{MOONS[day.moon_phase][0]}" : "#{day.strftime("%d")}\n#{MOONS[day.moon_phase][0]}"
67
+ end
68
+ weeks = days.each_slice(7).to_a
69
+
70
+ weeks.each { |week| table << week }
71
+
72
+ "\n" + center_string($pastel.bold("Moon Phases for #{@date.strftime("%B %Y")}")) + "\n\n" +
73
+ center_table(table.render(multiline: true, alignment: [:center], padding:[0, 1, 0, 1])) + "\n"
74
+ end
75
+
76
+ def help_text
77
+ "\nUsage: moon [today | week | month | help | -h]"
78
+ end
79
+
80
+ private
81
+
82
+ def number_ord(num)
83
+ case num
84
+ when 1 then num.to_s + "st"
85
+ when 2 then num.to_s + "nd"
86
+ when 3 then num.to_s + "rd"
87
+ else num.to_s + "th"
88
+ end
89
+ end
90
+
91
+ def center_string(str, width=TERM_WIDTH)
92
+ padding = ((width - $pastel.strip(str).length) / 2).floor
93
+ str.strip.prepend(" " * padding)
94
+ end
95
+
96
+ def center_table(rendered_table)
97
+ table_rows = rendered_table.split("\n")
98
+ padding = ((TERM_WIDTH - table_rows[1].length) / 2).floor
99
+ table_rows.map { |row| row.prepend(" " * padding) }.join("\n")
100
+ end
101
+ end
data/lib/moon_calc.rb ADDED
@@ -0,0 +1,78 @@
1
+ # Lunar/Moon phases ruby class
2
+ #
3
+ # Code is based upon Bradley E. Schaefer''s moon phase algorithm.
4
+ # Ruby version based on JavaScript Phase Calculator by Stephen R. Schmitt
5
+ class MoonCalc
6
+ attr_reader :epoch, :phase, :days, :icon, :dist, :ll
7
+
8
+ # Return the current (or input a date) moon.
9
+ # Moon.new
10
+ # Moon.new(some_day)
11
+ #
12
+ # Methods available:
13
+ # phase => Phase of the moon as a sym
14
+ # days => Moon days
15
+ # icon => An integer from 0 to 29
16
+ # dist => Distance in earth radii
17
+ # ll => Moon ecliptic lat/lon
18
+ #
19
+ def initialize(epoch=Time.now)
20
+ @epoch = epoch
21
+ do_calc
22
+ end
23
+
24
+ private
25
+
26
+ def calc_phase(p)
27
+ case p
28
+ when 0 then :new
29
+ when 1..6 then :waxing_crescent
30
+ when 7..9 then :first_quarter
31
+ when 10..12 then :waxing_gibbous
32
+ when 13..16 then :full
33
+ when 17..20 then :waning_gibbous
34
+ when 21..24 then :last_quarter
35
+ when 25..28 then :waning_crescent
36
+ else :new
37
+ end
38
+ end
39
+
40
+ def calc_coords(inter, phase)
41
+ phase = phase * 2 * Math::PI
42
+ dp = 2 * Math::PI * normalize((inter - 2451562.2 ) / 27.55454988)
43
+ @dist = 60.4 - 3.3 * Math.cos(dp) - 0.6 * Math.cos(2 * phase - dp) - 0.5 * Math.cos(2 * phase)
44
+
45
+ np = 2 * Math::PI * normalize((inter - 2451565.2) / 27.212220817)
46
+ la = 5.1 * Math.sin(np)
47
+
48
+ rp = normalize((inter - 2451555.8 ) / 27.321582241)
49
+ lo = 360 * rp + 6.3 * Math.sin(dp) + 1.3 * Math.sin(2 * phase - dp) + 0.7 * Math.sin(2 * phase)
50
+ @ll = [la, lo]
51
+ end
52
+
53
+ def do_calc
54
+ c_phase = 29.530588853
55
+ t_year = @epoch.year - ((12 - @epoch.month)/10).to_i
56
+ t_month = (@epoch.month + 9) % 12
57
+
58
+ t1 = (365.25 * (t_year + 4712)).to_i
59
+ t2 = (30.6 * t_month + 0.5).to_i
60
+ t3 = (((t_year / 100.0) + 49.0) * 0.75).to_i - 38
61
+ inter = t1 + t2 + @epoch.day + 59
62
+ inter -= t3 if inter > 2299160
63
+ phase = normalize((inter - 2451550.1) / c_phase)
64
+ res = phase * c_phase;
65
+
66
+ @days = (res * 100).to_i / 100
67
+ @icon = res.to_i % 30
68
+ @phase = calc_phase(@icon)
69
+ calc_coords(inter, phase)
70
+ end
71
+
72
+ def normalize(x)
73
+ x %= 1
74
+ x += 1 if x < 0
75
+ x
76
+ end
77
+
78
+ end
data/lib/moon_date.rb ADDED
@@ -0,0 +1,51 @@
1
+ require 'date'
2
+ require_relative 'moon_calc'
3
+
4
+ class MoonDate < Date
5
+ DAY_NAME = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
6
+ MONTH_NAME = ["January", "February", "March", "April", "May", "June",
7
+ "July", "August", "September", "October", "November", "December"]
8
+
9
+ def week_days(padded=false)
10
+ week_days = month_days.filter { |day| day.cweek == self.cweek }
11
+ padded ? pad_days(week_days) : week_days
12
+ end
13
+
14
+ def current_week
15
+ naive_cweek(self) - naive_cweek(MoonDate.new(self.year, self.month, 1)) + 1
16
+ end
17
+
18
+ def day_name
19
+ DAY_NAME[self.cwday - 1]
20
+ end
21
+
22
+ def month_name
23
+ MONTH_NAME[self.month - 1]
24
+ end
25
+
26
+ def month_days(padded=false)
27
+ days = (0..31).filter { |day| Date.valid_date?(self.year, self.month, day) }.map do |day|
28
+ MoonDate.new(self.year, self.month, day)
29
+ end
30
+
31
+ padded ? pad_days(days) : days
32
+ end
33
+
34
+ def moon_phase
35
+ MoonCalc.new(self).phase
36
+ end
37
+
38
+ private
39
+
40
+ def pad_days(days)
41
+ front_padding = days.first.cwday - 1
42
+ end_padding = 7 - days.last.cwday
43
+
44
+ Array.new(front_padding, nil) + days + Array.new(end_padding, nil)
45
+ end
46
+
47
+ def naive_cweek(date)
48
+ date.month == 1 && date.cweek == 53 ? 1 : date.month_days.first.cweek == 53 ? date.cweek + 1 : date.cweek
49
+ end
50
+ end
51
+
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mooncal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nikolai Kozak
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-09-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tty-table
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.12'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pastel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.8'
41
+ description: Print a moon phase calendar to your terminal!
42
+ email: nikokozak@gmail.com
43
+ executables:
44
+ - moon
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - bin/moon
49
+ - lib/moon.rb
50
+ - lib/moon_calc.rb
51
+ - lib/moon_date.rb
52
+ homepage:
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubygems_version: 3.2.15
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: Moon Phases!
75
+ test_files: []