Class: Alfred::Core

Inherits:
Object
  • Object
show all
Defined in:
lib/alfred.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&blk) ⇒ Core

Returns a new instance of Core.

Raises:



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/alfred.rb', line 152

def initialize(&blk)
  @with_rescue_feedback = true
  @with_help_feedback = false
  @cached_feedback_reload_option = {
    :use_reload_option => false,
    :use_exclamation_mark => false
  }

  @query = ARGV
  @raw_query = ARGV.dup

  @handler_controller = ::Alfred::Handler::Controller.new

  instance_eval(&blk) if block_given?

  raise NoBundleIDError unless bundle_id
end

Instance Attribute Details

#cached_feedback_reload_optionObject

Returns the value of attribute cached_feedback_reload_option.



146
147
148
# File 'lib/alfred.rb', line 146

def cached_feedback_reload_option
  @cached_feedback_reload_option
end

#handler_controllerObject (readonly)

Returns the value of attribute handler_controller.



148
149
150
# File 'lib/alfred.rb', line 148

def handler_controller
  @handler_controller
end

#queryObject (readonly)

Returns the value of attribute query.



149
150
151
# File 'lib/alfred.rb', line 149

def query
  @query
end

#raw_queryObject (readonly)

Returns the value of attribute raw_query.



149
150
151
# File 'lib/alfred.rb', line 149

def raw_query
  @raw_query
end

#with_help_feedbackObject

Returns the value of attribute with_help_feedback.



145
146
147
# File 'lib/alfred.rb', line 145

def with_help_feedback
  @with_help_feedback
end

#with_rescue_feedbackObject

Returns the value of attribute with_rescue_feedback.



145
146
147
# File 'lib/alfred.rb', line 145

def with_rescue_feedback
  @with_rescue_feedback
end

Instance Method Details

#bundle_idObject

Returns nil if not set.



361
362
363
# File 'lib/alfred.rb', line 361

def bundle_id
  @bundle_id ||= info_plist['bundleid'] unless info_plist['bundleid'].empty?
end

#cached_feedback?Boolean

Returns:

  • (Boolean)


383
384
385
# File 'lib/alfred.rb', line 383

def cached_feedback?
  @cached_feedback_reload_option.values.any?
end

#closeObject



251
252
253
254
255
# File 'lib/alfred.rb', line 251

def close
  @feedback.close if @feedback
  @setting.close if @setting
  # @workflow_setting.close if @workflow_setting
end

#debug?Boolean

Returns:

  • (Boolean)


171
172
173
# File 'lib/alfred.rb', line 171

def debug?
  ui.level >= LogUI::WARN
end

#feedback(opts = {}, &blk) ⇒ Object Also known as: with_cached_feedback



350
351
352
# File 'lib/alfred.rb', line 350

def feedback(opts = {}, &blk)
  @feedback ||= new_feedback(opts, &blk)
end

#info_plistObject



356
357
358
# File 'lib/alfred.rb', line 356

def info_plist
  @info_plist ||= Plist::parse_xml('info.plist')
end

#last_optionObject

Parse and return user query to three parts

[ [before], last option, tail ]


288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/alfred.rb', line 288

def last_option
  (@raw_query.size - 1).downto(0) do |i|
    if @raw_query[i].start_with? '-'
      if @raw_query[i] == @raw_query[-1]
        return @raw_query[0...i], '', @raw_query[i]
      else
        return @raw_query[0..i], @raw_query[i], @raw_query[(i + 1)..-1].join(' ')
      end
    end
  end

  return [], '', @raw_query.join(' ')
end

#new_feedback(opts, &blk) ⇒ Object



416
417
418
# File 'lib/alfred.rb', line 416

def new_feedback(opts, &blk)
  ::Alfred::Feedback.new(self, opts, &blk)
end

#new_setting(opts) ⇒ Object



421
422
423
424
425
426
427
428
429
430
431
432
# File 'lib/alfred.rb', line 421

def new_setting(opts)
  default_opts = {
    :file    => File.join(Alfred.workflow_folder, "setting.yaml"),
    :format  => 'yaml',
  }
  opts = default_opts.update(opts)

  ::Alfred::Setting.new(self) do
    @backend_file = opts[:file]
    @formt = opts[:format]
  end
end

#on_helpObject



411
412
413
# File 'lib/alfred.rb', line 411

def on_help
  reload_help_item
end

#options(opts = {}) ⇒ Object



304
305
306
# File 'lib/alfred.rb', line 304

def options(opts = {})
  @options ||= OpenStruct.new(opts)
end

#query_parserObject



308
309
310
# File 'lib/alfred.rb', line 308

def query_parser
  @query_parser ||= init_query_parser
end

#rescue_feedback(opts = {}) ⇒ Object



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/alfred.rb', line 388

