module Termtter::Client

It depends on defaults/fib.rb

あいうえお

Constants

CW
LINEH
PH
PROTOCOLS
SEARCH_URI
W3MIMG

Attributes

commands[R]
logger[R]
task_manager[R]

Public Class Methods

add_command(name) { |command| ... } click to toggle source
# File lib/termtter/client.rb, line 81
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) click to toggle source
# File lib/termtter/client.rb, line 51
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) click to toggle source
# File lib/termtter/client.rb, line 215
def add_task(*arg, &block)
  @task_manager.add_task(*arg, &block)
end
alias(alias_name, command)
Alias for: register_alias
alias_command(arg) click to toggle source
# File lib/plugins/command_plus.rb, line 11
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
apply_filters_for_hook(hook_name, statuses, event) click to toggle source
# File lib/termtter/client.rb, line 148
def apply_filters_for_hook(hook_name, statuses, event)
  get_hooks(hook_name).inject(statuses) {|s, hook|
    hook.call(s, event)
  }
end
clear_command() click to toggle source
# File lib/termtter/client.rb, line 91
def clear_command
  @commands.clear
end
clear_filter() click to toggle source
# File lib/termtter/client.rb, line 56
def clear_filter
  @filters.clear
end
clear_line() click to toggle source
# File lib/termtter/client.rb, line 362
def clear_line
  print "\e[0G" + "\e[K" unless win?
end
collect_hashtags(text) click to toggle source
# File lib/plugins/defaults/standard_completion.rb, line 55
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) click to toggle source
# File lib/termtter/client.rb, line 195
def command_exists?(text)
  @commands.values.any? {|command| command.match?(text) }
end
confirm(message, default_yes = true, &block) click to toggle source
# File lib/termtter/client.rb, line 366
def confirm(message, default_yes = true, &block)
  pause # TODO: TaskManager から呼ばれるならこれいらないなぁ

  print "\"#{message.strip}\" "
  readline = Readline.readline(default_yes ? "[Y/n] " : "[N/y] ", 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) click to toggle source
# File lib/plugins/defaults/stdout.rb, line 74
def self.data_to_typable_id(data)
  id = config.plugins.stdout.typable_id_prefix +
    @typable_id_generator.get_id(data)
end
default_logger() click to toggle source
# File lib/termtter/client.rb, line 273
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) click to toggle source
# File lib/plugins/replace.rb, line 3
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) click to toggle source
# File lib/plugins/command_plus.rb, line 3
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) click to toggle source
# File lib/plugins/multi_output.rb, line 9
def delete_output(name)
  @outputs.delete(name)
end
delete_task(key) click to toggle source
# File lib/plugins/searchline.rb, line 6
def delete_task(key)
  @task_manager.delete_task(key) # returns nil if task for key is not exist
end
encode(text, encoding) click to toggle source
# File lib/plugins/encoding.rb, line 4
def self.encode text, encoding
  return text unless encoding

  if RUBY_VERSION >= '1.9'
    begin
      text = text.encode encoding
    rescue
      # no encodings exception
    end
  else
    begin 
      require 'nkf'
    rescue
      return text
    end

    text = case encoding
           when 'utf-8'
             NKF.nkf('-w', text)
           when 'euc-jp'
             NKF.nkf('-e', text)
           when 'sjis'
             NKF.nkf('-s', text)
           else
             text
           end
  end
end
english?(text) click to toggle source
# File lib/plugins/en2ja.rb, line 13
def self.english?(text)
  /[一-龠]+|[ぁ-ん]+|[ァ-ヴー]+|[a-zA-Z0-9]+/ !~ text
end
eval_init_block() click to toggle source
# File lib/termtter/client.rb, line 305
def eval_init_block
  @init_block.call(self) if @init_block
end
execute(text) click to toggle source
# File lib/termtter/client.rb, line 154
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 Timeout::Error
  call_hooks("timeout", text)
  raise
end
exit() click to toggle source
# File lib/termtter/client.rb, line 223
def exit
  puts 'finalizing...'
  call_hooks(:exit)
  @task_manager.kill
