Module: Termtter::Client
- Defined in:
- lib/plugin/me.rb,
lib/plugin/sl.rb,
lib/filter/fib.rb,
lib/plugin/fib.rb,
lib/plugin/log.rb,
lib/plugin/say.rb,
lib/plugin/bomb.rb,
lib/plugin/cool.rb,
lib/plugin/spam.rb,
lib/filter/yhara.rb,
lib/plugin/clear.rb,
lib/plugin/devel.rb,
lib/plugin/grass.rb,
lib/plugin/group.rb,
lib/plugin/shell.rb,
lib/plugin/yhara.rb,
lib/plugin/yonda.rb,
lib/filter/ignore.rb,
lib/plugin/filter.rb,
lib/plugin/follow.rb,
lib/plugin/hatebu.rb,
lib/plugin/otsune.rb,
lib/plugin/otsune.rb,
lib/plugin/plugin.rb,
lib/plugin/primes.rb,
lib/plugin/random.rb,
lib/plugin/reblog.rb,
lib/plugin/scrape.rb,
lib/plugin/stdout.rb,
lib/filter/reverse.rb,
lib/plugin/history.rb,
lib/plugin/outputz.rb,
lib/plugin/favorite.rb,
lib/plugin/uri-open.rb,
lib/termtter/client.rb,
lib/plugin/quicklook.rb,
lib/plugin/multi_reply.rb,
lib/filter/url_addspace.rb,
lib/plugin/system_status.rb,
lib/plugin/update_editor.rb,
lib/filter/expand-tinyurl.rb,
lib/plugin/standard_plugins.rb
Class Method Summary collapse
-
.add_command(regex, &block) ⇒ Object
Deprecated FIXME: delete when become unnecessary.
- .add_help(name, desc) ⇒ Object
- .add_task(*arg, &block) ⇒ Object
-
.apply_filters(statuses) ⇒ Object
memo: each filter must return Array of Status.
- .call_commands(text, tw = nil) ⇒ Object
-
.call_hooks(statuses, event, tw = nil) ⇒ Object
TODO: delete argument “tw” when unnecessary.
-
.call_new_hooks(point, *args) ⇒ Object
return last hook return value.
- .create_highline ⇒ Object
- .create_input_thread ⇒ Object
- .do_hooks(statuses, event) ⇒ Object
- .exit ⇒ Object
- .find_filter_candidates(a, b, filters) ⇒ Object
- .find_group_candidates(a, b) ⇒ Object
- .find_plugin_candidates(a, b) ⇒ Object
- .find_status_id_candidates(a, b, u = nil) ⇒ Object
- .find_user_candidates(a, b) ⇒ Object
- .formatted_help(helps) ⇒ Object
- .get_command(name) ⇒ Object
- .get_hook(name) ⇒ Object
- .get_hooks(point) ⇒ Object
- .handle_error(e) ⇒ Object
- .init ⇒ Object
- .input_editor ⇒ Object
- .load_config ⇒ Object
- .load_default_plugins ⇒ Object
- .load_history ⇒ Object
- .open_uri(uri) ⇒ Object
- .pause ⇒ Object
- .print_statuses(statuses, sort = true, time_format = '%H:%M:%S') ⇒ Object
- .print_statuses_with_date(statuses, sort = true) ⇒ Object
- .public_storage ⇒ Object
- .register_command(arg) ⇒ Object
- .register_hook(arg) ⇒ Object
- .register_macro(name, macro, options = {}) ⇒ Object
- .resume ⇒ Object
- .run ⇒ Object
- .save_history ⇒ Object
- .scrape_group(group) ⇒ Object
- .scrape_members(members) ⇒ Object
- .setup_readline ⇒ Object
- .setup_update_timeline_task ⇒ Object
- .start_input_thread ⇒ Object
- .trap_setting ⇒ Object
- .wrap_require ⇒ Object
Instance Method Summary collapse
Class Method Details
.add_command(regex, &block) ⇒ Object
Deprecated FIXME: delete when become unnecessary
43 44 45 46 |
# File 'lib/termtter/client.rb', line 43 def add_command(regex, &block) warn "Termtter:Client.add_command method will be removed. Use Termtter::Client.register_command() instead. (#{caller.first})" @@commands[regex] = block end |
.add_help(name, desc) ⇒ Object
94 95 96 |
# File 'lib/termtter/client.rb', line 94 def add_help(name, desc) @@helps << [name, desc] end |
.add_task(*arg, &block) ⇒ Object
195 196 197 |
# File 'lib/termtter/client.rb', line 195 def add_task(*arg, &block) @@task_manager.add_task(*arg, &block) end |
.apply_filters(statuses) ⇒ Object
memo: each filter must return Array of Status
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/termtter/client.rb', line 107 def apply_filters(statuses) filtered = statuses.map{|s| s.dup } @@filters.each do |f| filtered = f.call(filtered) end filtered rescue => e handle_error(e) statuses end |
.call_commands(text, tw = nil) ⇒ Object
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 179 180 181 182 183 184 185 |
# File 'lib/termtter/client.rb', line 150 def call_commands(text, tw = nil) return if text.empty? command_found = false @@commands.each do |key, command| if key =~ text command_found = true @@task_manager.invoke_and_wait do command.call($~, Termtter::API.twitter) end end end @@new_commands.each do |key, command| command_info = command.match?(text) if command_info command_found = true input_command, arg = *command_info modified_arg = call_new_hooks("modify_arg_for_#{command.name.to_s}", input_command, arg) || arg || '' @@task_manager.invoke_and_wait do pre_exec_hook_result = call_new_hooks("pre_exec_#{command.name.to_s}", input_command, modified_arg) next if pre_exec_hook_result == false # exec command result = command.execute(modified_arg) if result call_new_hooks("post_exec_#{command.name.to_s}", input_command, modified_arg, result) end end end end raise CommandNotFound unless command_found end |
.call_hooks(statuses, event, tw = nil) ⇒ Object
TODO: delete argument “tw” when unnecessary
145 146 147 148 |
# File 'lib/termtter/client.rb', line 145 def call_hooks(statuses, event, tw = nil) do_hooks(statuses, :pre_filter) do_hooks(apply_filters(statuses), event) end |
.call_new_hooks(point, *args) ⇒ Object
return last hook return value
129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/termtter/client.rb', line 129 def call_new_hooks(point, *args) result = nil get_hooks(point).each {|hook| break if result == false # interrupt if hook return false result = hook.exec_proc.call(*args) } return result rescue => e if point.to_sym == :on_error raise else handle_error(e) end end |
.create_highline ⇒ Object
366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/termtter/client.rb', line 366 def create_highline HighLine.track_eof = false if $stdin.respond_to?(:getbyte) # for ruby1.9 require 'delegate' stdin_for_highline = SimpleDelegator.new($stdin) def stdin_for_highline.getc getbyte end else stdin_for_highline = $stdin end return HighLine.new(stdin_for_highline) end |
.create_input_thread ⇒ Object
351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/termtter/client.rb', line 351 def create_input_thread() Thread.new do while buf = Readline.readline(ERB.new(configatron.prompt).result(API.twitter.__send__(:binding)), true) Readline::HISTORY.pop if /^(u|update)\s+(.+)$/ =~ buf begin call_commands(buf) rescue CommandNotFound => e puts "Unknown command \"#{buf}\"" puts 'Enter "help" for instructions' end end exit # exit when press Control-D end end |
.do_hooks(statuses, event) ⇒ Object
118 119 120 121 122 123 124 125 126 |
# File 'lib/termtter/client.rb', line 118 def do_hooks(statuses, event) @@hooks.each do |h| begin h.call(statuses.dup, event, Termtter::API.twitter) rescue => e handle_error(e) end end end |
.exit ⇒ Object
199 200 201 202 203 204 205 206 207 |
# File 'lib/termtter/client.rb', line 199 def exit puts 'finalizing...' call_hooks([], :exit) call_new_hooks(:exit) @@task_manager.kill @@main_thread.kill if @@main_thread @@input_thread.kill if @@input_thread end |
.find_filter_candidates(a, b, filters) ⇒ Object
49 50 51 52 53 54 55 56 |
# File 'lib/plugin/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
19 20 21 22 23 |
# File 'lib/plugin/group.rb', line 19 def self.find_group_candidates(a, b) configatron.plugins.group.groups.keys.map {|k| k.to_s}. grep(/^#{Regexp.quote a}/). map {|u| b % u } end |
.find_plugin_candidates(a, b) ⇒ Object
38 39 40 41 42 |
# File 'lib/plugin/plugin.rb', line 38 def self.find_plugin_candidates(a, b) public_storage[:plugins]. grep(/^#{Regexp.quote a}/i). map {|u| b % u } end |
.find_status_id_candidates(a, b, u = nil) ⇒ Object
231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/plugin/standard_plugins.rb', line 231 def self.find_status_id_candidates(a, b, u = nil) candidates = public_storage[:status_ids].to_a if u && c = public_storage[:log].select {|s| s.user_screen_name == u }.map {|s| s.id.to_s } candidates = c unless c.empty? end if a.empty? candidates else candidates.grep(/#{Regexp.quote a}/) end. map {|u| b % u } end |
.find_user_candidates(a, b) ⇒ Object
244 245 246 247 248 249 250 251 |
# File 'lib/plugin/standard_plugins.rb', line 244 def self.find_user_candidates(a, b) if a.nil? || a.empty? public_storage[:users].to_a else public_storage[:users].grep(/^#{Regexp.quote a}/i) end. map {|u| b % u } end |
.formatted_help(helps) ⇒ Object
207 208 209 210 211 212 213 214 |
# File 'lib/plugin/standard_plugins.rb', line 207 def self.formatted_help(helps) helps = helps.sort_by{|help| help[0]} width = helps.map {|n, d| n.size }.max space = 3 helps.map {|name, desc| name.to_s.ljust(width + space) + desc.to_s }.join("\n") end |
.get_command(name) ⇒ Object
82 83 84 |
# File 'lib/termtter/client.rb', line 82 def get_command(name) @@new_commands[name] end |
.get_hook(name) ⇒ Object
60 61 62 |
# File 'lib/termtter/client.rb', line 60 def get_hook(name) @@new_hooks[name] end |
.get_hooks(point) ⇒ Object
64 65 66 67 68 |
# File 'lib/termtter/client.rb', line 64 def get_hooks(point) @@new_hooks.values.select do |hook| hook.match?(point) end end |
.handle_error(e) ⇒ Object
380 381 382 383 384 385 |
# File 'lib/termtter/client.rb', line 380 def handle_error(e) call_new_hooks("on_error", e) rescue => e puts "Error: #{e}" puts e.backtrace.join("\n") end |
.init ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/termtter/client.rb', line 10 def init @@hooks = [] @@new_hooks = {} @@commands = {} @@new_commands = {} @@completions = [] @@filters = [] @@helps = [] @@since_id = nil @@main_thread = nil @@input_thread = nil @@task_manager = Termtter::TaskManager.new configatron.set_default(:update_interval, 300) configatron.set_default(:prompt, '> ') configatron.set_default(:enable_ssl, false) configatron.proxy.set_default(:port, '8080') Thread.abort_on_exception = true end |
.input_editor ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/plugin/update_editor.rb', line 14 def self.input_editor file = Tempfile.new('termtter') editor = configatron.plugins.update_editor.editor if configatron.plugins.update_editor.add_completion file.puts "\n"*100 + "__END__\n" + public_storage[:users].to_a.join(' ') end file.close system("#{editor} #{file.path}") result = file.open.read file.close(false) result end |
.load_config ⇒ Object
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 250 251 252 253 254 255 |
# File 'lib/termtter/client.rb', line 218 def load_config conf_file = File.('~/.termtter') if File.exist? conf_file wrap_require do load conf_file end else ui = create_highline username = ui.ask('your twitter username: ') password = ui.ask('your twitter password: ') { |q| q.echo = false } File.open(File.('~/.termtter'), 'w') {|io| plugins = Dir.glob(File.dirname(__FILE__) + "/../lib/plugin/*.rb").map {|f| f.match(%r|lib/plugin/(.*?).rb$|)[1] } plugins -= %w[stdout standard_plugins] plugins.each do |p| io.puts "#plugin '#{p}'" end io.puts io.puts "configatron.user_name = '#{username}'" io.puts "configatron.password = '#{password}'" io.puts "#configatron.update_interval = 120" io.puts "#configatron.proxy.host = 'proxy host'" io.puts "#configatron.proxy.port = '8080'" io.puts "#configatron.proxy.user_name = 'proxy user'" io.puts "#configatron.proxy.password = 'proxy password'" io.puts io.puts "# vim: set filetype=ruby" } puts "generated: ~/.termtter" puts "enjoy!" wrap_require do load conf_file end end end |
.load_default_plugins ⇒ Object
209 210 211 212 213 214 215 216 |
# File 'lib/termtter/client.rb', line 209 def load_default_plugins plugin 'standard_plugins' plugin 'stdout' configatron.set_default(:devel, false) if configatron.devel plugin 'devel' end end |
.load_history ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/plugin/history.rb', line 17 def self.load_history filename = File.(configatron.plugins.history.filename) keys = configatron.plugins.history.keys if File.exist?(filename) begin history = Marshal.load Zlib::Inflate.inflate(File.read(filename)) 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 |
.open_uri(uri) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/plugin/uri-open.rb', line 14 def self.open_uri(uri) unless configatron.plugins.uri_open.browser.nil? system configatron.plugins.uri_open.browser, uri else case RUBY_PLATFORM when /linux/ system 'firefox', uri when /mswin(?!ce)|mingw|bccwin/ system 'explorer', uri else system 'open', uri end end end |
.pause ⇒ Object
187 188 189 |
# File 'lib/termtter/client.rb', line 187 def pause @@task_manager.pause end |
.print_statuses(statuses, sort = true, time_format = '%H:%M:%S') ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/plugin/stdout.rb', line 27 def self.print_statuses(statuses, sort = true, time_format = '%H:%M:%S') (sort ? statuses.sort_by{ |s| s.id} : statuses).each do |s| text = s.text status_color = configatron.plugins.stdout.colors[s.user_screen_name.hash % configatron.plugins.stdout.colors.size] status = "#{s.user_screen_name}: #{text}" if s.in_reply_to_status_id status += " (reply to #{s.in_reply_to_status_id})" end time = "(#{s.created_at.strftime(time_format)})" id = s.id erbed_text = ERB.new(configatron.plugins.stdout.timeline_format).result(binding) puts TermColor.parse(erbed_text) end end |
.print_statuses_with_date(statuses, sort = true) ⇒ Object
43 44 45 |
# File 'lib/plugin/stdout.rb', line 43 def self.print_statuses_with_date(statuses, sort = true) print_statuses(statuses, sort, '%m-%d %H:%M') end |
.public_storage ⇒ Object
29 30 31 |
# File 'lib/termtter/client.rb', line 29 def public_storage @@public_storage ||= {} end |
.register_command(arg) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/termtter/client.rb', line 70 def register_command(arg) command = case arg when Command arg when Hash Command.new(arg) else raise ArgumentError, 'must be given Termtter::Command or Hash' end @@new_commands[command.name] = command end |
.register_hook(arg) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/termtter/client.rb', line 48 def register_hook(arg) hook = case arg when Hook arg when Hash Hook.new(arg) else raise ArgumentError, 'must be given Termtter::Hook or Hash' end @@new_hooks[hook.name] = hook end |
.register_macro(name, macro, options = {}) ⇒ Object
86 87 88 89 90 91 92 |
# File 'lib/termtter/client.rb', line 86 def register_macro(name, macro, = {}) command = { :name => name.to_sym, :exec_proc => lambda {|arg| call_commands(macro % arg)} }.merge() register_command(command) end |
.resume ⇒ Object
191 192 193 |
# File 'lib/termtter/client.rb', line 191 def resume @@task_manager.resume end |
.run ⇒ Object
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/termtter/client.rb', line 334 def run puts 'initializing...' load_default_plugins() load_config() Termtter::API.setup() call_hooks([], :initialize) call_new_hooks(:initialize) setup_update_timeline_task() call_commands('_update_timeline') @@task_manager.run() start_input_thread() end |
.save_history ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/plugin/history.rb', line 35 def self.save_history filename = File.(configatron.plugins.history.filename) keys = configatron.plugins.history.keys history = { } keys.each do |key| history[key] = public_storage[key] end max_of_history = configatron.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/plugin/scrape.rb', line 14 def self.scrape_group(group) members = configatron.plugins.group.groups[group] || [] scrape_members(members) end |
.scrape_members(members) ⇒ Object
5 6 7 8 9 10 11 12 |
# File 'lib/plugin/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.get_user_timeline(member) end statuses end |
.setup_readline ⇒ Object
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/termtter/client.rb', line 257 def setup_readline if Readline.respond_to?(:basic_word_break_characters=) Readline.basic_word_break_characters= "\t\n\"\\'`><=;|&{(" end Readline.completion_proc = lambda {|input| begin # FIXME: when migrate to Termtter::Command completions = @@completions.map {|completion| completion.call(input) } completions += @@new_commands.map {|name, command| command.complement(input) } completions.flatten.compact rescue => e handle_error(e) end } vi_or_emacs = configatron.editing_mode unless vi_or_emacs.empty? Readline.__send__("#{vi_or_emacs}_editing_mode") end end |
.setup_update_timeline_task ⇒ Object
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
# File 'lib/termtter/client.rb', line 281 def setup_update_timeline_task() register_command( :name => :_update_timeline, :exec_proc => lambda {|arg| begin statuses = Termtter::API.twitter.get_friends_timeline(@@since_id) unless statuses.empty? @@since_id = statuses[0].id end print "\e[1K\e[0G" if !statuses.empty? && !win? call_hooks(statuses, :update_friends_timeline) @@input_thread.kill if @@input_thread && !statuses.empty? rescue OpenURI::HTTPError => e if e. == '401 Unauthorized' puts 'Could not login' puts 'plese check your account settings' exit! end end } ) add_task(:name => :update_timeline, :interval => configatron.update_interval) do call_commands('_update_timeline') end end |
.start_input_thread ⇒ Object
322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/termtter/client.rb', line 322 def start_input_thread setup_readline() trap_setting() @@main_thread = Thread.new do loop do @@input_thread = create_input_thread() @@input_thread.join end end @@main_thread.join end |
.trap_setting ⇒ Object
308 309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/termtter/client.rb', line 308 def trap_setting() begin stty_save = `stty -g`.chomp trap("INT") do begin system "stty", stty_save ensure exit end end rescue Errno::ENOENT end end |
.wrap_require ⇒ Object
387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'lib/termtter/client.rb', line 387 def wrap_require # FIXME: delete this method after the major version up alias original_require require def require(s) if %r|^termtter/(.*)| =~ s puts "[WARNING] use plugin '#{$1}' instead of require" puts " Such a legacy .termtter file will not be supported until version 1.0.0" s = "plugin/#{$1}" end original_require s end yield alias require original_require end |
Instance Method Details
#require(s) ⇒ Object
390 391 392 393 394 395 396 397 |
# File 'lib/termtter/client.rb', line 390 def require(s) if %r|^termtter/(.*)| =~ s puts "[WARNING] use plugin '#{$1}' instead of require" puts " Such a legacy .termtter file will not be supported until version 1.0.0" s = "plugin/#{$1}" end original_require s end |