def rescue_feedback(opts = {})
  default_opts = {
    :title        => "Failed Query!"                                  ,
    :subtitle     => "Check log #{ui.log_file} for extra debug info." ,
    :uid          => 'Rescue Feedback'                                ,
    :valid        => 'no'                                             ,
    :autocomplete => ''                                               ,
    :icon         => Feedback.CoreServicesIcon('AlertStopIcon')
  }
  if @with_help_feedback
   default_opts[:autocomplete] = '-h'
  end
  opts = default_opts.update(opts)

  items = []
  items << Feedback::Item.new(opts[:title], opts)
  log_item = Feedback::FileItem.new(ui.log_file)
  log_item.uid = nil
  items << log_item

  feedback.to_alfred('', items)
end

#start_handlerObject

Main loop to work with handlers



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/alfred.rb', line 178

def start_handler

  if @with_help_feedback
    ::Alfred::Handler::Help.new(self, :with_handler_help => true).register
  end

  return if @handler_controller.empty?

  # step 1: register option parser for handlers
  @handler_controller.each do |handler|
    handler.on_parser
  end

  begin
    query_parser.parse!
  rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
    ui.warn(
      "Fail to parse user query.\n" \
      "  #{e.inspect}\n  #{e.backtrace.join("  \n")}\n") if debug?
  end

  if @cached_feedback_reload_option[:use_exclamation_mark] && !options.should_reload_cached_feedback
    if ARGV[0].eql?('!')
      ARGV.shift
      options.should_reload_cached_feedback = true
    elsif ARGV[-1].eql?('!')
      ARGV.delete_at(-1)
      options.should_reload_cached_feedback = true
    end
  end

  @query = ARGV

  # step 2: dispatch options to handler for FEEDBACK or ACTION
  case options.workflow_mode
  when :feedback
    @handler_controller.each_handler do |handler|
      handler.on_feedback
    end

    puts feedback.to_alfred(@query)
  when :action
    arg = @query
    if @query.length == 1
      if hsh = xml_parser(@query[0])
        arg = hsh
      end
    end

    if arg.is_a?(Hash)
      @handler_controller.each_handler do |handler|
        handler.on_action(arg)
      end
    else
      #fallback default action
      arg.each do |a|
        if File.exist? a
          %x{open "#{a}"}
        end
      end
    end
  else
    raise InvalidArgument, "#{options.workflow_mode} mode is not supported."
  end

  # step 3: close
  close
  @handler_controller.each_handler do |handler|
    handler.on_close
  end

end

#storage_pathObject

Non-volatile storage directory for this bundle



374
375
376
377
378
379
380
# File 'lib/alfred.rb', line 374

def storage_path
  path = "#{ENV['HOME']}/Library/Application Support/Alfred 2/Workflow Data/#{bundle_id}"
  unless File.exist?(path)
    FileUtils.mkdir_p(path)
  end
  path
end

#uiObject



327
328
329
# File 'lib/alfred.rb', line 327

def ui
  @ui ||= LogUI.new(bundle_id)
end

#user_queryObject

User query without reload options



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/alfred.rb', line 261

def user_query
  q = @raw_query.dup

  if cached_feedback?
    if @cached_feedback_reload_option[:use_exclamation_mark] 
      if q[0].eql?('!')
        q.shift
      elsif q[-1].eql?('!')
        q.delete_at(-1)
      end
    end

    if @cached_feedback_reload_option[:use_reload_option]
      q.delete_if do |v|
        ['-r', '--reload'].include? v
      end
    end
  end

  q
end

#user_setting(&blk) ⇒ Object Also known as: setting

user setting is stored in the storage_path by default



342
343
344
345
346
# File 'lib/alfred.rb', line 342

def user_setting(&blk)
  @setting ||= new_setting(
    :file => File.join(storage_path, "setting.yaml")
  )
end

#volatile_storage_pathObject



365
366
367
368
369
370
371
# File 'lib/alfred.rb', line 365

def volatile_storage_path
  path = "#{ENV['HOME']}/Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data/#{bundle_id}"
  unless File.directory?(path)
    FileUtils.mkdir_p(path)
  end
  path
end

#workflow_setting(opts = {}) ⇒ Object

workflow setting is stored in the workflow_folder



335
336
337
# File 'lib/alfred.rb', line 335

def workflow_setting(opts = {})
  @workflow_setting ||= new_setting(opts)
end

#xml_builder(arg) ⇒ Object



323
324
325
# File 'lib/alfred.rb', line 323

def xml_builder(arg)
  Gyoku.xml(:root => arg)
end

#xml_parser(xml) ⇒ Object



312
313
314
315
316
317
318
319
320
321
# File 'lib/alfred.rb', line 312

def xml_parser(xml)
  @xml_parser ||= Nori.new(:parser => :rexml,
                           :convert_tags_to => lambda { |tag| tag.to_sym })
  begin
    hsh = @xml_parser.parse(xml)
    return hsh[:root]
  rescue REXML::ParseException, Nokogiri::XML::SyntaxError
    return nil
  end
end