end
expand_tco_urls!(text, urls) click to toggle source
# File lib/plugins/defaults/expand_tco_url.rb, line 13
def self.expand_tco_urls!(text, urls)
  urls.each do |u|
    next unless u[:expanded_url]
    text.sub!(/#{Regexp.escape(u[:url])}/, u[:expanded_url])
  end
end
fetch_title_data(uri) click to toggle source
# File lib/plugins/appendtitle.rb, line 11
def self.fetch_title_data(uri) # returns {:title, :uri} | {:uri} | nil
  return unless uri
  key = %w{ plugins appendtitle title-data}.push(Digest::SHA1.hexdigest(uri)).join('-')
  if v = memory_cache.get(key)
    logger.debug "appendtitle: cache hit for #{uri}"
    return v
  end

  memory_cache.set(key, {}, config.plugins.appendtitle.cache_expire) # to avoid duplicate fetch
  logger.debug "appendtitle: fetching title for #{uri}"
  data = {}
  uri_fetch = uri
  begin
    io = URI.parse(uri_fetch).read
    base_uri = io.base_uri.to_s
    base_uri = uri_fetch if base_uri.length > 1000
    data[:uri] = base_uri
    charset = io.scan(/charset="?([^\s"]*)/i).flatten.inject(Hash.new{0}){|a, b| a[b]+=1; a}.to_a.sort_by{|a|a[1]}.reverse.first[0] # XXX: scan charset from source
    begin # title
      source = Nokogiri(io, base_uri, charset)
      title = source.at('title').text rescue nil
      title ||= source.at('h1').text rescue nil
      title ||= source.at('h2').text rescue nil
      title = title.gsub(/\n/, '').gsub(/\s+/, ' ') if title
      data[:title] = title if title
    rescue
    end
    memory_cache.set(key, data, config.plugins.appendtitle.cache_expire)
    data
  rescue RuntimeError => error
    # example: redirection forbidden: http://bit.ly/gSarwN -> https://github.com/jugyo/termtter/commit/6e5fa4455a5117fb6c10bdf82bae52cfcf57a91f
    if error.message =~ /^redirection forbidden/
      logger.debug "appendtitle: #{error.message}"
      uri_fetch = error.message.split(/\s+/).last
      retry
    end
  rescue Timeout::Error, StandardError => error
    logger.debug "appendtitle: error #{uri}, #{error.class.to_s}: #{error.message}"
    nil
  end
end
find_command(text) click to toggle source
# File lib/termtter/client.rb, line 199
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) click to toggle source
# File lib/plugins/filter.rb, line 48
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) click to toggle source
# File lib/plugins/group.rb, line 8
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) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 590
def find_status_ids(text)
  public_storage[:status_ids].select {|id| /#{Regexp.quote(text)}/ =~ id.to_s }
end
find_users(text) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 594
def find_users(text)
  public_storage[:users].select {|user| /^#{Regexp.quote(text)}/ =~ user }
end
following_friends() click to toggle source
# File lib/plugins/irc_gw.rb, line 15
def following_friends
  user_name = config.user_name
  frinends  = []
  last = nil
  begin
    puts "collecting friends (#{frinends.length})"
    last = Termtter::API::twitter.friends(:screen_name => 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."
  Set.new(frinends.map(&:screen_name))
end
formatted_help(helps) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 467
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
friends(max) click to toggle source
# File lib/plugins/stream.rb, line 16
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
friends_or_followers_command(type, arg) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 173
def self.friends_or_followers_command(type, arg)
  raise "type should be :friends or :followers" unless [:friends, :followers].include? type
  limit = 20
  if /\-([\d]+)/ =~ arg
    limit = $1.to_i
    arg = arg.gsub(/\-([\d]+)/, '')
  end
  arg.strip!
  user_name = arg.empty? ? config.user_name : arg
  users = get_friends_or_followers(type, user_name, limit)
  longest = users.map{ |u| u.screen_name.length}.max
  users.reverse.each{|user|
    padding = ' ' * (longest - user.screen_name.length)
    user_id = Termtter::Client.data_to_typable_id(user.id) rescue ''
    color = user.following ? config.plugins.stdout.colors.first : config.plugins.stdout.colors.last
    mark  = user.following ? '♥' : '✂'
    erbed_text = ERB.new(config.plugins.standard.one_line_profile_format).result(binding)
    puts TermColor.unescape(TermColor.parse(erbed_text))
  }
end
gen_pass(master_pass) click to toggle source
# File lib/plugins/md5pass.rb, line 10
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) click to toggle source

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

# File lib/termtter/client.rb, line 96
def get_command(name)
  @commands[name]
end
get_followers(user_name, max) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 138
def self.get_followers(user_name, max)
  self.get_friends_or_followers(:followers, user_name, max)
end
get_friends(user_name, max) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 134
def self.get_friends(user_name, max)
  self.get_friends_or_followers(:friends, user_name, max)
end
get_friends_or_followers(type, user_name, max) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 142
def self.get_friends_or_followers(type, user_name, max)
  raise "type should be :friends or :followers" unless [:friends, :followers].include? type
  users = []
  cursor = -1
  begin
    tmp = Termtter::API::twitter.__send__(type, user_name, :cursor => cursor)
    cursor = tmp[:next_cursor]
    users += tmp[:users]
    puts "#{users.length}/#{max}" if max > 100
  rescue
    break
  end until (cursor.zero? or users.length > max)
  users.take(max)
end
get_group_of(screen_name) click to toggle source
# File lib/plugins/group.rb, line 14
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) click to toggle source
# File lib/termtter/client.rb, line 348
def handle_error(e)
  logger.error("#{e.class.to_s}: #{e.message}")
  logger.error(e.backtrace.join("\n")) if (e.backtrace and config.devel)
  get_hooks(:on_error).each {|hook| hook.call(e) }
end
init(&block) click to toggle source
# File lib/termtter/client.rb, line 296
def init(&block)
  @init_block = block
end
is_member?(status, group = nil) click to toggle source
# File lib/plugins/group.rb, line 55
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
legacy_config_support() click to toggle source
# File lib/termtter/client.rb, line 242
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) click to toggle source
# File lib/plugins/defaults/list.rb, line 183
def self.list_name_to_slug(list_name)
  list_name[/([^\/]*)$/]
