Module: Termtter::Client

Includes:
Hookable
Defined in:
lib/plugins/train.rb,
lib/plugins/ar.rb,
lib/plugins/db.rb,
lib/plugins/hi.rb,
lib/plugins/l2.rb,
lib/plugins/me.rb,
lib/plugins/sl.rb,
lib/plugins/erb.rb,
lib/plugins/log.rb,
lib/plugins/say.rb,
lib/plugins/bomb.rb,
lib/plugins/cool.rb,
lib/plugins/open.rb,
lib/plugins/async.rb,
lib/plugins/clear.rb,
lib/plugins/curry.rb,
lib/plugins/draft.rb,
lib/plugins/eject.rb,
lib/plugins/en2ja.rb,
lib/plugins/grass.rb,
lib/plugins/group.rb,
lib/plugins/quote.rb,
lib/plugins/shell.rb,
lib/plugins/timer.rb,
lib/plugins/wassr.rb,
lib/plugins/whois.rb,
lib/plugins/yhara.rb,
lib/plugins/yonda.rb,
lib/plugins/fibyou.rb,
lib/plugins/filter.rb,
lib/plugins/hatebu.rb,
lib/plugins/ignore.rb,
lib/plugins/irc_gw.rb,
lib/plugins/itunes.rb,
lib/plugins/otsune.rb,
lib/plugins/otsune.rb,
lib/plugins/primes.rb,
lib/plugins/random.rb,
lib/plugins/reblog.rb,
lib/plugins/scrape.rb,
lib/plugins/source.rb,
lib/plugins/stream.rb,
lib/plugins/trends.rb,
lib/plugins/w3mimg.rb,
lib/plugins/friends.rb,
lib/plugins/history.rb,
lib/plugins/jakigan.rb,
lib/plugins/md5pass.rb,
lib/plugins/outputz.rb,
lib/plugins/replace.rb,
lib/plugins/storage.rb,
lib/plugins/twitpic.rb,
lib/termtter/client.rb,
lib/plugins/addspace.rb,
lib/plugins/countter.rb,
lib/plugins/defaults.rb,
lib/plugins/favotter.rb,
lib/plugins/open_url.rb,
lib/plugins/paranoid.rb,
lib/plugins/saykanji.rb,
lib/plugins/uri-open.rb,
lib/plugins/quicklook.rb,
lib/plugins/fib_filter.rb,
lib/plugins/multi_post.rb,
lib/plugins/quick_exit.rb,
lib/plugins/search_url.rb,
lib/plugins/searchline.rb,
lib/plugins/typable_id.rb,
lib/plugins/http_server.rb,
lib/plugins/multi_reply.rb,
lib/plugins/reduce_text.rb,
lib/plugins/command_plus.rb,
lib/plugins/command_plus.rb,
lib/plugins/multi_output.rb,
lib/plugins/multi_output.rb,
lib/plugins/defaults/eval.rb,
lib/plugins/defaults/exec.rb,
lib/plugins/defaults/list.rb,
lib/plugins/github-issues.rb,
lib/plugins/reply_retweet.rb,
lib/plugins/screen-notify.rb,
lib/plugins/system_status.rb,
lib/plugins/update_editor.rb,
lib/plugins/another_prompt.rb,
lib/plugins/defaults/alias.rb,
lib/plugins/defaults/users.rb,
lib/plugins/list_with_opts.rb,
lib/plugins/defaults/plugin.rb,
lib/plugins/defaults/stdout.rb,
lib/plugins/defaults/switch.rb,
lib/plugins/defaults/hashtag.rb,
lib/plugins/defaults/keyword.rb,
lib/plugins/defaults/retweet.rb,
lib/plugins/hatebu_and_update.rb,
lib/plugins/defaults/standard_commands.rb,
lib/plugins/defaults/standard_completion.rb

Overview

config.plugins.alias.aliases = { :e => ‘exit’, :q => ‘exit’}

Defined Under Namespace

Modules: Jakigan Classes: DirectMessage, SearchEvent, UserSearchEvent

Constant Summary collapse

SEARCH_URI =
'search.twitter.com'
W3MIMG =
'/usr/lib/w3m/w3mimgdisplay'
LINEH =
PH / CH
PROTOCOLS =
%w(http https)

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Hookable

included

Class Attribute Details

.commandsObject (readonly)

Returns the value of attribute commands.



22
23
24
# File 'lib/termtter/client.rb', line 22

def commands
  @commands
end

Class Method Details

.add_command(name) ⇒ Object



