sensible-cinema 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +4 -0
- data/LICENSE.TXT +70 -0
- data/README +95 -29
- data/TODO +85 -71
- data/USAGE_TERMS.TXT +15 -0
- data/VERSION +1 -1
- data/bin/sensible-cinema +90 -32
- data/bin/sensible-cinema-cli +17 -0
- data/edit sensible cinema decision list files.bat b/data/create new sensible cinema decision list → files.bat +0 -0
- data/ext/mkrf_conf.rb +17 -0
- data/how_to_create +1 -0
- data/lib/add_any_bundled_gems_to_load_path.rb +17 -0
- data/lib/blanker.rb +17 -0
- data/lib/drive_info.rb +17 -0
- data/lib/edl_parser.rb +17 -0
- data/lib/fake_blanker.rb +17 -0
- data/lib/file_chooser.rb +17 -0
- data/lib/keyboard_input.rb +17 -0
- data/lib/mencoder_wrapper.rb +32 -33
- data/lib/mouse.rb +17 -0
- data/lib/mouse_forever.rb +17 -0
- data/lib/mplayer_edl.rb +31 -0
- data/lib/muter.rb +17 -0
- data/lib/ocr.rb +17 -0
- data/lib/overlayer.rb +17 -0
- data/lib/screen_tracker.rb +18 -1
- data/lib/storage.rb +99 -82
- data/lib/swing_helpers.rb +17 -0
- data/lib/vlc_programmer.rb +17 -0
- data/preamble +17 -0
- data/sensible-cinema.gemspec +12 -5
- data/spec/blanker.spec.rb +17 -0
- data/spec/common.rb +17 -0
- data/spec/convert_image.rb +17 -0
- data/spec/drive_info.spec.rb +17 -0
- data/spec/edl_parser.spec.rb +17 -0
- data/spec/keyboard_input.spec.rb +17 -0
- data/spec/mencoder_wrapper.spec.rb +61 -21
- data/spec/mouse.spec.rb +17 -0
- data/spec/mplayer_edl.spec.rb +33 -0
- data/spec/muter.spec.rb +17 -0
- data/spec/ocr.spec.rb +17 -0
- data/spec/overlayer.spec.rb +17 -0
- data/spec/screen_tracker.spec.rb +17 -0
- data/spec/sensible_cinema_gui.spec.rb +38 -16
- data/spec/swing_helpers.spec.rb +17 -0
- data/spec/vlc_programmer.spec.rb +17 -0
- data/zamples/edit_decision_lists/dvds/COOL_RUNNINGS.txt +23 -1
- data/zamples/edit_decision_lists/dvds/Harry Potter 2.txt +18 -0
- data/zamples/edit_decision_lists/dvds/pack_wedding_2007-03-03.txt +24 -0
- data/zamples/edit_decision_lists/example_edit_decision_list.txt +1 -1
- metadata +13 -6
- data/LICENSE +0 -56
data/lib/mencoder_wrapper.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
1
18
|
if $0 == __FILE__
|
2
19
|
require 'rubygems'
|
3
20
|
require 'sane'
|
@@ -9,19 +26,21 @@ class MencoderWrapper
|
|
9
26
|
|
10
27
|
class << self
|
11
28
|
|
12
|
-
def get_header this_drive
|
29
|
+
def get_header this_drive, these_settings
|
13
30
|
out = ''
|
14
31
|
if File.exist?(@big_temp) && File.exist?(@big_temp + '.done')
|
15
32
|
out = '@rem '
|
16
33
|
end
|
34
|
+
# video_opts = "-ovc lavc -lavcopts keyint=1" # seems reasonable quality somehow...
|
17
35
|
# equivalent of ffmpeg's -target ntsc-dvd...I think...except that aspect thing terrifies me...
|
18
|
-
|
19
|
-
|
20
|
-
out + "call mencoder dvdnav://#{@dvd_title_track} -sid 1000 -oac
|
36
|
+
audio_codec = these_settings['audio_codec'] || 'copy'
|
37
|
+
video_opts = "-ovc lavc -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=1:vstrict=0:acodec=ac3:abitrate=192:autoaspect -ofps 30000/1001"
|
38
|
+
out + "call mencoder dvdnav://#{@dvd_title_track} -of mpeg -mpegopts format=dvd:tsaf -alang en -nocache -sid 1000 -oac #{audio_codec} #{video_opts} -ovc lavc -o #{@big_temp} -dvd-device #{this_drive} && echo got_file > #{@big_temp}.done\n"
|
21
39
|
end
|
22
40
|
|
23
|
-
|
24
|
-
|
41
|
+
# called from the UI...
|
42
|
+
def get_bat_commands these_settings, this_drive, to_here_final_file, start_here = nil, end_here = nil, dvd_title_track = "1", delete_partials = false
|
43
|
+
combined = VLCProgrammer.convert_incoming_to_split_sectors these_settings
|
25
44
|
@dvd_title_track = dvd_title_track
|
26
45
|
if start_here || end_here
|
27
46
|
raise 'need both' unless end_here && start_here
|
@@ -33,8 +52,8 @@ class MencoderWrapper
|
|
33
52
|
else
|
34
53
|
previous_end = 0
|
35
54
|
end
|
36
|
-
@big_temp = to_here_final_file + ".
|
37
|
-
out = get_header this_drive
|
55
|
+
@big_temp = to_here_final_file + ".fulli_unedited.tmp.mpg"
|
56
|
+
out = get_header this_drive, these_settings
|
38
57
|
@idx = 0
|
39
58
|
combined.each {|start, endy, type|
|
40
59
|
if start > previous_end
|
@@ -54,15 +73,15 @@ class MencoderWrapper
|
|
54
73
|
if File.exist? to_here_final_file
|
55
74
|
FileUtils.rm to_here_final_file # raises on failure...which is what we want I think
|
56
75
|
end
|
57
|
-
# ridiculous
|
58
76
|
out += "call mencoder #{partials.join(' ')} -o #{to_here_final_file} -ovc copy -oac copy\n"
|
59
77
|
# LODO only do this if they want to watch it on their computer, with something other than smplayer, or want to make it smaller, as it takes *forever* longer
|
60
|
-
# LODO the "insta play" mode, or the "faster rip" mode (related...)
|
61
78
|
out += "@rem call mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf -vf scale=720:480,harddup -srate 48000 -af lavcresample=48000 -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=16/9 -ofps 30000/1001 #{partials.join(' ')} -o #{to_here_final_file}\n"
|
79
|
+
|
80
|
+
delete_prefix = delete_partials ? "" : "@rem "
|
62
81
|
|
63
82
|
out += "@rem del #{@big_temp}\n" # LODO no @rem
|
64
|
-
out += "
|
65
|
-
out += "echo wrote to #{to_here_final_file}"
|
83
|
+
out += "#{delete_prefix} del " + partials.join(' ') + "\n"
|
84
|
+
out += "echo wrote (probably successfully) to #{to_here_final_file}"
|
66
85
|
out
|
67
86
|
end
|
68
87
|
|
@@ -73,33 +92,13 @@ class MencoderWrapper
|
|
73
92
|
# very decreased volume is like muting :)
|
74
93
|
# LODO can we copy more here? ntsc-dvd supposedly remuxes...
|
75
94
|
codecs = should_mute ? "-vcodec copy -acodec ac3 -vol 0 " : "-vcodec copy -acodec copy " # LODO the ac3 must match the copy...hmm...
|
76
|
-
# ffmpeg -i from_here.avi -vcodec copy -acodec copy -ss 1:00 -t 1:00 out.avi
|
77
95
|
partial_filename = to_here_final_file + '.' + (@idx += 1).to_s + '.avi'
|
78
96
|
if File.exist? partial_filename
|
79
97
|
FileUtils.rm partial_filename
|
80
98
|
end
|
81
|
-
"
|
99
|
+
"call ffmpeg -i #{@big_temp} #{codecs} -ss #{start} -t #{endy} #{partial_filename}\n"
|
82
100
|
end
|
83
101
|
|
84
102
|
end
|
85
103
|
|
86
104
|
end
|
87
|
-
|
88
|
-
if $0 == __FILE__
|
89
|
-
require 'rubygems'
|
90
|
-
require 'sane'
|
91
|
-
puts 'syntax: yaml_file_name d:\ output (00:15 00:25) (--run)'
|
92
|
-
a = YAML.load_file ARGV.shift
|
93
|
-
drive = ARGV.shift
|
94
|
-
raise 'wrong drive' unless File.exist?(drive + "AUDIO_TS")
|
95
|
-
execute = ARGV.delete('--run')
|
96
|
-
commands = MencoderWrapper.get_bat_commands(a, drive, *ARGV)
|
97
|
-
if ARGV.length > 2
|
98
|
-
write_to = 'range.bat'
|
99
|
-
else
|
100
|
-
write_to = 'all.bat'
|
101
|
-
end
|
102
|
-
File.write(write_to, commands)
|
103
|
-
print 'wrote ' + write_to
|
104
|
-
system(write_to) if execute
|
105
|
-
end
|
data/lib/mouse.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
1
18
|
require 'rubygems'
|
2
19
|
require 'ffi'
|
3
20
|
|
data/lib/mouse_forever.rb
CHANGED
@@ -1,2 +1,19 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
1
18
|
require './../lib/mouse.rb'
|
2
19
|
Mouse::jitter_forever_in_own_thread.join
|
data/lib/mplayer_edl.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
require_relative 'overlayer'
|
19
|
+
|
20
|
+
class MplayerEdl
|
21
|
+
def self.convert_to_edl specs
|
22
|
+
out = ""
|
23
|
+
for type, metric in {"mutes" => 1, "blank_outs" => 0}
|
24
|
+
specs[type].each{|start, endy, other|
|
25
|
+
out += "#{OverLayer.translate_string_to_seconds start} #{OverLayer.translate_string_to_seconds endy} #{metric}\n"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
out
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/muter.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
1
18
|
require 'rubygems' # ugh
|
2
19
|
require 'ffi'
|
3
20
|
|
data/lib/ocr.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
1
18
|
require 'sane' # gem
|
2
19
|
require 'whichr' # gem
|
3
20
|
require_relative 'swing_helpers' # to_filename lodo not have it there
|
data/lib/overlayer.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
1
18
|
require 'sane'
|
2
19
|
require 'thread'
|
3
20
|
require 'timeout'
|
data/lib/screen_tracker.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
1
18
|
require 'win32/screenshot'
|
2
19
|
require 'sane'
|
3
20
|
require 'yaml'
|
@@ -41,7 +58,7 @@ class ScreenTracker
|
|
41
58
|
@digits = digits
|
42
59
|
@previously_displayed_warning = false
|
43
60
|
@dump_digit_count = 1
|
44
|
-
pps 'using x',@x, 'from x', x, 'y', @y, 'from y', y,'x2',@x2,'y2',@y2,'digits', @digits if $VERBOSE
|
61
|
+
pps 'using x',@x, 'from x', x, 'y', @y, 'from y', y,'x2',@x2,'y2',@y2,'digits', @digits if $VERBOSE
|
45
62
|
end
|
46
63
|
|
47
64
|
def get_hwnd
|
data/lib/storage.rb
CHANGED
@@ -1,82 +1,99 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
#
|
31
|
-
#
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
def
|
80
|
-
@
|
81
|
-
|
82
|
-
|
1
|
+
=begin
|
2
|
+
Copyright 2010, Roger Pack
|
3
|
+
This file is part of Sensible Cinema.
|
4
|
+
|
5
|
+
Sensible Cinema is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
Sensible Cinema is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with Sensible Cinema. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
# use it like
|
19
|
+
|
20
|
+
class Storage
|
21
|
+
class << self
|
22
|
+
attr_writer :storage_dir
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.storage_dir
|
26
|
+
@user_dir ||= File.join(File.expand_path('~'), ".storage")
|
27
|
+
end
|
28
|
+
|
29
|
+
# Open a storage file or create it if it doesn't exist.
|
30
|
+
#
|
31
|
+
# @param [String] a (short) name, should be suitable for use as a filename
|
32
|
+
def initialize(name)
|
33
|
+
@name = name
|
34
|
+
unless File.exists?(Storage.storage_dir)
|
35
|
+
FileUtils.mkdir_p(Storage.storage_dir)
|
36
|
+
end
|
37
|
+
rollback
|
38
|
+
end
|
39
|
+
|
40
|
+
# Save the storage to disk.
|
41
|
+
def save
|
42
|
+
File.open(path, "w") { |f| YAML.dump(@storage, f) }
|
43
|
+
update_timestamp
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
# Rollback the storage to the latest revision saved to disk or empty it if
|
48
|
+
# it hasn't been saved.
|
49
|
+
def rollback
|
50
|
+
if File.exists?(path)
|
51
|
+
@storage = YAML.load_file(path)
|
52
|
+
raise 'storage file is corrupted--please delete ' + path unless @storage.is_a? Hash
|
53
|
+
update_timestamp
|
54
|
+
else
|
55
|
+
@storage = {}
|
56
|
+
end
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
# retrieve key value
|
61
|
+
# note: it does not re-read from disk before returning you this value
|
62
|
+
def [](key)
|
63
|
+
if @last_modified_time
|
64
|
+
if File.exist?(path()) && (File.stat(path()).mtime != @last_modified_time)
|
65
|
+
rollback
|
66
|
+
end
|
67
|
+
end
|
68
|
+
@storage[key]
|
69
|
+
end
|
70
|
+
|
71
|
+
# set key to value
|
72
|
+
# note: it automatically saves this to disk
|
73
|
+
def []=(key, value)
|
74
|
+
@storage[key] = value
|
75
|
+
save
|
76
|
+
value
|
77
|
+
end
|
78
|
+
|
79
|
+
def set_default(key, value)
|
80
|
+
unless @storage.has_key?(key)
|
81
|
+
self[key] = value
|
82
|
+
end
|
83
|
+
value
|
84
|
+
end
|
85
|
+
|
86
|
+
def keys
|
87
|
+
@storage.keys
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def path
|
93
|
+
File.join(Storage.storage_dir, @name + ".yaml")
|
94
|
+
end
|
95
|
+
|
96
|
+
def update_timestamp
|
97
|
+
@last_modified_time = File.stat(path()).mtime
|
98
|
+
end
|
99
|
+
end
|