alfred-workflow 1.11.3 → 2.0.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 +7 -7
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Gemfile.lock +45 -28
- data/Guardfile +4 -4
- data/History.txt +142 -0
- data/Manifest.txt +7 -0
- data/README.md +19 -1
- data/Rakefile +6 -4
- data/alfred-workflow.gemspec +27 -9
- data/lib/alfred.rb +275 -47
- data/lib/alfred/feedback.rb +112 -24
- data/lib/alfred/feedback/file_item.rb +2 -6
- data/lib/alfred/feedback/item.rb +10 -0
- data/lib/alfred/feedback/webloc_item.rb +1 -1
- data/lib/alfred/handler.rb +133 -0
- data/lib/alfred/handler/autocomplete.rb +86 -0
- data/lib/alfred/handler/callback.rb +130 -0
- data/lib/alfred/handler/cofig.rb +33 -0
- data/lib/alfred/handler/help.rb +162 -0
- data/lib/alfred/osx.rb +63 -0
- data/lib/alfred/setting.rb +29 -73
- data/lib/alfred/ui.rb +1 -0
- data/lib/alfred/util.rb +53 -5
- data/lib/alfred/version.rb +1 -1
- data/spec/alfred/feedback_spec.rb +8 -8
- data/spec/alfred/setting_spec.rb +44 -50
- data/spec/alfred_spec.rb +2 -10
- data/test/workflow/setting.yaml +2 -1
- metadata +304 -135
- metadata.gz.sig +1 -3
data/lib/alfred.rb
CHANGED
@@ -3,10 +3,15 @@ require 'rubygems' unless defined? Gem # rubygems is only needed in 1.8
|
|
3
3
|
require 'plist'
|
4
4
|
require 'fileutils'
|
5
5
|
require 'yaml'
|
6
|
+
require 'optparse'
|
7
|
+
require 'ostruct'
|
8
|
+
require 'gyoku'
|
9
|
+
require 'nori'
|
6
10
|
|
7
11
|
require 'alfred/ui'
|
8
12
|
require 'alfred/feedback'
|
9
13
|
require 'alfred/setting'
|
14
|
+
require 'alfred/handler/help'
|
10
15
|
|
11
16
|
module Alfred
|
12
17
|
|
@@ -18,15 +23,33 @@ module Alfred
|
|
18
23
|
|
19
24
|
class ObjCError < AlfredError; status_code(1) ; end
|
20
25
|
class NoBundleIDError < AlfredError; status_code(2) ; end
|
26
|
+
class InvalidArgument < AlfredError; status_code(10) ; end
|
21
27
|
class InvalidFormat < AlfredError; status_code(11) ; end
|
22
28
|
class NoMethodError < AlfredError; status_code(13) ; end
|
23
29
|
class PathError < AlfredError; status_code(14) ; end
|
24
30
|
|
25
31
|
class << self
|
26
32
|
|
33
|
+
#
|
34
|
+
# Default entry point to build alfred workflow with this gem
|
35
|
+
#
|
36
|
+
# Example:
|
37
|
+
#
|
38
|
+
# class MyHandler < ::Alfred::Handler::Base
|
39
|
+
# # ......
|
40
|
+
# end
|
41
|
+
# Alfred.with_friendly_error do |alfred|
|
42
|
+
# alfred.with_rescue_feedback = true
|
43
|
+
# alfred.with_help_feedback = true
|
44
|
+
# MyHandler.new(alfred).register
|
45
|
+
# end
|
46
|
+
#
|
27
47
|
def with_friendly_error(alfred = Alfred::Core.new, &blk)
|
28
48
|
begin
|
49
|
+
|
29
50
|
yield alfred
|
51
|
+
alfred.start_handler
|
52
|
+
|
30
53
|
rescue AlfredError => e
|
31
54
|
alfred.ui.error e.message
|
32
55
|
alfred.ui.debug e.backtrace.join("\n")
|
@@ -42,6 +65,8 @@ module Alfred
|
|
42
65
|
rescue SystemExit => e
|
43
66
|
puts alfred.rescue_feedback(
|
44
67
|
:title => "SystemExit: #{e.status}") if alfred.with_rescue_feedback
|
68
|
+
alfred.ui.error e.message
|
69
|
+
alfred.ui.debug e.backtrace.join("\n")
|
45
70
|
exit e.status
|
46
71
|
rescue Exception => e
|
47
72
|
alfred.ui.error(
|
@@ -83,41 +108,190 @@ __APPLESCRIPT__}.chop
|
|
83
108
|
end
|
84
109
|
|
85
110
|
class Core
|
86
|
-
attr_accessor :with_rescue_feedback
|
87
|
-
attr_accessor :
|
111
|
+
attr_accessor :with_rescue_feedback, :with_help_feedback
|
112
|
+
attr_accessor :cached_feedback_reload_option
|
88
113
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
@
|
114
|
+
attr_reader :handler_controller
|
115
|
+
attr_reader :query, :raw_query
|
116
|
+
|
117
|
+
|
118
|
+
def initialize(&blk)
|
119
|
+
@with_rescue_feedback = true
|
120
|
+
@with_help_feedback = false
|
121
|
+
@cached_feedback_reload_option = {
|
122
|
+
:use_reload_option => false,
|
123
|
+
:use_exclamation_mark => false
|
124
|
+
}
|
125
|
+
|
126
|
+
@query = ARGV
|
127
|
+
@raw_query = ARGV.dup
|
128
|
+
|
129
|
+
@handler_controller = ::Alfred::Handler::Controller.new
|
95
130
|
|
96
131
|
instance_eval(&blk) if block_given?
|
132
|
+
|
133
|
+
raise NoBundleIDError unless bundle_id
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
def debug?
|
138
|
+
ui.level >= LogUI::WARN
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Main loop to work with handlers
|
143
|
+
#
|
144
|
+
def start_handler
|
145
|
+
|
146
|
+
if @with_help_feedback
|
147
|
+
::Alfred::Handler::Help.new(self, :with_handler_help => true).register
|
148
|
+
end
|
149
|
+
|
150
|
+
return if @handler_controller.empty?
|
151
|
+
|
152
|
+
# step 1: register option parser for handlers
|
153
|
+
@handler_controller.each do |handler|
|
154
|
+
handler.on_parser
|
155
|
+
end
|
156
|
+
|
157
|
+
begin
|
158
|
+
query_parser.parse!
|
159
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
|
160
|
+
ui.warn(
|
161
|
+
"Fail to parse user query.\n" \
|
162
|
+
" #{e.inspect}\n #{e.backtrace.join(" \n")}\n") if debug?
|
163
|
+
end
|
164
|
+
|
165
|
+
if @cached_feedback_reload_option[:use_exclamation_mark] && !options.should_reload_cached_feedback
|
166
|
+
if ARGV[0].eql?('!')
|
167
|
+
ARGV.shift
|
168
|
+
options.should_reload_cached_feedback = true
|
169
|
+
elsif ARGV[-1].eql?('!')
|
170
|
+
ARGV.delete_at(-1)
|
171
|
+
options.should_reload_cached_feedback = true
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
@query = ARGV
|
176
|
+
|
177
|
+
# step 2: dispatch options to handler for FEEDBACK or ACTION
|
178
|
+
case options.workflow_mode
|
179
|
+
when :feedback
|
180
|
+
@handler_controller.each_handler do |handler|
|
181
|
+
handler.on_feedback
|
182
|
+
end
|
183
|
+
|
184
|
+
puts feedback.to_alfred(@query)
|
185
|
+
when :action
|
186
|
+
arg = @query
|
187
|
+
if @query.length == 1
|
188
|
+
if hsh = xml_parser(@query[0])
|
189
|
+
arg = hsh
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
if arg.is_a?(Hash)
|
194
|
+
@handler_controller.each_handler do |handler|
|
195
|
+
handler.on_action(arg)
|
196
|
+
end
|
197
|
+
else
|
198
|
+
#fallback default action
|
199
|
+
arg.each do |a|
|
200
|
+
if File.exist? a
|
201
|
+
%x{open "#{a}"}
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
else
|
206
|
+
raise InvalidArgument, "#{options.workflow_mode} mode is not supported."
|
207
|
+
end
|
208
|
+
|
209
|
+
# step 3: close
|
210
|
+
close
|
211
|
+
@handler_controller.each_handler do |handler|
|
212
|
+
handler.on_close
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
def close
|
218
|
+
@feedback.close if @feedback
|
219
|
+
@setting.close if @setting
|
220
|
+
# @workflow_setting.close if @workflow_setting
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
#
|
225
|
+
# Parse and return user query to three parts
|
226
|
+
#
|
227
|
+
# [ [before], last option, tail ]
|
228
|
+
#
|
229
|
+
def last_option
|
230
|
+
(@raw_query.size - 1).downto(0) do |i|
|
231
|
+
if @raw_query[i].start_with? '-'
|
232
|
+
if @raw_query[i] == @raw_query[-1]
|
233
|
+
return @raw_query[0...i], '', @raw_query[i]
|
234
|
+
else
|
235
|
+
return @raw_query[0..i], @raw_query[i], @raw_query[(i + 1)..-1].join(' ')
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
return [], '', @raw_query.join(' ')
|
241
|
+
end
|
242
|
+
|
243
|
+
def options(opts = {})
|
244
|
+
@options ||= OpenStruct.new(opts)
|
245
|
+
end
|
246
|
+
|
247
|
+
def query_parser
|
248
|
+
@query_parser ||= init_query_parser
|
249
|
+
end
|
250
|
+
|
251
|
+
def xml_parser(xml)
|
252
|
+
@xml_parser ||= Nori.new(:parser => :rexml,
|
253
|
+
:convert_tags_to => lambda { |tag| tag.to_sym })
|
254
|
+
begin
|
255
|
+
hsh = @xml_parser.parse(xml)
|
256
|
+
return hsh[:root]
|
257
|
+
rescue REXML::ParseException, Nokogiri::XML::SyntaxError
|
258
|
+
return nil
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def xml_builder(arg)
|
263
|
+
Gyoku.xml(:root => arg)
|
97
264
|
end
|
98
265
|
|
99
266
|
def ui
|
100
|
-
raise NoBundleIDError unless bundle_id
|
101
267
|
@ui ||= LogUI.new(bundle_id)
|
102
268
|
end
|
103
269
|
|
104
|
-
def setting(&blk)
|
105
|
-
@setting ||= Setting.new(self, &blk)
|
106
|
-
end
|
107
270
|
|
271
|
+
#
|
272
|
+
# workflow setting is stored in the workflow_folder
|
273
|
+
#
|
108
274
|
def workflow_setting(opts = {})
|
109
|
-
@workflow_setting ||=
|
275
|
+
@workflow_setting ||= new_setting(opts)
|
110
276
|
end
|
111
277
|
|
112
|
-
|
113
|
-
|
278
|
+
#
|
279
|
+
# user setting is stored in the storage_path by default
|
280
|
+
#
|
281
|
+
def user_setting(&blk)
|
282
|
+
@setting ||= new_setting(
|
283
|
+
:file => File.join(storage_path, "setting.yaml")
|
284
|
+
)
|
114
285
|
end
|
286
|
+
alias_method :setting, :user_setting
|
115
287
|
|
116
|
-
|
117
|
-
|
118
|
-
@feedback ||=
|
288
|
+
|
289
|
+
def feedback(opts = {}, &blk)
|
290
|
+
@feedback ||= new_feedback(opts, &blk)
|
119
291
|
end
|
120
292
|
|
293
|
+
alias_method :with_cached_feedback, :feedback
|
294
|
+
|
121
295
|
def info_plist
|
122
296
|
@info_plist ||= Plist::parse_xml('info.plist')
|
123
297
|
end
|
@@ -128,9 +302,8 @@ __APPLESCRIPT__}.chop
|
|
128
302
|
end
|
129
303
|
|
130
304
|
def volatile_storage_path
|
131
|
-
raise NoBundleIDError unless bundle_id
|
132
305
|
path = "#{ENV['HOME']}/Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data/#{bundle_id}"
|
133
|
-
unless File.
|
306
|
+
unless File.directory?(path)
|
134
307
|
FileUtils.mkdir_p(path)
|
135
308
|
end
|
136
309
|
path
|
@@ -138,7 +311,6 @@ __APPLESCRIPT__}.chop
|
|
138
311
|
|
139
312
|
# Non-volatile storage directory for this bundle
|
140
313
|
def storage_path
|
141
|
-
raise NoBundleIDError unless bundle_id
|
142
314
|
path = "#{ENV['HOME']}/Library/Application Support/Alfred 2/Workflow Data/#{bundle_id}"
|
143
315
|
unless File.exist?(path)
|
144
316
|
FileUtils.mkdir_p(path)
|
@@ -147,55 +319,111 @@ __APPLESCRIPT__}.chop
|
|
147
319
|
end
|
148
320
|
|
149
321
|
|
150
|
-
def
|
151
|
-
|
152
|
-
if ws.has_key? :help
|
153
|
-
ws[:help].map do |item|
|
154
|
-
case item[:kind]
|
155
|
-
when 'url'
|
156
|
-
item[:folder] = storage_path
|
157
|
-
Feedback::UrlItem.new(item)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
322
|
+
def cached_feedback?
|
323
|
+
@cached_feedback_reload_option.values.any?
|
161
324
|
end
|
162
325
|
|
163
326
|
|
164
327
|
def rescue_feedback(opts = {})
|
165
328
|
default_opts = {
|
166
|
-
:title
|
167
|
-
:subtitle
|
168
|
-
:uid
|
169
|
-
:
|
170
|
-
|
171
|
-
|
172
|
-
}
|
329
|
+
:title => "Failed Query!" ,
|
330
|
+
:subtitle => "Check log #{ui.log_file} for extra debug info." ,
|
331
|
+
:uid => 'Rescue Feedback' ,
|
332
|
+
:valid => 'no' ,
|
333
|
+
:autocomplete => '' ,
|
334
|
+
:icon => Feedback.CoreServicesIcon('AlertStopIcon')
|
173
335
|
}
|
336
|
+
if @with_help_feedback
|
337
|
+
default_opts[:autocomplete] = '-h'
|
338
|
+
end
|
174
339
|
opts = default_opts.update(opts)
|
175
340
|
|
176
341
|
items = []
|
177
342
|
items << Feedback::Item.new(opts[:title], opts)
|
178
|
-
|
343
|
+
log_item = Feedback::FileItem.new(ui.log_file)
|
344
|
+
log_item.uid = nil
|
345
|
+
items << log_item
|
179
346
|
|
180
347
|
feedback.to_alfred('', items)
|
181
348
|
end
|
182
349
|
|
183
|
-
|
350
|
+
def on_help
|
351
|
+
reload_help_item
|
352
|
+
end
|
353
|
+
|
184
354
|
|
185
|
-
def
|
355
|
+
def new_feedback(opts, &blk)
|
356
|
+
::Alfred::Feedback.new(self, opts, &blk)
|
357
|
+
end
|
358
|
+
|
359
|
+
|
360
|
+
def new_setting(opts)
|
186
361
|
default_opts = {
|
187
|
-
:file => "setting.yaml",
|
362
|
+
:file => File.join(Alfred.workflow_folder, "setting.yaml"),
|
188
363
|
:format => 'yaml',
|
189
364
|
}
|
190
365
|
opts = default_opts.update(opts)
|
191
366
|
|
192
|
-
|
193
|
-
|
367
|
+
::Alfred::Setting.new(self) do
|
368
|
+
@backend_file = opts[:file]
|
369
|
+
@formt = opts[:format]
|
194
370
|
end
|
195
|
-
@workflow_setting
|
196
371
|
end
|
197
372
|
|
198
|
-
|
373
|
+
private
|
374
|
+
|
375
|
+
def reload_help_item
|
376
|
+
title = []
|
377
|
+
if @cached_feedback_reload_option[:use_exclamation_mark]
|
378
|
+
title.push "!"
|
379
|
+
end
|
380
|
+
|
381
|
+
if @cached_feedback_reload_option[:use_reload_option]
|
382
|
+
title.push "-r, --reload"
|
383
|
+
end
|
384
|
+
|
385
|
+
unless title.empty?
|
386
|
+
return {
|
387
|
+
:kind => 'text',
|
388
|
+
:order => (Handler::HelpItem::Base_Order * 10),
|
389
|
+
:title => "#{title.join(', ')} [Reload cached feedback unconditionally]" ,
|
390
|
+
:subtitle => %q{The '!' mark must be at the beginning or end of the query.} ,
|
391
|
+
}
|
392
|
+
else
|
393
|
+
return nil
|
394
|
+
end
|
395
|
+
end
|
199
396
|
|
397
|
+
def init_query_parser
|
398
|
+
options.workflow_mode = :feedback
|
399
|
+
options.modifier = :none
|
400
|
+
options.should_reload_cached_feedback = false
|
401
|
+
|
402
|
+
modifiers = [:command, :alt, :control, :shift, :fn, :none]
|
403
|
+
OptionParser.new do |opts|
|
404
|
+
opts.separator ""
|
405
|
+
opts.separator "Built-in Options:"
|
406
|
+
|
407
|
+
opts.on("--workflow-mode [TYPE]", [:feedback, :action],
|
408
|
+
"Alfred handler working mode (feedback, action)") do |t|
|
409
|
+
options.workflow_mode = t
|
410
|
+
end
|
411
|
+
|
412
|
+
opts.on("--modifier [MODIFIER]", modifiers,
|
413
|
+
"Alfred action modifier (#{modifiers})") do |t|
|
414
|
+
options.modifier = t
|
415
|
+
end
|
416
|
+
|
417
|
+
if @cached_feedback_reload_option[:use_reload_option]
|
418
|
+
opts.on("-r", "--reload", "Reload cached feedback") do
|
419
|
+
options.should_reload_cached_feedback = true
|
420
|
+
end
|
421
|
+
end
|
422
|
+
opts.separator ""
|
423
|
+
opts.separator "Handler Options:"
|
424
|
+
end
|
425
|
+
|
426
|
+
end
|
427
|
+
end
|
200
428
|
end
|
201
429
|
|
data/lib/alfred/feedback.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
require "rexml/document"
|
2
2
|
require 'alfred/feedback/item'
|
3
3
|
require 'alfred/feedback/file_item'
|
4
|
+
require 'alfred/feedback/webloc_item'
|
4
5
|
|
5
6
|
module Alfred
|
6
7
|
|
7
8
|
class Feedback
|
8
9
|
attr_accessor :items
|
10
|
+
attr_reader :backend_file
|
9
11
|
|
10
|
-
def initialize
|
12
|
+
def initialize(alfred, opts = {}, &blk)
|
11
13
|
@items = []
|
14
|
+
@core = alfred
|
15
|
+
use_backend(opts)
|
16
|
+
instance_eval(&blk) if block_given?
|
17
|
+
|
12
18
|
end
|
13
19
|
|
14
20
|
def add_item(opts = {})
|
@@ -20,6 +26,13 @@ module Alfred
|
|
20
26
|
@items << FileItem.new(path, opts)
|
21
27
|
end
|
22
28
|
|
29
|
+
def add_webloc_item(path, opts = {})
|
30
|
+
unless opts[:folder]
|
31
|
+
opts[:folder] = @core.storage_path
|
32
|
+
end
|
33
|
+
@items << WeblocItem.new(path, opts)
|
34
|
+
end
|
35
|
+
|
23
36
|
def to_xml(with_query = '', items = @items)
|
24
37
|
document = REXML::Element.new("items")
|
25
38
|
if with_query.empty?
|
@@ -36,47 +49,122 @@ module Alfred
|
|
36
49
|
|
37
50
|
alias_method :to_alfred, :to_xml
|
38
51
|
|
52
|
+
#
|
53
|
+
# Merge with other feedback
|
54
|
+
#
|
55
|
+
def merge!(other)
|
56
|
+
if other.is_a? Array
|
57
|
+
@items |= other
|
58
|
+
elsif other.is_a? Alfred::Feedback
|
59
|
+
@items |= other.items
|
60
|
+
else
|
61
|
+
raise ArgumentError, "Feedback can not merge with #{other.class}"
|
62
|
+
end
|
63
|
+
end
|
39
64
|
|
65
|
+
#
|
66
|
+
# The workflow is about to complete
|
67
|
+
#
|
68
|
+
# - save cached feedback if necessary
|
69
|
+
#
|
70
|
+
def close
|
71
|
+
put_cached_feedback if @backend_file
|
72
|
+
end
|
40
73
|
|
41
|
-
#
|
42
|
-
|
43
|
-
|
74
|
+
#
|
75
|
+
# ## helper class method for icon
|
76
|
+
#
|
77
|
+
def self.CoreServicesIcon(name)
|
78
|
+
{
|
79
|
+
:type => "default" ,
|
80
|
+
:name => "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/#{name}.icns"
|
81
|
+
}
|
44
82
|
end
|
45
83
|
|
46
|
-
def
|
47
|
-
|
84
|
+
def self.Icon(name)
|
85
|
+
{
|
86
|
+
:type => "default" ,
|
87
|
+
:name => name ,
|
88
|
+
}
|
89
|
+
end
|
90
|
+
def self.FileIcon(path)
|
91
|
+
{
|
92
|
+
:type => "fileicon" ,
|
93
|
+
:name => path ,
|
94
|
+
}
|
48
95
|
end
|
49
|
-
end
|
50
96
|
|
51
97
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
@core = alfred
|
98
|
+
#
|
99
|
+
# ## serialization
|
100
|
+
#
|
56
101
|
|
57
|
-
|
102
|
+
def use_backend(opts = {})
|
103
|
+
@backend_file = opts[:file] if opts[:file]
|
104
|
+
@should_expire_after_second = opts[:expire].to_i if opts[:expire]
|
58
105
|
end
|
106
|
+
alias_method :use_cache_file, :use_backend
|
59
107
|
|
60
|
-
def
|
61
|
-
@
|
62
|
-
@cf_file_valid_time = opts[:expire] if opts[:expire]
|
108
|
+
def backend_file
|
109
|
+
@backend_file ||= File.join(@core.volatile_storage_path, "cached_feedback")
|
63
110
|
end
|
64
111
|
|
65
|
-
def
|
66
|
-
|
112
|
+
def expired?
|
113
|
+
return false unless @should_expire_after_second
|
114
|
+
Time.now - File.ctime(backend_file) > @should_expire_after_second
|
67
115
|
end
|
116
|
+
|
68
117
|
def get_cached_feedback
|
69
|
-
return nil unless File.exist?(
|
70
|
-
if
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
return self
|
118
|
+
return nil unless File.exist?(backend_file)
|
119
|
+
return nil if expired?
|
120
|
+
|
121
|
+
load(@backend_file)
|
122
|
+
self
|
75
123
|
end
|
76
124
|
|
77
125
|
def put_cached_feedback
|
78
|
-
dump(
|
126
|
+
dump(backend_file)
|
127
|
+
end
|
128
|
+
|
129
|
+
def dump(to_file)
|
130
|
+
File.open(to_file, "wb") { |f| Marshal.dump(@items, f) }
|
131
|
+
end
|
132
|
+
|
133
|
+
def load(from_file)
|
134
|
+
@items = File.open(from_file, "rb") { |f| Marshal.load(f) }
|
135
|
+
end
|
136
|
+
|
137
|
+
def append(from_file)
|
138
|
+
@items << File.open(from_file, "rb") { |f| Marshal.load(f) }
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Provides yaml serialization support
|
143
|
+
#
|
144
|
+
if RUBY_VERSION < "1.9"
|
145
|
+
def to_yaml_properties
|
146
|
+
[ '@items' ]
|
147
|
+
end
|
148
|
+
else
|
149
|
+
def encode_with(coder)
|
150
|
+
coder['items'] = @items
|
151
|
+
end
|
79
152
|
end
|
153
|
+
|
154
|
+
#
|
155
|
+
# Provides marshalling support for use by the Marshal library.
|
156
|
+
#
|
157
|
+
def marshal_dump
|
158
|
+
@items
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# Provides marshalling support for use by the Marshal library.
|
163
|
+
#
|
164
|
+
def marshal_load(x)
|
165
|
+
@items = x
|
166
|
+
end
|
167
|
+
|
80
168
|
end
|
81
169
|
|
82
170
|
end
|