73
74
75
76
77
78
79
80
81
# File 'lib/termtter/client.rb', line 73

def add_command(name)
  if block_given?
    command = Command.new(:name => name)
    yield command
    @commands[command.name] = command
  else
    raise ArgumentError, 'must be given block to set parameters'
  end
end

.add_filter(&b) ⇒ Object



47
48
49
50
# File 'lib/termtter/client.rb', line 47

def add_filter(&b)
  warn "add_filter method will be removed. Use Termtter::Client.register_hook(:name => ..., :point => :filter_for_output, :exec => ... ) instead."
  @filters << b
end

.add_task(*arg, &block) ⇒ Object



200
201
202
# File 'lib/termtter/client.rb', line 200

def add_task(*arg, &block)
  @task_manager.add_task(*arg, &block)
end

.alias_command(arg) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/plugins/command_plus.rb', line 12

def alias_command(arg)
  original, new = arg.split(/\s+/)
  if @commands[original.to_sym]
    @commands[new.to_sym] = @commands[original.to_sym].clone
    @commands[new.to_sym].name    = new.to_sym
    @commands[new.to_sym].aliases = []
    @commands[new.to_sym].help    = ''
    puts "alias '#{original}' to '#{new}'."
  else
    raise "#{original} command is not found."
  end
end

.alive_thread?(name) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
# File 'lib/plugins/stream.rb', line 50

def alive_thread?(name)
  config.plugins.stream.__send__(name).alive? rescue false
end

.apply_filters_for_hook(hook_name, statuses, event) ⇒ Object



133
134
135
136
137
# File 'lib/termtter/client.rb', line 133

def apply_filters_for_hook(hook_name, statuses, event)
  get_hooks(hook_name).inject(statuses) {|s, hook|
    hook.call(s, event)
  }
end

.clear_commandObject



83
84
85
# File 'lib/termtter/client.rb', line 83

def clear_command
  @commands.clear
end

.clear_filterObject



52
53
54
# File 'lib/termtter/client.rb', line 52

def clear_filter
  @filters.clear
end

.collect_hashtags(text) ⇒ Object



42
43
44
45
# File 'lib/plugins/defaults/standard_completion.rb', line 42