end
load_config() click to toggle source
# File lib/termtter/client.rb, line 229
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
  unless config.dmsg_permission
    require 'termtter/config_setup'
    ConfigSetup.reauth
  end
end
load_history() click to toggle source
# File lib/plugins/history.rb, line 16
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_plugins() click to toggle source
# File lib/termtter/client.rb, line 300
def load_plugins
  plug 'defaults'
  plug config.system.load_plugins
end
memory_cache() click to toggle source
# File lib/termtter/client.rb, line 47
def memory_cache
  @memory_cache ||= Termtter::MemoryCache.new
end
mongo_db() click to toggle source
# File lib/plugins/mongo.rb, line 6
def mongo_db
  @mongo_db ||= Mongo::Connection.new('localhost', 27017, :pool_size => 5, :timeout => 5).db(config.plugins.mongo.db_name)
end
move_legacy_config_file() click to toggle source

MEMO: This method will be removed in Termtter 2.0.0

# File lib/termtter/client.rb, line 252
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) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 586
def normalize_as_user_name(text)
  text.strip.sub(/^@/, '')
end
notify(*args) click to toggle source
# File lib/termtter/client.rb, line 144
def notify(*args)
  ::Notify.notify(*args)
end
open_editor(path) click to toggle source
# 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) click to toggle source
# File lib/plugins/open_url.rb, line 5
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/
      system 'xdg-open', uri
    when /mswin(?!ce)|mingw|bccwin/
      system 'explorer', uri
    else
      system 'open', uri
    end
  end
end
output(statuses, event = :default) click to toggle source

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,
}
# File lib/termtter/client.rb, line 120
def output(statuses, event = :default)
  return if statuses.nil? || statuses.empty?
  event = Termtter::Event.new(event) unless event.kind_of? Termtter::Event

  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.
    # but... when is the "someday"?
    filtered = f.call(filtered, event)
  end

  call_hooks(:post_filter, filtered, event)
  get_hooks(:output).each do |hook|
    Termtter::Client.logger.debug { "output: call hook :output #{hook.inspect}" }
    hook.call(
      apply_filters_for_hook(:"filter_for_#{hook.name}", filtered, event),
      event)
  end
  Termtter::Client.logger.debug "output: call hook :output, done"
