tlapse 0.7.0 → 0.8.0
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/.gitignore +1 -0
- data/README.md +37 -5
- data/lib/tlapse/cli/cli.rb +4 -0
- data/lib/tlapse/cli/config.rb +67 -0
- data/lib/tlapse/config.rb +136 -0
- data/lib/tlapse/errors.rb +4 -0
- data/lib/tlapse/solar_event.rb +9 -9
- data/lib/tlapse/version.rb +1 -1
- data/tlapse.gemspec +1 -0
- metadata +20 -4
- data/:w +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f9ba7284d147763881cdb94e11e8bb77369be4eb1c43ec1b290382700f0a004
|
4
|
+
data.tar.gz: 3ba78dd8eec0d82fbae34003c6dd525ca3e6df4ebbc0ea1e70dc2eaea97da50e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb467169d60beaa2e9f5b3a8bfa88cb0264873ead65fe3254ea19e1780ebd75b48cb095270338e72142c4b0934ecb60b7fcc2b73ec6a38fe72ab471a809f17ea
|
7
|
+
data.tar.gz: edea957cce99cbc196fef32eb3766be708bc8b58d37b4f1269daa4f3104deed929eb56f33be2b98b9a961d12ec8a9c2a03a54a8239ce3e207a795b62bfcc7f76
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -4,19 +4,27 @@ Automated time lapse photography using gphoto2.
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
1. Install gphoto2
|
7
|
+
1. Install gphoto2 and ffmpeg
|
8
8
|
|
9
|
-
* macOS: `brew install gphoto2`
|
10
|
-
* Debian/Ubuntu: `sudo apt install gphoto2`
|
9
|
+
* macOS: `brew install gphoto2 ffmpeg`
|
10
|
+
* Debian/Ubuntu: `sudo apt install gphoto2 ffmpeg`
|
11
11
|
|
12
12
|
2. `gem install tlapse`
|
13
13
|
|
14
14
|
## Example: Integrate with cron
|
15
15
|
|
16
|
-
* From 9 AM to
|
16
|
+
* From 9 AM to 1 PM, capture one image every 10 minutes
|
17
17
|
|
18
18
|
```
|
19
|
-
0 9 * * * cd $HOME &&
|
19
|
+
0 9 * * * cd $HOME && tlapse alpha capture --until 1pm --interval 10
|
20
|
+
```
|
21
|
+
|
22
|
+
* From 3 PM to sunset, capture an image every minute. Compile the result into a video.
|
23
|
+
* You should [configure](#configuration) your coordinates to accurately
|
24
|
+
determine sunset in your location
|
25
|
+
|
26
|
+
```
|
27
|
+
0 15 * * * cd $HOME && tlapse alpha capture --until sunset --interval 10 --compile
|
20
28
|
```
|
21
29
|
|
22
30
|
## CLI
|
@@ -25,6 +33,14 @@ Find better documentation by running `tlapse help` or `tlapse help SUBCOMMAND`
|
|
25
33
|
|
26
34
|
* `tlapse capture_single` - Capture an image using the tethered camera
|
27
35
|
* `tlapse until_sunset` - Generate a gphoto2 command which captures images until sunset
|
36
|
+
* You should [configure](#configuration) your coordinates to accurately
|
37
|
+
determine sunset in your location
|
38
|
+
|
39
|
+
#### Alpha CLI
|
40
|
+
|
41
|
+
These are early-stage features which are likely to change quite a bit before they're ready for prime time.
|
42
|
+
|
43
|
+
* `tlapse alpha capture` - Capture a series of timelapse images (see `tlapse alpha capture --help` for options)
|
28
44
|
|
29
45
|
## API
|
30
46
|
|
@@ -45,6 +61,22 @@ Mostly useful for cronjobs and the like.
|
|
45
61
|
# => "gphoto2 --capture-image-and-download -I 1800 -F 11 --filename '%Y-%m-%d_%H-%M-%S.jpg'"
|
46
62
|
```
|
47
63
|
|
64
|
+
## Configuration <a name="configuration"/>
|
65
|
+
|
66
|
+
So sunrise and sunset calculations are correct for your location, it is
|
67
|
+
advisable to configure your (approximate) coordintes using the CLI. Defaults are
|
68
|
+
for Raleigh, NC, which is probably not where you live.
|
69
|
+
|
70
|
+
You can get rough coordinates from https://www.iplocation.net/
|
71
|
+
|
72
|
+
```
|
73
|
+
tlapse config set lat YOUR_LATITUDE
|
74
|
+
tlapse config set lon YOUR_LONGITUDE
|
75
|
+
|
76
|
+
# Optionally also configure your timezone to make date formatting nicer
|
77
|
+
tlapze config set tz YOUR_TIMEZONE (e.g. America/New_York)
|
78
|
+
```
|
79
|
+
|
48
80
|
## License
|
49
81
|
|
50
82
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/tlapse/cli/cli.rb
CHANGED
@@ -2,6 +2,7 @@ require "thor"
|
|
2
2
|
require "active_support/core_ext/numeric/time.rb"
|
3
3
|
require "tlapse"
|
4
4
|
require "tlapse/cli/alpha"
|
5
|
+
require "tlapse/cli/config"
|
5
6
|
|
6
7
|
module Tlapse::CLI
|
7
8
|
class CLI < Thor
|
@@ -31,6 +32,9 @@ module Tlapse::CLI
|
|
31
32
|
puts Tlapse::Capture.timelapse_command_while_sun_is_up(interval: interval)
|
32
33
|
end
|
33
34
|
|
35
|
+
desc "config", "Read and write config options"
|
36
|
+
subcommand "config", Tlapse::CLI::Config
|
37
|
+
|
34
38
|
desc "alpha", "Get early access to in-development (and likely unstable) commands"
|
35
39
|
subcommand "alpha", Tlapse::CLI::Alpha
|
36
40
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "tlapse/config"
|
3
|
+
|
4
|
+
module Tlapse::CLI
|
5
|
+
class Config < Thor
|
6
|
+
desc "list", "List available configuration options"
|
7
|
+
def list
|
8
|
+
config = Tlapse::Config.list.dup
|
9
|
+
opts = config.keys
|
10
|
+
|
11
|
+
values = Tlapse::Config.get *opts
|
12
|
+
|
13
|
+
config = config.transform_values.with_index do |original, index|
|
14
|
+
default = original[:default]
|
15
|
+
default = default.call if default.respond_to? :call
|
16
|
+
original[:default] = default
|
17
|
+
|
18
|
+
original[:value] = values[index].to_s
|
19
|
+
|
20
|
+
original
|
21
|
+
end
|
22
|
+
|
23
|
+
# Make a simple table.
|
24
|
+
max_name = opts.max_by(&:length).length
|
25
|
+
max_desc = opts.max_by { |opt| config[opt][:desc].length }
|
26
|
+
max_desc = config[max_desc][:desc].length
|
27
|
+
max_value = opts.max_by { |opt| config[opt][:value].length }
|
28
|
+
max_value = config[max_value][:value].length
|
29
|
+
|
30
|
+
config.each_pair do |option, meta|
|
31
|
+
desc, default = meta.values_at :desc, :default
|
32
|
+
name_padded = option.ljust(max_name, " ")
|
33
|
+
desc_padded = meta[:desc].ljust(max_desc, " ")
|
34
|
+
#value_padded = meta[:value].ljust(max_value, " ")
|
35
|
+
value_padded = meta[:value]
|
36
|
+
|
37
|
+
puts "#{name_padded} -> #{desc_padded} -> #{value_padded} (default: #{default})"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "get OPTION", "Get the value for the given config option"
|
42
|
+
def get(*options)
|
43
|
+
puts Tlapse::Config.get *options
|
44
|
+
rescue Tlapse::NoSuchConfigOption
|
45
|
+
Tlapse::Logger.error! "The config option \"#{option}\" does not exist. " \
|
46
|
+
"Run tlapse config list for a full list of available options"
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "set OPTION VALUE", "Set the given config option to the given value"
|
50
|
+
def set(option, value)
|
51
|
+
Tlapse::Config.set option, value
|
52
|
+
rescue Tlapse::NoSuchConfigOption
|
53
|
+
Tlapse::Logger.error! "The config option \"#{option}\" does not exist. " \
|
54
|
+
"Run tlapse config list for a full list of available options"
|
55
|
+
rescue Tlapse::ConfigOptionInvalid => invalid
|
56
|
+
Tlapse::Logger.error! invalid.message
|
57
|
+
end
|
58
|
+
|
59
|
+
desc "unset OPTION", "Restore the given option to its default state"
|
60
|
+
def unset(option)
|
61
|
+
Tlapse::Config.unset option
|
62
|
+
rescue Tlapse::NoSuchConfigOption
|
63
|
+
Tlapse::Logger.error! "The config option \"#{option}\" does not exist. " \
|
64
|
+
"Run tlapse config list for a full list of available options"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "fileutils"
|
3
|
+
require "tlapse/errors"
|
4
|
+
require "active_support/time_with_zone"
|
5
|
+
|
6
|
+
module Tlapse
|
7
|
+
class Config
|
8
|
+
Validation = Struct.new :method, :error
|
9
|
+
|
10
|
+
CONFIG_OPTIONS = {
|
11
|
+
"lat" => {
|
12
|
+
default: 35.779590,
|
13
|
+
desc: "Your current latitude",
|
14
|
+
type: :float
|
15
|
+
},
|
16
|
+
"lon" => {
|
17
|
+
default: -78.638179,
|
18
|
+
desc: "Your current longitude",
|
19
|
+
type: :float
|
20
|
+
},
|
21
|
+
"tz" => {
|
22
|
+
default: -> { Tlapse::Config.current_tz },
|
23
|
+
desc: "Your current timezone",
|
24
|
+
type: :string,
|
25
|
+
validations: [
|
26
|
+
Validation.new(
|
27
|
+
->(tz) { TZInfo::Timezone.get(tz) },
|
28
|
+
->(tz) do
|
29
|
+
zones = ActiveSupport::TimeZone.all.map do |tz|
|
30
|
+
tz.tzinfo.name
|
31
|
+
end.uniq.sort.join("\n")
|
32
|
+
|
33
|
+
"#{tz} is not a valid timezone. Valid zones are:\n\n#{zones}"
|
34
|
+
end
|
35
|
+
)
|
36
|
+
]
|
37
|
+
}
|
38
|
+
}.freeze
|
39
|
+
|
40
|
+
CONFIG_KEYS = CONFIG_OPTIONS.keys.freeze
|
41
|
+
|
42
|
+
CONFIG_PATH = File.expand_path ".config/tlapse/tlapse.yaml", Dir.home
|
43
|
+
|
44
|
+
CONFIG_UNDEFINED = :undefined
|
45
|
+
|
46
|
+
def self.list
|
47
|
+
CONFIG_OPTIONS
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.get(*options)
|
51
|
+
values = Array(options).map do |option|
|
52
|
+
verify_option_exists! option
|
53
|
+
|
54
|
+
value = value_for option
|
55
|
+
value == CONFIG_UNDEFINED ? default_for(option) : value
|
56
|
+
end
|
57
|
+
|
58
|
+
values.length == 1 ? values.first : values
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.set(option, value)
|
62
|
+
verify_option_exists! option
|
63
|
+
validate! option, value
|
64
|
+
|
65
|
+
values = user_values
|
66
|
+
|
67
|
+
if value == default_for(option)
|
68
|
+
values.delete option
|
69
|
+
else
|
70
|
+
values[option] = value
|
71
|
+
end
|
72
|
+
|
73
|
+
save values
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.unset(option)
|
77
|
+
set option, default_for(option)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def self.current_tz
|
83
|
+
utc_offset = Time.now.utc_offset
|
84
|
+
tz = ActiveSupport::TimeZone.all.find { |tz| tz.utc_offset == utc_offset }
|
85
|
+
tz&.tzinfo&.name || "America/New_York"
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.cast(option, value)
|
89
|
+
case type_for(option)
|
90
|
+
when :integer then value.to_i
|
91
|
+
when :float then value.to_f
|
92
|
+
when :string then value.to_s
|
93
|
+
else value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.verify_option_exists!(option)
|
98
|
+
raise Tlapse::NoSuchConfigOption unless CONFIG_KEYS.include? option
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.value_for(option)
|
102
|
+
value = user_values[option]
|
103
|
+
value ? cast(option, value) : CONFIG_UNDEFINED
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.default_for(option)
|
107
|
+
default = CONFIG_OPTIONS.dig option, :default
|
108
|
+
default = default.call if default.respond_to? :call
|
109
|
+
cast option, default
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.type_for(option)
|
113
|
+
CONFIG_OPTIONS.dig option, :type
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.user_values
|
117
|
+
File.exists?(CONFIG_PATH) ? YAML.load_file(CONFIG_PATH) : {}
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.save(user_values)
|
121
|
+
FileUtils.mkdir_p File.dirname CONFIG_PATH
|
122
|
+
File.write CONFIG_PATH, user_values.to_yaml
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.validate!(option, value)
|
126
|
+
Array(CONFIG_OPTIONS.dig(option, :validations)).each do |validation|
|
127
|
+
begin
|
128
|
+
validation.method.call value
|
129
|
+
rescue
|
130
|
+
message = validation.error.call value
|
131
|
+
raise ConfigOptionInvalid, message
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/lib/tlapse/solar_event.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
require "solareventcalculator"
|
2
|
+
require "tlapse/config"
|
2
3
|
|
3
4
|
module Tlapse
|
4
5
|
module SolarEvent
|
5
|
-
LAT = 35.779590
|
6
|
-
LON = -78.638179
|
7
|
-
TZ = "America/New_York"
|
8
|
-
|
9
6
|
def self.sunrise
|
10
|
-
|
11
|
-
|
7
|
+
tz = Tlapse::Config.get "tz"
|
8
|
+
s = solar_event.compute_official_sunrise(tz)
|
9
|
+
n = Time.new
|
12
10
|
Time.new(n.year, n.month, n.day, s.hour, s.minute)
|
13
11
|
end
|
14
12
|
|
15
13
|
def self.sunset
|
16
|
-
|
17
|
-
|
14
|
+
tz = Tlapse::Config.get "tz"
|
15
|
+
s = solar_event.compute_official_sunset(tz)
|
16
|
+
n = Time.new
|
18
17
|
Time.new(n.year, n.month, n.day, s.hour, s.minute)
|
19
18
|
end
|
20
19
|
|
21
20
|
def self.solar_event
|
22
21
|
date = Date.new
|
23
|
-
|
22
|
+
lat, lon = Tlapse::Config.get "lat", "lon"
|
23
|
+
SolarEventCalculator.new date, lat, lon
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/tlapse/version.rb
CHANGED
data/tlapse.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.0"
|
24
24
|
spec.add_development_dependency "byebug", "~> 8.2"
|
25
25
|
spec.add_development_dependency "timecop", "~> 0.8"
|
26
|
+
spec.add_development_dependency "simplecov", "~> 0.15"
|
26
27
|
|
27
28
|
spec.add_dependency "activesupport", "~> 5"
|
28
29
|
spec.add_dependency "RubySunrise", "~> 0.3"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tlapse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Toniazzo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.8'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.15'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.15'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: activesupport
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -149,7 +163,6 @@ files:
|
|
149
163
|
- ".rspec"
|
150
164
|
- ".ruby-version"
|
151
165
|
- ".travis.yml"
|
152
|
-
- ":w"
|
153
166
|
- Gemfile
|
154
167
|
- LICENSE.txt
|
155
168
|
- README.md
|
@@ -161,7 +174,10 @@ files:
|
|
161
174
|
- lib/tlapse/capture.rb
|
162
175
|
- lib/tlapse/cli/alpha.rb
|
163
176
|
- lib/tlapse/cli/cli.rb
|
177
|
+
- lib/tlapse/cli/config.rb
|
178
|
+
- lib/tlapse/config.rb
|
164
179
|
- lib/tlapse/doctor.rb
|
180
|
+
- lib/tlapse/errors.rb
|
165
181
|
- lib/tlapse/logger.rb
|
166
182
|
- lib/tlapse/server.rb
|
167
183
|
- lib/tlapse/solar_event.rb
|
@@ -189,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
205
|
version: '0'
|
190
206
|
requirements: []
|
191
207
|
rubyforge_project:
|
192
|
-
rubygems_version: 2.7.
|
208
|
+
rubygems_version: 2.7.4
|
193
209
|
signing_key:
|
194
210
|
specification_version: 4
|
195
211
|
summary: Automated time lapse photography via gphoto2
|