def self.collect_hashtags(text)
  text.force_encoding("UTF-8") if text.respond_to?(:force_encoding)
  public_storage[:hashtags_for_completion] += text.scan(/#([0-9A-Za-z_]+)/u).flatten
end

.command_exists?(text) ⇒ Boolean

Returns:

  • (Boolean)


180
181
182
# File 'lib/termtter/client.rb', line 180

def command_exists?(text)
  @commands.values.any? {|command| command.match?(text) }
end

.confirm(message, default_yes = true, &block) ⇒ Object



338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'lib/termtter/client.rb', line 338

def confirm(message, default_yes = true, &block)
  pause # TODO: TaskManager から呼ばれるならこれいらないなぁ

  prompt =
    if default_yes
      "\"#{message}".strip + "\" [Y/n] "
    else
      "\"#{message}".strip + "\" [N/y] "
    end
  readline = Readline.readline(prompt, false)
  result =
    if !!(/^$/ =~ readline) 
      default_yes
    else
      !!(/^y/i =~ readline)
    end

  if result && block
    block.call
  end

  result
ensure
  resume # TODO: TaskManager から呼ばれるならこれいらないなぁ
end

.data_to_typable_id(data) ⇒ Object



66
67
68
# File 'lib/plugins/defaults/stdout.rb', line 66

def self.data_to_typable_id(data)
  id = config.plugins.stdout.typable_id_prefix + @typable_id_generator.get_id(data)
end

.default_loggerObject



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/termtter/client.rb', line 248

def default_logger
  logger = Logger.new(STDOUT)
  logger.formatter = lambda {|severity, time, progname, message|
    color =
      case severity
      when /^DEBUG/
        'blue'
      when /^INFO/
        'cyan'
      when /^WARN/
        'magenta'
      when /^ERROR/
        'red'
      when /^FATAL/
        'on_red'
      else
        'white'
      end
    TermColor.parse("<#{color}>" + TermColor.escape("[#{severity}] #{message}\n") + "</#{color}>")
  }
  logger
end

.delete_and_replace(recent, pattern_reg, replace, global) ⇒ Object



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
33
# File 'lib/plugins/replace.rb', line 4

def self.delete_and_replace(recent, pattern_reg, replace, global)
  new_text =
    if global
      recent.text.gsub(pattern_reg, replace)
    else
      recent.text.sub(pattern_reg, replace)
    end

  param =
    if recent.in_reply_to_status_id
      {:in_reply_to_status_id => recent.in_reply_to_status_id}
    else
      {}
    end

  if new_text == recent.text
    puts "It was not replaced."
    raise Termtter::CommandCanceled
  end

  if /^y?$/i !~ Readline.readline("\"replace #{new_text}\" [Y/n] ", false)
    puts 'canceled.'
    raise Termtter::CommandCanceled
  else
    result = Termtter::API.twitter.remove_status(recent.id)
    puts "deleted => #{result.text}"
    result = Termtter::API.twitter.update(new_text, param)
    puts "updated => #{result.text}"
  end
end

.delete_command(arg) ⇒ Object



4
5
6
7
8
9
10
# File 'lib/plugins/command_plus.rb', line 4

def delete_command(arg)
  if @commands.delete(arg.to_sym)
    puts "#{arg} command is deleted."
  else
    raise "#{arg} command is not found."
  end
end

.delete_output(name) ⇒ Object



10
11
12
# File 'lib/plugins/multi_output.rb', line 10

def delete_output(name)
  @outputs.delete(name)
end

.delete_task(key) ⇒ Object



7
8
9
# File 'lib/plugins/searchline.rb', line 7

def delete_task(key)
  @task_manager.delete_task(key) # returns nil if task for key is not exist
end

.english?(text) ⇒ Boolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/plugins/en2ja.rb', line 14

def self.english?(text)
  /[一-龠]+|[ぁ-ん]+|[ァ-ヴー]+|[a-zA-Z0-9]+/ !~ text
end

.eval_init_blockObject



280
281
282
# File 'lib/termtter/client.rb', line 280

def eval_init_block
  @init_block.call(self) if @init_block
end

.execute(text) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/termtter/client.rb', line 139

def execute(text)
  text = text.strip

  @task_manager.invoke_and_wait do
    # FIXME: This block can become Maybe Monad
    get_hooks("pre_command").each {|hook|
      break if text == nil # interrupt if hook returns nil
      text = hook.call(text)
    }
    return if text.empty?

    command = find_command(text)
    raise CommandNotFound, text unless command

    command_str, modified_arg = command.split_command_line(text)
    command_str.strip!
    modified_arg ||= ''

    # FIXME: This block can become Maybe Monad
    get_hooks("modify_arg_for_#{command.name.to_s}").each {|hook|
      break if modified_arg == false # interrupt if hook return false
      modified_arg.strip!
      modified_arg = hook.call(command_str, modified_arg) || ''
    }
    modified_arg.strip!

    begin
      call_hooks("pre_exec_#{command.name.to_s}", command, modified_arg)
      result = command.call(command_str, modified_arg, text) # exec command
      call_hooks("post_exec_#{command.name.to_s}", command_str, modified_arg, result)
      call_hooks("post_command", text)
    rescue CommandCanceled
      return false
    end
    return true
  end
rescue TimeoutError
  call_hooks("timeout", text)
  raise
end

.exitObject



204
205
206
207
208
# File 'lib/termtter/client.rb', line 204

def exit
  puts 'finalizing...'
  call_hooks(:exit)
  @task_manager.kill
end

.find_command(text) ⇒ Object



184
185
186
187
188
189
190
# File 'lib/termtter/client.rb', line 184

def find_command(text)
  @commands.
    values.
    select {|command| command.match?(text) }.
    sort_by {|command| command.name.to_s.split(' ').size }.
    last
end

.find_filter_candidates(a, b, filters) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/plugins/filter.rb', line 49

def self.find_filter_candidates(a, b, filters)
  if a.empty?
    filters.to_a
  else
    filters.grep(/^#{Regexp.quote a}/i)
  end.
  map {|u| b % u }
end

.find_group_candidates(a, b) ⇒ Object



9
10
11
12
13
# File 'lib/plugins/group.rb', line 9

def self.find_group_candidates(a, b)
  config.plugins.group.groups.keys.map {|k| k.to_s}.
    grep(/^#{Regexp.quote a}/).
    map {|u| b % u }
end

.find_status_ids(text) ⇒ Object



468
469
470
# File 'lib/plugins/defaults/standard_commands.rb', line 468

def self.find_status_ids(text)
  public_storage[:status_ids].select {|id| /#{Regexp.quote(text)}/ =~ id.to_s}
end

.find_users(text) ⇒ Object



472
473
474
# File 'lib/plugins/defaults/standard_commands.rb', line 472

def self.find_users(text)
  public_storage[:users].select {|user| /^#{Regexp.quote(text)}/ =~ user}
end

.following_friendsObject



11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/plugins/irc_gw.rb', line 11

def following_friends
  user_name = config.user_name
  frinends  = []
  last = nil
  begin
    puts "collecting friends (#{frinends.length})"
    last = Termtter::API::twitter.friends(user_name, :cursor => last ? last.next_cursor : -1)
	frinends += last.users
  rescue Timeout::Error, StandardError # XXX
    break
  end until last.next_cursor == 0
  puts "You have #{frinends.length} friends."
  frinends.map(&:screen_name)
end

.formatted_help(helps) ⇒ Object



350
351
352
353
354
355
356
357
# File 'lib/plugins/defaults/standard_commands.rb', line 350

def self.formatted_help(helps)
  helps = helps.sort_by {|help| help[0] }
  width = helps.map {|n, _| n.size }.max
  space = 3
  helps.map {|name, desc|
    name.to_s.ljust(width + space) + desc.to_s
  }.join("\n")
end

.gen_pass(master_pass) ⇒ Object



11
12
13
14
15
16
17
18
19
# File 'lib/plugins/md5pass.rb', line 11

def self.gen_pass(master_pass)
    salt = config.plugins.md5pass.salt
    len = config.plugins.md5pass.len
    times = config.plugins.md5pass.times
    url = "http://#{config.host}/"
    user = config.user_name
    str = (url + salt + user + master_pass) * (2 ** times);
    Base64.encode64(Digest::MD5.digest(str))[0, len]
end

.get_command(name) ⇒ Object

MEMO: attr_reader :commands してるからこれいらない気もする



88
89
90
# File 'lib/termtter/client.rb', line 88

def get_command(name)
  @commands[name]
end

.get_friends(user_name, max) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/plugins/friends.rb', line 5

def get_friends(user_name, max)
  friends = []
  cursor = -1
  begin
    tmp = Termtter::API::twitter.friends(user_name, :cursor => cursor)
    cursor = tmp[:next_cursor]
    friends += tmp[:users]
    puts "#{friends.length}/#{max}"
  rescue
  end until (cursor.zero? or friends.length > max)
  friends.take(max)
end

.get_group_of(screen_name) ⇒ Object



15
16
17
# File 'lib/plugins/group.rb', line 15

def self.get_group_of(screen_name)
  config.plugins.group.groups.select{ |k, v| v.include? screen_name}.map{|a| a.first}
end

.handle_error(e) ⇒ Object



325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/termtter/client.rb', line 325

def handle_error(e)
  if logger
    logger.error("#{e.class.to_s}: #{e.message}")
    logger.error(e.backtrace.join("\n")) if (e.backtrace and config.devel)
  else
    raise e
  end
  get_hooks(:on_error).each {|hook| hook.call(e) }
rescue Exception => e
  $stderr.puts "Error: #{e}"
  $stderr.puts e.backtrace.join("\n")
end

.init(&block) ⇒ Object



271
272
273
# File 'lib/termtter/client.rb', line 271

def init(&block)
  @init_block = block
end

.input_editorObject



180
181
182
183
184
185
186
187
188
189
190
# File 'lib/plugins/github-issues.rb', line 180

def self.input_editor(body = nil)
  file = Tempfile.new('termtter')
  editor = config.plugins.github_issues.editor
  file.write body if body
  file.close
  system("#{editor} #{file.path}")
  result = file.open.read
  file.flush
  file.close(false)
  result
end

.is_member?(status, group = nil) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
59
60
61
62
# File 'lib/plugins/group.rb', line 56

def self.is_member?(status, group = nil)
  if group
    config.plugins.group.groups[group].include? status.user.screen_name
  else
    config.plugins.group.groups.values.flatten.include? status.user.screen_name
  end
end

.kill_thread(name) ⇒ Object



46
47
48
49
# File 'lib/plugins/stream.rb', line 46

def kill_thread(name)
  config.plugins.stream.__send__(name).kill rescue nil
  config.plugins.stream.__assign__(name, nil)
end

.legacy_config_supportObject



219
220
221
222
223
224
225
226
# File 'lib/termtter/client.rb', line 219

def legacy_config_support
  case File.ftype(File.expand_path('~/.termtter'))
  when 'directory'
    # nop
  when 'file'
    move_legacy_config_file
  end
end

.list_name_to_slug(list_name) ⇒ Object



152
153
154
# File 'lib/plugins/defaults/list.rb', line 152

def self.list_name_to_slug(list_name)
  list_name[/([^\/]*)$/]
end

.load_configObject



210
211
212
213
214
215
216
217
# File 'lib/termtter/client.rb', line 210

def load_config
  legacy_config_support() if File.exist? Termtter::CONF_DIR
  unless File.exist?(Termtter::CONF_FILE)
    require 'termtter/config_setup'
    ConfigSetup.run
  end
  load Termtter::CONF_FILE
end

.load_historyObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/plugins/history.rb', line 17

def self.load_history
  filename = File.expand_path(config.plugins.history.filename)
  keys = config.plugins.history.keys

  if File.exist?(filename)
    begin
      history = Marshal.load Zlib::Inflate.inflate(File.read(filename))
    rescue Zlib::BufError => e
      ui = create_highline
      delete = ui.ask("Unable to read #{filename}. Do you wish to remove it?")
      if delete =~ /^y/i
        if File.delete(filename) > 1
          puts "Removed #{filename}"
        end
      end
      history = nil
    end
    if history
      keys.each do |key|
        public_storage[key] = history[key] if history[key]
      end
      Readline::HISTORY.push *history[:history] if history[:history]
      puts "history loaded(#{File.size(filename)/1000}kb)"
    end
  end
end

.load_pluginsObject



275
276
277
278
# File 'lib/termtter/client.rb', line 275

def load_plugins
  plug 'defaults'
  plug config.system.load_plugins
end

.loggerObject



238
239
240
# File 'lib/termtter/client.rb', line 238

def logger
  @logger || setup_logger
end

.move_legacy_config_fileObject



228
229
230
231
232
233
234
235
236
# File 'lib/termtter/client.rb', line 228

def move_legacy_config_file
  FileUtils.mv(
    Termtter::CONF_DIR,
    File.expand_path('~/.termtter___'))
  Dir.mkdir(Termtter::CONF_DIR)
  FileUtils.mv(
    File.expand_path('~/.termtter___'),
    Termtter::CONF_FILE)
end

.normalize_as_user_name(text) ⇒ Object



464
465
466
# File 'lib/plugins/defaults/standard_commands.rb', line 464

def self.normalize_as_user_name(text)
  text.strip.sub(/^@/, '')
end

.open_editor(path) ⇒ Object



40
41
42
43
# File 'lib/plugins/defaults/plugin.rb', line 40

def self.open_editor(path)
  # TODO: change to common method or use launchy
  system ENV['EDITOR'] || 'vim', path
end

.open_uri(uri) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/plugins/open_url.rb', line 6

def self.open_uri(uri)
  unless config.plugins.open_url.browser.empty?
    system config.plugins.open_url.browser, uri
  else
    case RUBY_PLATFORM
    when /linux/
      if %x{echo $BROWSER}.strip.empty?
        system 'firefox', uri
      else
        system '$BROWSER', uri
      end
    when /mswin(?!ce)|mingw|bccwin/
      system 'explorer', uri
    else
      system 'open', uri
    end
  end
end

.output(statuses, event) ⇒ Object

statuses => [status, status, …] status => {

  :id => status id,
  :created_at => created time,
  :user_id => user id,
  :name => user name,
  :screen_name => user screen_name,
  :source => source,
  :reply_to => reply_to status id,
  :text => status,
  :original_data => original data,
}


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/termtter/client.rb', line 112

def output(statuses, event)
  return if statuses.nil? || statuses.empty?

  statuses = statuses.sort_by(&:id)
  call_hooks(:pre_filter, statuses, event)

  filtered = apply_filters_for_hook(:filter_for_output, statuses.map(&:clone), event)

  @filters.each do |f|  # TODO: code for compatibility. delete someday.
    filtered = f.call(filtered, event)
  end

  call_hooks(:post_filter, filtered, event)
  get_hooks(:output).each do |hook|
    hook.call(
      apply_filters_for_hook(:"filter_for_#{hook.name}", filtered, event),
      event
    )
  end
end

.output_favorites(target, threshold) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/plugins/favotter.rb', line 12

def output_favorites(target, threshold)
  favorites = parse("http://favotter.matope.com/user.php?user=#{target}&threshold=#{threshold}")

  public_storage[:favorited_ids].clear
  alphabet = '$a'
  max_amount_width = favorites.map {|f| now = f[2].to_s.size }.max
  favorites.reverse.each do |id, text, amount, users|
    public_storage[:favorited_ids][alphabet] = id
    color = fav_color(amount)
    fav   = "fav#{amount == 1 ? '' : 's'}"
    favorites_info = "(#{amount} #{fav})".rjust(max_amount_width + 7)
    format = "<GREEN>#{favorites_info} #{alphabet}</GREEN> <YELLOW>%s</YELLOW>: <#{color}>%s</#{color}>"
    values = [users.join(', '), CGI.escape(text)]
    puts CGI.unescape(TermColor.parse(format % values ))
    alphabet.succ!
  end
end

.parse_optionsObject



288
289
290
# File 'lib/termtter/client.rb', line 288

def parse_options
  Termtter::OptParser.parse!(ARGV)
end

.pauseObject



192
193
194
# File 'lib/termtter/client.rb', line 192

def pause
  @task_manager.pause
end

.plug(name, options = {}) ⇒ Object

plug

Name -> (Hash) -> IO () where NAME = String | Symbol | [NAME]



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/termtter/client.rb', line 25

def plug(name, options = {})
  if Array === name # Obviously `name.respond_to?(:each)` is better, but for 1.8.6 compatibility we cannot.
    name.each {|i| plug(i, options) }
    return
  end

  name = name.to_s

  return if config.system.disable_plugins.include?(name.gsub('defaults/', ''))

  options.each do |key, value|
    config.plugins.__refer__(name.gsub(/-/, '_').to_sym).__assign__(key.to_sym, value)
  end
  load "plugins/#{name}.rb"
rescue Exception => e
  Termtter::Client.handle_error(e)
end

.plugin_files(include_system_plugins = false) ⇒ Object



50
51
52
53
54
# File 'lib/plugins/defaults/plugin.rb', line 50

def self.plugin_files(include_system_plugins = false)
  files = Dir["#{Termtter::CONF_DIR}/plugins/*.rb"]
  files += Dir["#{File.expand_path(File.dirname(__FILE__))}/*.rb"] if include_system_plugins
  files
end

.plugin_listObject

plugin_list

IO ()



381
382
383
384
385
# File 'lib/plugins/defaults/standard_commands.rb', line 381

def self.plugin_list
  (Dir["#{File.dirname(__FILE__)}/../*.rb"] + Dir["#{Termtter::CONF_DIR}/plugins/*.rb"]).
    map {|f| File.basename(f).sub(/\.rb$/, '')}.
    sort
end

.post_quote(s, comment = nil) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/plugins/quote.rb', line 7

def self.post_quote(s, comment = nil)
  if s.user.protected && config.plugins.quote.confirm_protected &&
      !confirm("#{s.user.screen_name} is protected! Are you sure?", false)
    return
  end

  comment += ' ' unless comment.nil?
  text = ERB.new(config.plugins.quote.format).result(binding)
  Termtter::API.twitter.update(text)
  puts "=> #{text}"

  return text
end

.post_reply_retweet(s, comment = nil) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/plugins/reply_retweet.rb', line 7

def self.post_reply_retweet(s, comment = nil)
  if s.user.protected && config.plugins.reply_retweet.confirm_protected &&
      !confirm("#{s.user.screen_name} is protected! Are you sure?", false)
    return
  end

  text = s.text.gsub(/RT.+\z/, '')
  comment += ' ' unless comment.nil?
  text = ERB.new(config.plugins.reply_retweet.format).result(binding)
  Termtter::API.twitter.update(text)
  puts "=> #{text}"

  return text
end

.post_retweet(s, comment = nil) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/plugins/defaults/retweet.rb', line 13

def self.post_retweet(s, comment = nil)
  s.user.protected and
    config.plugins.retweet.confirm_protected and
    !confirm("#{s.user.screen_name} is protected! Are you sure?", false) and
    return

  # NOTE: If it's possible, this plugin tries to
  #   use the default RT feature twitter provides.
  if comment.nil? && config.plugins.retweet.official_retweet
    begin
      Termtter::API.twitter.retweet(s.id)
      # TODO: Vimshell support
      puts TermColor.parse("<blue>=&gt; RT @#{s.user.screen_name}: #{s.text}</blue>")
      return
    rescue Rubytter::APIError  # XXX: just for transition period
      if $!.to_s == 'Not found'
        Termtter::Client.logger.warn "Failed official retweet. Set twitter langage to English in https://twitter.com/account/settings or set config.plugins.retweet.official_retweet to false."
      end
    end
  end
  comment += ' ' unless comment.nil?
  rt_or_qt = (config.plugins.retweet.quotetweet and comment) ? 'QT' : 'RT'
  text = ERB.new(config.plugins.retweet.format).result(binding)
  Termtter::API.twitter.update(text)
  puts "=> #{text}"
end

.public_storageObject



43
44
45
# File 'lib/termtter/client.rb', line 43

def public_storage
  @public_storage ||= {}
end

.puts(message) ⇒ Object



14
15
16
17
18
# File 'lib/plugins/multi_output.rb', line 14

def puts message
  @outputs.each_value do |block|
    block.call(message)
  end
end

.register_alias(alias_name, command) ⇒ Object Also known as: alias



24
25
26
# File 'lib/plugins/defaults/alias.rb', line 24

def register_alias(alias_name, command)
  @aliases[alias_name.to_sym] = command.to_s
end

.register_command(arg, opts = {}, &block) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/termtter/client.rb', line 56

def register_command(arg, opts = {}, &block)
  command = case arg
    when Command
      arg
    when Hash
      Command.new(arg)
    when String, Symbol
      options = { :name => arg }
      options.merge!(opts)
      options[:exec_proc] = block
      Command.new(options)
    else
      raise ArgumentError, 'must be given Termtter::Command, Hash or String(Symbol) with block'
    end
  @commands[command.name] = command
end

.register_macro(name, macro, options = {}) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/termtter/client.rb', line 92

def register_macro(name, macro, options = {})
  command = {
    :name => name.to_sym,
    :exec_proc => lambda {|arg| execute(macro % arg)}
  }.merge(options)
  register_command(command)
end

.register_output(as, &block) ⇒ Object



6
7
8
# File 'lib/plugins/multi_output.rb', line 6

def register_output(as, &block)
  @outputs[as] = block
end

.remove_alias(alias_name) ⇒ Object



29
30
31
# File 'lib/plugins/defaults/alias.rb', line 29

def remove_alias(alias_name)
  @aliases.delete alias_name.to_sym
end

.resumeObject



196
197
198
# File 'lib/termtter/client.rb', line 196

def resume
  @task_manager.resume
end

.runObject



296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/termtter/client.rb', line 296

def run
  show_splash
  parse_options()
  load_config()
  setup_task_manager()
  load_plugins()
  eval_init_block()
  Termtter::API.setup()

  config.system.eval_scripts.each do |script|
    begin
      eval script
    rescue Exception => e
      handle_error(e)
    end
  end

  config.system.run_commands.each {|cmd| execute(cmd) }

  unless config.system.cmd_mode
    @task_manager.run()
    call_hooks(:initialize)
    add_task(:name => :call_hooks_after_launched, :after => 1) do
      call_hooks(:launched)
    end
    call_hooks(:init_command_line)
  end
end

.save_historyObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/plugins/history.rb', line 44

def self.save_history
  filename = File.expand_path(config.plugins.history.filename)
  keys = config.plugins.history.keys
  history = { }
  keys.each do |key|
    history[key] = public_storage[key]
  end
  max_of_history = config.plugins.history.max_of_history
  history[:history] = Readline::HISTORY.to_a.reverse.uniq.reverse
  if history[:history].size > max_of_history
    history[:history] = history[:history][-max_of_history..-1]
  end

  File.open(filename, 'w') do |f|
    f.write Zlib::Deflate.deflate(Marshal.dump(history))
  end
  puts "history saved(#{File.size(filename)/1000}kb)"
end

.scrape_group(group) ⇒ Object



14
15
16
17
# File 'lib/plugins/scrape.rb', line 14

def self.scrape_group(group)
  members = config.plugins.group.groups[group] || []
  scrape_members(members)
end

.scrape_members(members) ⇒ Object



5
6
7
8
9
10
11
12
# File 'lib/plugins/scrape.rb', line 5

def self.scrape_members(members)
  statuses = []
  members.each_with_index do |member, index|
    puts "member #{index+1}/#{members.size} #{member}"
    statuses += Termtter::API.twitter.user_timeline(member)
  end
  statuses
end

.search_plugin_file(name, include_system_plugins = false) ⇒ Object



45
46
47
48
# File 'lib/plugins/defaults/plugin.rb', line 45

def self.search_plugin_file(name, include_system_plugins = false)
  regex = /#{Regexp.quote(name + '.rb')}$/
  plugin_files(include_system_plugins).detect {|f| regex =~ f}
end

.setup_loggerObject



242
243
244
245
246
# File 'lib/termtter/client.rb', line 242

def setup_logger
  @logger = config.logger || default_logger
  @logger.level = config.devel ? Logger::DEBUG : Logger::INFO
  @logger
end

.setup_task_managerObject



284
285
286
# File 'lib/termtter/client.rb', line 284

def setup_task_manager
  @task_manager = Termtter::TaskManager.new(1)
end

.show_settings(conf, level = 0) ⇒ Object



271
272
273
274
275
276
277
278
279
280
281
# File 'lib/plugins/defaults/standard_commands.rb', line 271

def self.show_settings(conf, level = 0)
  conf.__values__.each do |k, v|
    if v.instance_of? Termtter::Config
      puts "#{k}:"
      show_settings v, level + 1
    else
      print '  ' * level
      puts "#{k} = #{v.nil? ? 'nil' : v.inspect}"
    end
  end
end

.show_splashObject



292
293
294
# File 'lib/termtter/client.rb', line 292

def show_splash
  puts TermColor.parse(config.splash)
end

.swap_timeline_format(format) ⇒ Object



36
37
38
39
40
41
42
43
44
# File 'lib/plugins/stream.rb', line 36

def swap_timeline_format(format)
  original = config.plugins.stdout.timeline_format
  if /\$orig/ =~ format
    format.gsub!(/\$orig/, original)
  end
  config.plugins.stdout.timeline_format = format
  yield
  config.plugins.stdout.timeline_format = original
end

.time_format_for(statuses) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/plugins/defaults/stdout.rb', line 74

def self.time_format_for(statuses)
  t0 = Time.now
  t1 = Time.parse(statuses.first[:created_at])
  t2 = Time.parse(statuses.last[:created_at])
  if [t0.year, t0.month, t0.day] == [t1.year, t1.month, t1.day] \
    and [t1.year, t1.month, t1.day] == [t2.year, t2.month, t2.day]
    config.plugins.stdout.time_format_today
  else
    config.plugins.stdout.time_format_not_today
  end
end

.train(length) ⇒ Object



4
5
6
7
8
# File 'lib/plugins/train.rb', line 4

def self.train(length)
  text = "ε="
  length.times{ text << "⋤⋥" }
  text
end

.typable_id?(id) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
61
62
63
64
# File 'lib/plugins/typable_id.rb', line 58

def self.typable_id?(id)
  if public_storage[:typable_id].assoc(id.to_s)
    return true
  else
    return false
  end
end

.typable_id_convert(id) ⇒ Object



39
40
41
42
43
44
45
46
47
# File 'lib/plugins/typable_id.rb', line 39

def self.typable_id_convert(id)
  if current_id = public_storage[:typable_id].assoc(id.to_s)
    return current_id[1]
  elsif current_id = public_storage[:typable_id].rassoc(id.to_s)
    return current_id[0]
  else
    return nil
  end
end

.typable_id_status(id) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/plugins/typable_id.rb', line 49

def self.typable_id_status(id)
  if current_id = (public_storage[:typable_id].assoc(id.to_s)||\
                   public_storage[:typable_id].rassoc(id.to_s))
    return current_id[2]
  else
    return nil
  end
end

.typable_id_to_data(id) ⇒ Object



70
71
72
# File 'lib/plugins/defaults/stdout.rb', line 70

def self.typable_id_to_data(id)
  @typable_id_generator.get(id)
end

.update_with_user_and_id(text, username, id) ⇒ Object



458
459
460
461
462
# File 'lib/plugins/defaults/standard_commands.rb', line 458

def self.update_with_user_and_id(text, username, id)
  text = "@#{username} #{text}"
  result = Termtter::API.twitter.update(text, {'in_reply_to_status_id' => id})
  puts "replied => #{result.text}"
end

.wassr_update(text) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/plugins/multi_post.rb', line 5

def wassr_update(text)
  if text.match(/^(\d+)\s+(.+)$/) and
      (s = Termtter::API.twitter.show($1) rescue nil)
    tmp_text = "@#{s.user.screen_name} #{$2}"
  else
    tmp_text = text
  end

  Net::HTTP.version_1_2
  req = Net::HTTP::Post.new("/statuses/update.json?")
  req.basic_auth config.plugins.wassr.username, config.plugins.wassr.password
  Net::HTTP.start('api.wassr.jp', 80) do |http|
    res = http.request(req, "status=#{URI.escape(tmp_text)}&source=Termtter")
  end
end

Instance Method Details

#friends(max) ⇒ Object



17
18
19
20
21
22
# File 'lib/plugins/stream.rb', line 17

def friends(max)
  Status.group(:user_id).
    select(:user_id, :screen_name).
    join(:users, :id => :user_id).
    order(:COUNT.sql_function.desc).take(max)
end