end
output_favorites(target, threshold) click to toggle source
# File lib/plugins/favotter.rb, line 10
def output_favorites(target, threshold)
  favorites = parse("http://favotter.net/user/#{target}?mode=new&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_options() click to toggle source
# File lib/termtter/client.rb, line 313
def parse_options
  Termtter::OptParser.parse!(ARGV)
end
pause() click to toggle source
# File lib/termtter/client.rb, line 207
def pause
  @task_manager.pause
end
plug :: Name -> (Hash) → IO () where NAME = String | Symbol | [NAME] click to toggle source
# File lib/termtter/client.rb, line 24
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/', ''))

  name_sym = name.gsub(/-/, '_').to_sym
  options.each do |key, value|
    config.plugins.__refer__(name_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) click to toggle source
# 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_list() click to toggle source
plugin_list

IO ()

# File lib/plugins/defaults/standard_commands.rb, line 498
def self.plugin_list
  (Dir["#{File.dirname(__FILE__)}/../**/*.rb"] + Dir["#{Termtter::CONF_DIR}/plugins/**/*.rb"]).
    map {|f| File.expand_path(f).scan(/.*plugins\/(.*)\.rb/).flatten[0] }.
    sort
end
post_quote(s, comment = nil) click to toggle source
# File lib/plugins/quote.rb, line 6
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) click to toggle source
# File lib/plugins/reply_retweet.rb, line 6
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) click to toggle source
# File lib/plugins/defaults/retweet.rb, line 14
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."
      else
        raise
      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)
  params = config.plugins.retweet.as_reply ? {:in_reply_to_status_id => s.id} : {}
  Termtter::API.twitter.update(text, params)
  puts "=> #{text}"
end
public_storage() click to toggle source
# File lib/termtter/client.rb, line 43
def public_storage
  @public_storage ||= {}
end
puts(message) click to toggle source
# File lib/plugins/multi_output.rb, line 13
def puts message
  @outputs.each_value do |block|
    block.call(message)
  end
end
register_alias(alias_name, command) click to toggle source
# File lib/plugins/defaults/alias.rb, line 23
def register_alias(alias_name, command)
  @aliases[alias_name.to_sym] = command.to_s
end
Also aliased as: alias
register_command(arg, opts = {}, &block) click to toggle source
# File lib/termtter/client.rb, line 60
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 = {}) click to toggle source
# File lib/termtter/client.rb, line 100
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) click to toggle source
# File lib/plugins/multi_output.rb, line 5
def register_output(as, &block)
  @outputs[as] = block
end
remove_alias(alias_name) click to toggle source
# File lib/plugins/defaults/alias.rb, line 28
def remove_alias(alias_name)
  @aliases.delete alias_name.to_sym
end
remove_command(name) click to toggle source
# File lib/termtter/client.rb, line 77
def remove_command(name)
  commands.delete(name.to_sym)
end
rescue_error() { || ... } click to toggle source
# File lib/termtter/client.rb, line 354
def rescue_error
  begin
    yield
  rescue Exception => e
    handle_error(e)
  end
end
resume() click to toggle source
# File lib/termtter/client.rb, line 211
def resume
  @task_manager.resume
