telescope-term 2.0 → 2.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.
- checksums.yaml +4 -4
- data/bin/telescope +63 -44
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c74c6c6a0d418a1418cf442f5a67763a20308eee58c24bbbd98377c363ec4373
|
|
4
|
+
data.tar.gz: 59a75595a9ea9db796e7d492e184fd46c37d5114cef29947a2f16d39088be193
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1fd26d33a924c73dbb95798ea53e02fb82579bee93a12caba77e02d17bfd1151fc35b7d8ca47c2687e2374f4439a8bea64b975797dd66215975ec46f98378d8b
|
|
7
|
+
data.tar.gz: a95af60950cce3a01c047dd5597f25703c395b40977e39931adebdc4911c37d0dfb82ecd1e7ca0719e3b7d8ea7d6816818ab1becd25bbe5f09ab8be6c28ed4b9
|
data/bin/telescope
CHANGED
|
@@ -37,7 +37,7 @@ require 'json'
|
|
|
37
37
|
require 'csv'
|
|
38
38
|
|
|
39
39
|
# Version
|
|
40
|
-
VERSION = "2.0"
|
|
40
|
+
VERSION = "2.0.1"
|
|
41
41
|
|
|
42
42
|
# Persistence paths
|
|
43
43
|
SAVE = File.join(Dir.home, '.telescope')
|
|
@@ -159,8 +159,6 @@ def create_backup
|
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
# Load saved data if present
|
|
162
|
-
SAVE = File.join(Dir.home, '.telescope') # Persistence path
|
|
163
|
-
|
|
164
162
|
if File.exist?(SAVE)
|
|
165
163
|
create_backup
|
|
166
164
|
load SAVE # expects plaintext: @ts = [...] and @ep = [...]
|
|
@@ -195,47 +193,49 @@ module Rcurses
|
|
|
195
193
|
end
|
|
196
194
|
|
|
197
195
|
# OPTICAL FORMULAS {{{1
|
|
198
|
-
def tfr(app, tfl); (tfl.to_f / app); end
|
|
199
|
-
def mlim(app); (5 * Math::log(app / 10, 10) + 7.5); end
|
|
200
|
-
def xeye(app); (app.to_f ** 2 / 49);
|
|
201
|
-
def minx(app, tfl); (tfl / (7 *
|
|
202
|
-
def mine(app, tfl); (7 * tfr(app, tfl));
|
|
203
|
-
def maxx(app); (2 * app.to_f);
|
|
204
|
-
def maxe(app, tfl);
|
|
205
|
-
def sepr(app); (3600.0 * Math::asin(671E-6 / app).rad); end
|
|
206
|
-
def sepd(app); (115.824 / app); end
|
|
207
|
-
def e_st(app, tfl); (6.4 * tfl / app); end
|
|
208
|
-
def e_gx(app, tfl); (3.6 * tfl / app); end
|
|
209
|
-
def e_pl(app, tfl); (2.1 * tfl / app); end
|
|
210
|
-
def e_2s(app, tfl); (1.3 * tfl / app); end
|
|
211
|
-
def e_t2(app, tfl); (0.7 * tfl / app); end
|
|
212
|
-
def moon(tfl); (384E6*Math::tan((115.824.deg / tfl)/360)); end
|
|
213
|
-
def sun(tfl); (moon(tfl) / 2.5668);
|
|
214
|
-
def
|
|
215
|
-
def
|
|
216
|
-
def
|
|
196
|
+
def tfr(app, tfl); return 0.0 if app.to_f == 0; (tfl.to_f / app); end
|
|
197
|
+
def mlim(app); return 0.0 if app.to_f <= 0; (5 * Math::log(app / 10, 10) + 7.5); end
|
|
198
|
+
def xeye(app); (app.to_f ** 2 / 49); end
|
|
199
|
+
def minx(app, tfl); r = tfr(app, tfl); return 0.0 if r == 0; (tfl / (7 * r)); end
|
|
200
|
+
def mine(app, tfl); (7 * tfr(app, tfl)); end
|
|
201
|
+
def maxx(app); (2 * app.to_f); end
|
|
202
|
+
def maxe(app, tfl); m = maxx(app); return 0.0 if m == 0; (tfl / m); end
|
|
203
|
+
def sepr(app); return 0.0 if app.to_f == 0; (3600.0 * Math::asin(671E-6 / app).rad); end
|
|
204
|
+
def sepd(app); return 0.0 if app.to_f == 0; (115.824 / app); end
|
|
205
|
+
def e_st(app, tfl); return 0.0 if app.to_f == 0; (6.4 * tfl / app); end
|
|
206
|
+
def e_gx(app, tfl); return 0.0 if app.to_f == 0; (3.6 * tfl / app); end
|
|
207
|
+
def e_pl(app, tfl); return 0.0 if app.to_f == 0; (2.1 * tfl / app); end
|
|
208
|
+
def e_2s(app, tfl); return 0.0 if app.to_f == 0; (1.3 * tfl / app); end
|
|
209
|
+
def e_t2(app, tfl); return 0.0 if app.to_f == 0; (0.7 * tfl / app); end
|
|
210
|
+
def moon(tfl); return 0.0 if tfl.to_f == 0; (384E6*Math::tan((115.824.deg / tfl)/360)); end
|
|
211
|
+
def sun(tfl); (moon(tfl) / 2.5668); end
|
|
212
|
+
def magx(tfl, epfl); return 0.0 if epfl.to_f == 0; (tfl.to_f / epfl); end
|
|
213
|
+
def tfov(tfl, epfl, afov); m = magx(tfl, epfl); return 0.0 if m == 0; (afov.to_f / m); end
|
|
214
|
+
def pupl(app, tfl, epfl); m = magx(tfl, epfl); return 0.0 if m == 0; (app.to_f / m); end
|
|
217
215
|
|
|
218
216
|
# VALIDATION FUNCTIONS {{{1
|
|
217
|
+
# Returns nil on success, or an error message string on failure.
|
|
219
218
|
def validate_telescope_input(input_array)
|
|
220
|
-
return
|
|
221
|
-
|
|
219
|
+
return "Need at least: name, aperture, focal length" unless input_array.size >= 3
|
|
220
|
+
|
|
222
221
|
name, app, fl = input_array[0..2]
|
|
223
|
-
return
|
|
224
|
-
return
|
|
225
|
-
return
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
return "Name cannot be empty" if name.nil? || name.strip.empty?
|
|
223
|
+
return "Aperture must be a positive number" unless app.to_s.strip =~ /\A\d+(\.\d+)?\z/ && app.to_f > 0
|
|
224
|
+
return "Focal length must be a positive number" unless fl.to_s.strip =~ /\A\d+(\.\d+)?\z/ && fl.to_f > 0
|
|
225
|
+
|
|
226
|
+
nil
|
|
228
227
|
end
|
|
229
228
|
|
|
229
|
+
# Returns nil on success, or an error message string on failure.
|
|
230
230
|
def validate_eyepiece_input(input_array)
|
|
231
|
-
return
|
|
232
|
-
|
|
231
|
+
return "Need at least: name, focal length, AFOV" unless input_array.size >= 3
|
|
232
|
+
|
|
233
233
|
name, fl, afov = input_array[0..2]
|
|
234
|
-
return
|
|
235
|
-
return
|
|
236
|
-
return
|
|
237
|
-
|
|
238
|
-
|
|
234
|
+
return "Name cannot be empty" if name.nil? || name.strip.empty?
|
|
235
|
+
return "Focal length must be a positive number" unless fl.to_s.strip =~ /\A\d+(\.\d+)?\z/ && fl.to_f > 0
|
|
236
|
+
return "AFOV must be between 0 and 180 degrees" unless afov.to_s.strip =~ /\A\d+(\.\d+)?\z/ && afov.to_f > 0 && afov.to_f <= 180
|
|
237
|
+
|
|
238
|
+
nil
|
|
239
239
|
end
|
|
240
240
|
|
|
241
241
|
def safe_file_write(file, content)
|
|
@@ -306,6 +306,7 @@ def render_ts #{{{2
|
|
|
306
306
|
end
|
|
307
307
|
|
|
308
308
|
def ep_nice(app, tfl, e) #{{{2
|
|
309
|
+
return '' if app.to_f == 0
|
|
309
310
|
r = (tfl / app)
|
|
310
311
|
out = ''
|
|
311
312
|
# Enhanced color coding with background highlights for optimal ranges - aligned with header
|
|
@@ -356,6 +357,13 @@ def ep_nice(app, tfl, e) #{{{2
|
|
|
356
357
|
end
|
|
357
358
|
|
|
358
359
|
def render_ep #{{{2
|
|
360
|
+
if @ts.empty?
|
|
361
|
+
@pEP.text = "\n Add a telescope first (press 't')"
|
|
362
|
+
@pEP.refresh
|
|
363
|
+
@pEPh.full_refresh
|
|
364
|
+
return
|
|
365
|
+
end
|
|
366
|
+
@pTS.index = [[@pTS.index, 0].max, @ts.size - 1].min
|
|
359
367
|
app = @ts[@pTS.index][1].to_f
|
|
360
368
|
tfl = @ts[@pTS.index][2].to_f
|
|
361
369
|
@pEP.text = "\n"
|
|
@@ -623,8 +631,9 @@ loop do
|
|
|
623
631
|
refresh_all
|
|
624
632
|
when 't'
|
|
625
633
|
inp=@pTSa.ask('name, app, fl [, notes]: ','').split(', ')
|
|
626
|
-
|
|
627
|
-
|
|
634
|
+
err = validate_telescope_input(inp)
|
|
635
|
+
if err
|
|
636
|
+
@pST.say(" #{err} - Press any key")
|
|
628
637
|
getchr
|
|
629
638
|
next
|
|
630
639
|
end
|
|
@@ -635,8 +644,9 @@ loop do
|
|
|
635
644
|
@current = @ts
|
|
636
645
|
when 'e'
|
|
637
646
|
inp=@pEPa.ask('name, fl, afov [, notes]: ','').split(', ')
|
|
638
|
-
|
|
639
|
-
|
|
647
|
+
err = validate_eyepiece_input(inp)
|
|
648
|
+
if err
|
|
649
|
+
@pST.say(" #{err} - Press any key")
|
|
640
650
|
getchr
|
|
641
651
|
next
|
|
642
652
|
end
|
|
@@ -646,25 +656,29 @@ loop do
|
|
|
646
656
|
@ep_unsorted << inp # keep master list updated
|
|
647
657
|
@current = @ep
|
|
648
658
|
when 'ENTER'
|
|
659
|
+
next if @current.empty?
|
|
649
660
|
val = @current[@focus.index].join(', ')
|
|
650
661
|
arr=@pST.ask('Edit: ', val).split(', ')
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
@pST.say("
|
|
662
|
+
err = @current.equal?(@ts) ? validate_telescope_input(arr) : validate_eyepiece_input(arr)
|
|
663
|
+
if err
|
|
664
|
+
@pST.say(" #{err} - Press any key")
|
|
654
665
|
getchr
|
|
655
666
|
next
|
|
656
667
|
end
|
|
657
668
|
arr << '' if arr.size == 3 # Add empty notes if not provided
|
|
658
669
|
@current[@focus.index] = arr
|
|
659
670
|
when 'D'
|
|
671
|
+
next if @current.empty?
|
|
660
672
|
if @current.equal?(@ts)
|
|
661
673
|
removed = @ts.delete_at(@focus.index)
|
|
662
674
|
@ts_unsorted.delete(removed)
|
|
663
675
|
@tstag.delete_at(@focus.index)
|
|
676
|
+
@pTS.index = [[@pTS.index, 0].max, @ts.size - 1].min
|
|
664
677
|
else
|
|
665
678
|
removed = @ep.delete_at(@focus.index)
|
|
666
679
|
@ep_unsorted.delete(removed)
|
|
667
680
|
@eptag.delete_at(@focus.index)
|
|
681
|
+
@pEP.index = [[@pEP.index, 0].max, @ep.size - 1].min
|
|
668
682
|
end
|
|
669
683
|
when 'TAB'
|
|
670
684
|
@focus = (@focus == @pTS ? @pEP : @pTS)
|
|
@@ -675,20 +689,24 @@ loop do
|
|
|
675
689
|
@pTS.border_refresh
|
|
676
690
|
@pEP.border_refresh
|
|
677
691
|
when 'UP'
|
|
692
|
+
next if @current.empty?
|
|
678
693
|
@focus.index -= 1
|
|
679
694
|
@focus.index = @current.length - 1 if @focus.index < 0
|
|
680
695
|
when 'DOWN'
|
|
696
|
+
next if @current.empty?
|
|
681
697
|
@focus.index += 1
|
|
682
698
|
@focus.index = 0 if @focus.index > @current.length - 1
|
|
683
|
-
@focus == :ts ? @cursor_ts = 0 : @cursor_ep = 0
|
|
684
699
|
when 'HOME'
|
|
685
700
|
@focus.index = 0
|
|
686
701
|
when 'END'
|
|
702
|
+
next if @current.empty?
|
|
687
703
|
@focus.index = @current.length - 1
|
|
688
704
|
when 'S-UP'
|
|
705
|
+
next if @current.empty?
|
|
689
706
|
@current.insert([@focus.index - 1, 0].max, @current.delete_at(@focus.index))
|
|
690
707
|
@focus.index -= 1 if @focus.index != 0
|
|
691
708
|
when 'S-DOWN'
|
|
709
|
+
next if @current.empty?
|
|
692
710
|
@current.insert([@focus.index + 1, @current.size - 1].min, @current.delete_at(@focus.index))
|
|
693
711
|
@focus.index += 1 if @focus.index != @current.size - 1
|
|
694
712
|
when 'o' # Toggle-sort the currently focused list
|
|
@@ -712,6 +730,7 @@ loop do
|
|
|
712
730
|
@pEP.index = [@pEP.index, @ep.size - 1].min
|
|
713
731
|
end
|
|
714
732
|
when ' ' # SPACE: tag/untag current entry
|
|
733
|
+
next if @current.empty?
|
|
715
734
|
if @current.equal?(@ts)
|
|
716
735
|
idx = @pTS.index
|
|
717
736
|
@tstag[idx] = !@tstag[idx]
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: telescope-term
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Geir Isene
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-03-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rcurses
|
|
@@ -26,9 +26,9 @@ dependencies:
|
|
|
26
26
|
version: '6.0'
|
|
27
27
|
description: 'With this program you can list your telescopes and eyepieces and get
|
|
28
28
|
a set of calculations done for each scope and for the combination of scope and eyepiece.
|
|
29
|
-
Easy interface. Run the program, then hit ''?'' to show the help file. Version 2.0:
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
Easy interface. Run the program, then hit ''?'' to show the help file. Version 2.0.1:
|
|
30
|
+
Improved input validation with descriptive errors, division-by-zero guards, empty
|
|
31
|
+
list safety.'
|
|
32
32
|
email: g@isene.com
|
|
33
33
|
executables:
|
|
34
34
|
- telescope
|