end
run() click to toggle source
# File lib/termtter/client.rb, line 321
def run
  parse_options
  show_splash unless config.system.cmd_mode
  setup_task_manager
  load_config
  load_plugins
  eval_init_block
  begin
    Termtter::API.setup
  rescue Rubytter::APIError => e
    handle_error(e)
    exit!
  end

  config.system.eval_scripts.each {|script| rescue_error { eval script }}
  config.system.run_commands.each {|cmd| rescue_error { 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_history() click to toggle source
# File lib/plugins/history.rb, line 43
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) click to toggle source
# File lib/plugins/scrape.rb, line 13
def self.scrape_group(group)
  members = config.plugins.group.groups[group] || []
  scrape_members(members)
end
scrape_members(members) click to toggle source
# File lib/plugins/scrape.rb, line 4
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(:screen_name => member, :include_entities => 1)
  end
  statuses
end
search_plugin_file(name, include_system_plugins = false) click to toggle source
# 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_logger() click to toggle source
# File lib/termtter/client.rb, line 266
def setup_logger
  @logger = config.logger || default_logger
  @logger.level = config.devel ? Logger::DEBUG : Logger::INFO
  call_hooks(:post_setup_logger)
  @logger
end
setup_task_manager() click to toggle source
# File lib/termtter/client.rb, line 309
def setup_task_manager
  @task_manager = Termtter::TaskManager.new(1)
end
shorten_url(url, host, format) click to toggle source

returns nil if not shorten

# File lib/plugins/url_shortener.rb, line 49
def self.shorten_url(url, host, format)
  return url if config.plugins.url_shortener.ignore_regexp =~ url # already shorten
  url_enc = URI.escape(url, /[^a-zA-Z0-9.:]/)
  res = Termtter::HTTPpool.start(host) do |h|
    h.get(format % url_enc)
  end
  if res.code == '200'
    result = res.body
    if /"(http.*?)"/ =~ result
      result = $1
    elsif /"statusCode": "ERROR"/ =~ result
      return nil
    end
    result
  else
    nil
  end
end
show_settings(conf, level = 0) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 388
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_splash() click to toggle source
# File lib/termtter/client.rb, line 317
def show_splash
  puts TermColor.parse(config.splash)
end
swap_timeline_format(format) { || ... } click to toggle source
# File lib/plugins/stream.rb, line 35
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) click to toggle source
# File lib/plugins/defaults/stdout.rb, line 83
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) click to toggle source
# File lib/plugins/train.rb, line 3
def self.train(length)
  text = "ε="
  length.times{ text << "⋤⋥" }
  text
end
typable_id?(id) click to toggle source
# File lib/plugins/typable_id.rb, line 57
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) click to toggle source
# File lib/plugins/typable_id.rb, line 38
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) click to toggle source
# File lib/plugins/typable_id.rb, line 48
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) click to toggle source
# File lib/plugins/defaults/stdout.rb, line 79
def self.typable_id_to_data(id)
  @typable_id_generator.get(id)
end
update_with_user_and_id(text, username, id) click to toggle source
# File lib/plugins/defaults/standard_commands.rb, line 580
def 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) click to toggle source
# File lib/plugins/multi_post.rb, line 4
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

Private Class Methods

alive_thread?(name) click to toggle source
# File lib/plugins/stream.rb, line 49
def alive_thread?(name)
  config.plugins.stream.__send__(name).alive? rescue false
end
fav_color(amount) click to toggle source
# File lib/plugins/favotter.rb, line 42
def fav_color(amount)
  case amount
    when 1 then 'GREEN'
    when 2 then 'CYAN'
    when 3 then 'CYAN'
    when 4 then 'CYAN'
    else        'RED'
  end
end
gi_config() click to toggle source
# File lib/plugins/github-issues.rb, line 165
def self.gi_config; config.plugins.github_issues end
gi_project() click to toggle source
# File lib/plugins/github-issues.rb, line 166
def self.gi_project; Giic.new(gi_config.user, gi_config.repo) end
input_editor(body = nil) click to toggle source
# 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
kill_thread(name) click to toggle source
# File lib/plugins/stream.rb, line 45
def kill_thread(name)
  config.plugins.stream.__send__(name).kill rescue nil
  config.plugins.stream.__assign__(name, nil)
end
login() click to toggle source
# File lib/plugins/github-issues.rb, line 168
def self.login
  if config.plugins.github_issues.login.empty?
    print 'login > '; $stdout.flush
    config.plugins.github_issues.login = gets.chomp
  end
  if config.plugins.github_issues.token.empty?
    print 'token > '; $stdout.flush
    config.plugins.github_issues.token = gets.chomp
  end
  gi_project.login(gi_config.login, gi_config.token)
end
parse(url) click to toggle source
# File lib/plugins/favotter.rb, line 30
def parse(url)
  doc = Nokogiri(open(url).read)
  doc.css('div.entry').map do |entry|
    id     = entry['id'].gsub(/\Astatus_/, '')
    text   = CGI.unescapeHTML(entry.css('span.status_text').first.content)
    amount = entry.css('div.info span.favotters').first.content
    amount = amount.match(/(\d+)/)[1].to_i
    users  = entry.css('div.info span.favotters img').map {|u| u['title'] }
    [id, text, amount, users]
  end
end