termtter 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/History.txt +4 -0
  2. data/README.rdoc +97 -0
  3. data/Rakefile +46 -0
  4. data/bin/kill_termtter +22 -0
  5. data/bin/termtter +7 -0
  6. data/lib/filter/en2ja.rb +11 -0
  7. data/lib/filter/english.rb +8 -0
  8. data/lib/filter/expand-tinyurl.rb +24 -0
  9. data/lib/filter/fib.rb +15 -0
  10. data/lib/filter/ignore.rb +19 -0
  11. data/lib/filter/reply.rb +8 -0
  12. data/lib/filter/reverse.rb +13 -0
  13. data/lib/filter/url_addspace.rb +16 -0
  14. data/lib/filter/yhara.rb +20 -0
  15. data/lib/plugin/april_fool.rb +15 -0
  16. data/lib/plugin/bomb.rb +29 -0
  17. data/lib/plugin/clear.rb +14 -0
  18. data/lib/plugin/confirm.rb +9 -0
  19. data/lib/plugin/cool.rb +10 -0
  20. data/lib/plugin/devel.rb +13 -0
  21. data/lib/plugin/english.rb +59 -0
  22. data/lib/plugin/erb.rb +17 -0
  23. data/lib/plugin/favorite.rb +75 -0
  24. data/lib/plugin/fib.rb +8 -0
  25. data/lib/plugin/filter.rb +69 -0
  26. data/lib/plugin/follow.rb +56 -0
  27. data/lib/plugin/graduatter.rb +9 -0
  28. data/lib/plugin/grass.rb +27 -0
  29. data/lib/plugin/group.rb +60 -0
  30. data/lib/plugin/growl.rb +62 -0
  31. data/lib/plugin/hatebu.rb +59 -0
  32. data/lib/plugin/history.rb +82 -0
  33. data/lib/plugin/keyword.rb +18 -0
  34. data/lib/plugin/log.rb +63 -0
  35. data/lib/plugin/modify_arg_hook_sample.rb +7 -0
  36. data/lib/plugin/msagent.rb +26 -0
  37. data/lib/plugin/multi_reply.rb +36 -0
  38. data/lib/plugin/notify-send.rb +17 -0
  39. data/lib/plugin/otsune.rb +21 -0
  40. data/lib/plugin/outputz.rb +35 -0
  41. data/lib/plugin/pause.rb +3 -0
  42. data/lib/plugin/plugin.rb +53 -0
  43. data/lib/plugin/post_exec_hook_sample.rb +9 -0
  44. data/lib/plugin/pre_exec_hook_sample.rb +9 -0
  45. data/lib/plugin/primes.rb +23 -0
  46. data/lib/plugin/quicklook.rb +38 -0
  47. data/lib/plugin/reblog.rb +40 -0
  48. data/lib/plugin/reload.rb +3 -0
  49. data/lib/plugin/say.rb +24 -0
  50. data/lib/plugin/scrape.rb +41 -0
  51. data/lib/plugin/screen.rb +24 -0
  52. data/lib/plugin/shell.rb +14 -0
  53. data/lib/plugin/sl.rb +48 -0
  54. data/lib/plugin/spam.rb +9 -0
  55. data/lib/plugin/standard_plugins.rb +269 -0
  56. data/lib/plugin/stdout.rb +62 -0
  57. data/lib/plugin/system_status.rb +33 -0
  58. data/lib/plugin/translation.rb +28 -0
  59. data/lib/plugin/update_editor.rb +53 -0
  60. data/lib/plugin/uri-open.rb +69 -0
  61. data/lib/plugin/wassr_post.rb +22 -0
  62. data/lib/plugin/yhara.rb +148 -0
  63. data/lib/plugin/yonda.rb +20 -0
  64. data/lib/termtter/api.rb +14 -0
  65. data/lib/termtter/client.rb +399 -0
  66. data/lib/termtter/command.rb +77 -0
  67. data/lib/termtter/connection.rb +39 -0
  68. data/lib/termtter/hook.rb +18 -0
  69. data/lib/termtter/status.rb +26 -0
  70. data/lib/termtter/task.rb +16 -0
  71. data/lib/termtter/task_manager.rb +116 -0
  72. data/lib/termtter/twitter.rb +173 -0
  73. data/lib/termtter/user.rb +13 -0
  74. data/lib/termtter/version.rb +3 -0
  75. data/lib/termtter.rb +157 -0
  76. data/spec/plugin/cool_spec.rb +10 -0
  77. data/spec/plugin/fib_spec.rb +16 -0
  78. data/spec/plugin/filter_spec.rb +18 -0
  79. data/spec/plugin/plugin_spec.rb +25 -0
  80. data/spec/plugin/shell_spec.rb +10 -0
  81. data/spec/plugin/spam_spec.rb +17 -0
  82. data/spec/plugin/standard_plugins_spec.rb +31 -0
  83. data/spec/spec_helper.rb +4 -0
  84. data/spec/termtter/client_spec.rb +175 -0
  85. data/spec/termtter/command_spec.rb +161 -0
  86. data/spec/termtter/task_manager_spec.rb +78 -0
  87. data/spec/termtter/task_spec.rb +22 -0
  88. data/spec/termtter/user_spec.rb +27 -0
  89. data/spec/termtter_spec.rb +43 -0
  90. data/test/friends_timeline.json +5 -0
  91. data/test/search.json +8 -0
  92. data/test/test_termtter.rb +86 -0
  93. metadata +177 -0
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-12-26
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/README.rdoc ADDED
@@ -0,0 +1,97 @@
1
+ = termtter
2
+
3
+ http://github.com/jugyo/termtter
4
+
5
+ == DESCRIPTION:
6
+
7
+ Termtter is a terminal based Twitter client
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ == SYNOPSIS:
12
+
13
+ Run:
14
+
15
+ termtter
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * json
20
+ * configatron
21
+
22
+ == INSTALL:
23
+
24
+ sudo gem source -a http://gems.github.com (you only have to do this once)
25
+ sudo gem install jugyo-termtter
26
+
27
+ if you want to install gem package from source code, install like following.
28
+
29
+ git clone git://github.com/jugyo/termtter.git
30
+ cd termtter
31
+ rake manifest
32
+ rake gemspec
33
+ gem build termtter.gemspec
34
+ gem install *.gem
35
+
36
+ Just run a new command termtter.
37
+
38
+ termtter
39
+
40
+ Termtter generates a configuration file named '.termtter' in your HOME directory.
41
+ You can edit the file anytime.
42
+
43
+ vim ~/.termtter
44
+
45
+ configatron.user_name = 'USERNAME'
46
+ configatron.password = 'PASSWORD'
47
+
48
+ If you would like to use proxy server, add configurations like this:
49
+
50
+ configatron.proxy.host = 'PROXYHOST'
51
+ configatron.proxy.port = 'PROXYPORT'
52
+ configatron.proxy.user_name = 'USERNAME'
53
+ configatron.proxy.password = 'PASSWORD'
54
+
55
+ To update the config, just restart your termtter proccess.
56
+
57
+ == FORUM:
58
+
59
+ http://www.lingr.com/room/termtter
60
+
61
+ == DOCUMENT:
62
+
63
+ http://wiki.github.com/jugyo/termtter/home (in Japanese)
64
+
65
+ == TODO:
66
+
67
+ - newgem を使わないようにする
68
+ - rubytter を使うようにする
69
+ - filter と plugin を統一する
70
+ - plugin => plugins (ディレクトリ名変更)
71
+ - $HOME 以下に plugin 用のディレクトリを置けるようにする
72
+ - コマンドラインオプションでいろいろ指定できるようにする
73
+
74
+ == LICENSE:
75
+
76
+ (The MIT License)
77
+
78
+ Copyright (c) 2008-2009 The Termtter Development Team
79
+
80
+ Permission is hereby granted, free of charge, to any person obtaining
81
+ a copy of this software and associated documentation files (the
82
+ 'Software'), to deal in the Software without restriction, including
83
+ without limitation the rights to use, copy, modify, merge, publish,
84
+ distribute, sublicense, and/or sell copies of the Software, and to
85
+ permit persons to whom the Software is furnished to do so, subject to
86
+ the following conditions:
87
+
88
+ The above copyright notice and this permission notice shall be
89
+ included in all copies or substantial portions of the Software.
90
+
91
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
92
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
93
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
94
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
95
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
96
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
97
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ $:.unshift File.dirname(__FILE__) + '/lib'
2
+ require 'termtter'
3
+
4
+ require 'spec/rake/spectask'
5
+ desc 'run all specs'
6
+ Spec::Rake::SpecTask.new do |t|
7
+ t.spec_files = FileList['spec/**/*_spec.rb']
8
+ t.spec_opts = ['-c']
9
+ end
10
+
11
+ desc 'Generate gemspec'
12
+ task :gemspec do |t|
13
+ open('termtter.gemspec', "wb" ) do |file|
14
+ file << <<-EOS
15
+ Gem::Specification.new do |s|
16
+ s.name = 'termtter'
17
+ s.version = '#{Termtter::VERSION}'
18
+ s.summary = "Terminal based Twitter client"
19
+ s.description = "Termtter is a terminal based Twitter client"
20
+ s.files = %w( #{Dir['lib/**/*.rb'].join(' ')}
21
+ #{Dir['spec/**/*.rb'].join(' ')}
22
+ #{Dir['test/**/*.rb', 'test/**/*.json'].join(' ')}
23
+ README.rdoc
24
+ History.txt
25
+ Rakefile )
26
+ s.executables = ["kill_termtter", "termtter"]
27
+ s.add_dependency("json_pure", ">= 1.1.3")
28
+ s.add_dependency("configatron", ">= 2.2.2")
29
+ s.add_dependency("highline", ">= 1.5.0")
30
+ s.authors = %w(jugyo ujihisa)
31
+ s.email = 'jugyo.org@gmail.com'
32
+ s.homepage = 'http://wiki.github.com/jugyo/termtter'
33
+ s.rubyforge_project = 'termtter'
34
+ s.has_rdoc = true
35
+ s.rdoc_options = ["--main", "README.rdoc", "--exclude", "spec"]
36
+ s.extra_rdoc_files = ["README.rdoc", "History.txt"]
37
+ end
38
+ EOS
39
+ end
40
+ puts "Generate gemspec"
41
+ end
42
+
43
+ desc 'Generate gem'
44
+ task :gem => :gemspec do |t|
45
+ system 'gem', 'build', 'termtter.gemspec'
46
+ end
data/bin/kill_termtter ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # If your termtter can't be exited, you might use this script.
3
+ #
4
+ # > exit
5
+ # (no response...)
6
+ # C-z
7
+ # $ kill_termtter -i
8
+ # y
9
+ #
10
+ # OPTION
11
+ # -i interactive
12
+ def s(a)
13
+ puts a
14
+ system a
15
+ end
16
+
17
+ `ps`.map(&:split).map {|i|
18
+ pid, runner, file = i[0], i[4], i[5]
19
+ if runner == 'ruby' && $$ != pid.to_i && /termtter/ =~ file
20
+ s "kill -KILL #{pid}"
21
+ end
22
+ }
data/bin/termtter ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $KCODE = 'u'
4
+
5
+ require 'rubygems'
6
+ require 'termtter'
7
+ Termtter::Client.run
@@ -0,0 +1,11 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ plugin 'translation'
4
+
5
+ Termtter::Client.add_filter do |statuses|
6
+ statuses.each do |s|
7
+ if s.english?
8
+ s.text = translate(s.text, 'en|ja')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::Client.add_filter do |statuses|
4
+ statuses.select{|s| s.english? }
5
+ end
6
+
7
+ # filter-english.rb
8
+ # select English post only
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ add_filter do |statuses|
5
+ statuses.each do |s|
6
+ s.text.gsub!(%r'(http://tinyurl\.com(/[\w/]+))') do |m|
7
+ expand_tinyurl($2) || $1
8
+ end
9
+ end
10
+ statuses
11
+ end
12
+ end
13
+
14
+ def expand_tinyurl(path)
15
+ http_class = Net::HTTP
16
+ unless configatron.proxy.host.empty?
17
+ http_class = Net::HTTP::Proxy(configatron.proxy.host,
18
+ configatron.proxy.port,
19
+ configatron.proxy.user_name,
20
+ configatron.proxy.password)
21
+ end
22
+ res = http_class.new('tinyurl.com').head(path)
23
+ res['Location']
24
+ end
data/lib/filter/fib.rb ADDED
@@ -0,0 +1,15 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ def fib(n)i=0;j=1;n.times{j=i+i=j};i end
4
+ module Termtter::Client
5
+ add_filter do |statuses|
6
+ statuses.each do |s|
7
+ s.text.gsub!(/(\d+)/) do |m|
8
+ n = $1.to_i
9
+ n < 1000000000 ? fib(n) : n # not to calc fib(id)
10
+ end
11
+ end
12
+ statuses
13
+ end
14
+ end
15
+
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ configatron.filters.ignore.set_default(:words, [])
5
+
6
+ module Termtter::Client
7
+ add_filter do |statuses|
8
+ ignore_words = configatron.filters.ignore.words
9
+ statuses.delete_if do |s|
10
+ ignore_words.any? {|i| i =~ s.text }
11
+ end
12
+ end
13
+ end
14
+
15
+ # filter/ignore.rb
16
+ # ignore words
17
+ # setting
18
+ # configatron.filters.ignore.words = [ /ignore/, /words/ ]
19
+
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::Client.add_filter do |statuses|
4
+ statuses.select{|s| s.text =~ /@/ }
5
+ end
6
+
7
+ # filter-reply.rb
8
+ # select @ reply post only
@@ -0,0 +1,13 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ add_filter do |statuses|
5
+ statuses.map do |s|
6
+ s.text = s.text.split(//).reverse.to_s
7
+ s
8
+ end
9
+ end
10
+ end
11
+
12
+ # filter-reverse.rb
13
+ # reverse texts
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ add_filter do |statuses|
5
+ statuses.each do |s|
6
+ s.text.gsub!(/(\S)(https?:\/\/)/, '\1 \2')
7
+ end
8
+ statuses
9
+ end
10
+ end
11
+
12
+ # url_addspace
13
+ # add space before URL without space
14
+ # example:
15
+ # before: ABCDEhttp://~~~
16
+ # after: ABCDE http://~~~
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter
4
+
5
+ class Status
6
+ def yharian?
7
+ self.text =~ /^(?:\s|(y\s)|(?:hara\s))+\s*(?:y|(?:hara))(?:\?|!|\.)?\s*$/
8
+ end
9
+ end
10
+
11
+ module Client
12
+ add_filter do |statuses|
13
+ statuses.select{|s| s.yharian? }
14
+ end
15
+ end
16
+ end
17
+
18
+ # filter-yhara.rb
19
+ # select Yharian post only
20
+
@@ -0,0 +1,15 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ def april_fool?;true;end
4
+ def april_fool;april_fool? ? "今日はエイプリルフールではありません。" : "今日はエイプリルフールです。";end
5
+
6
+ Termtter::Client.register_command(
7
+ :name => :april_fool, :aliases => [:af],
8
+ :exec_proc => lambda {|arg|
9
+ if arg =~ /^\?you\s(\w+)/
10
+ puts "=> #{Termtter::Client.update_status("@#{$1} #{april_fool}")}"
11
+ else
12
+ puts "=> #{Termtter::Client.update_status(april_fool)}"
13
+ end
14
+ }
15
+ )
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter
4
+ class Status
5
+ def bomb?
6
+ /爆発|bomb/ =~ self.text
7
+ end
8
+ end
9
+
10
+ module Client
11
+ register_command(
12
+ :name => :bomb, :aliases => [],
13
+ :exec_proc => lambda {|arg|
14
+ text = "#{arg.strip} 爆発しろ!"
15
+ Termtter::API::twitter.update_status(text)
16
+ puts "=> #{text}"
17
+ },
18
+ :help => ['bomb WORD', 'Bomb it']
19
+ )
20
+ end
21
+ end
22
+
23
+ # bomb.rb
24
+ # Bomb it!
25
+ #
26
+ # See http://gyazo.com/4b33517380673d92f51a52e675ecdb02.png .
27
+ # configatron.plugins.stdout.timeline_format =
28
+ # '<%= color(time, 90) %> <%= s.bomb? ? color(color(status, 41), 37) : color(status, status_color) %> <%= color(id, 90) %>'
29
+ # vim: fenc=utf8
@@ -0,0 +1,14 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ register_command :name => :clear, :aliases => [:cls],
5
+ :help => ['clear,cls', "Clear termtter's buffer"],
6
+ :exec_proc => lambda {|args|
7
+ system 'clear'
8
+ }
9
+ end
10
+
11
+ # todo:
12
+ # support windows.
13
+ # i don't have windows machine and cannot test:P
14
+ # cls command?
@@ -0,0 +1,9 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::Client.register_hook(
4
+ :name => :confirm,
5
+ :points => [:pre_exec_update],
6
+ :exec_proc => lambda {|cmd, arg|
7
+ false if arg.empty? || /^y?$/i !~ Readline.readline("update? #{arg} [Y/n] ", false)
8
+ }
9
+ )
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ register_macro(:cool, "update @%s cool.",
5
+ :help => ['cool {SCREENNAME}', 'update "@{SCREENNAME} cool."'],
6
+ :completion_proc => lambda {|cmd, args|
7
+ find_user_candidates args, "#{cmd} %s"
8
+ }
9
+ )
10
+ end
@@ -0,0 +1,13 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ register_command(
5
+ :name => :eval,
6
+ :aliases => [],
7
+ :exec_proc => lambda {|arg|
8
+ result = eval(arg) unless arg.empty?
9
+ puts "=> #{result.inspect}"
10
+ },
11
+ :help => ['eval EXPR', 'evaluate expression']
12
+ )
13
+ end
@@ -0,0 +1,59 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'erb'
4
+
5
+ module Termtter
6
+ Client.clear_hooks # FIXME: not to clear all but to clear just stdout.rb
7
+
8
+ configatron.set_default(
9
+ :timeline_format,
10
+ '<%= color(time, 90) %> <%= color(status, status_color) %> <%= color(id, 90) %>')
11
+
12
+ def color(str, num)
13
+ "\e[#{num}m#{str}\e[0m"
14
+ end
15
+
16
+ # FIXME: The code below is a copy from stdout.rb so it's not DRY. DRY it.
17
+
18
+ Client.add_hook do |statuses, event|
19
+ colors = %w(0 31 32 33 34 35 36 91 92 93 94 95 96)
20
+
21
+ case event
22
+ when :update_friends_timeline, :list_friends_timeline, :list_user_timeline, :show, :replies
23
+ unless statuses.empty?
24
+ statuses.reverse! if event == :update_friends_timeline
25
+ statuses.each do |s|
26
+ text = s.text.gsub("\n", '')
27
+ next unless Status.english?(text) # if you substitute "if" for "unless", this script will be "japanese.rb"
28
+ status_color = colors[s.user_screen_name.hash % colors.size]
29
+ status = "#{s.user_screen_name}: #{text}"
30
+ if s.in_reply_to_status_id
31
+ status += " (reply to #{s.in_reply_to_status_id})"
32
+ end
33
+
34
+ time_format = case event
35
+ when :update_friends_timeline, :list_friends_timeline
36
+ '%H:%M:%S'
37
+ else
38
+ '%m-%d %H:%M'
39
+ end
40
+ time = "(#{s.created_at.strftime(time_format)})"
41
+
42
+ id = s.id
43
+
44
+ puts ERB.new(configatron.timeline_format).result(binding)
45
+ end
46
+ end
47
+ when :search
48
+ statuses.each do |s|
49
+ text = s.text.gsub("\n", '')
50
+ status_color = colors[s.user_screen_name.hash % colors.size]
51
+
52
+ status = "#{s.user_screen_name}: #{text}"
53
+ time = "(#{s.created_at.strftime('%m-%d %H:%M')})"
54
+ id = s.id
55
+ puts ERB.new(configatron.timeline_format).result(binding)
56
+ end
57
+ end
58
+ end
59
+ end
data/lib/plugin/erb.rb ADDED
@@ -0,0 +1,17 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'erb'
4
+
5
+ Termtter::Client.register_hook(
6
+ :name => :erb,
7
+ :points => [:pre_exec_update],
8
+ :exec_proc => lambda {|cmd, arg|
9
+ ERB.new(arg).result(binding)
10
+ }
11
+ )
12
+
13
+ # erb.rb
14
+ # enable to <%= %> in the command update
15
+ # example:
16
+ # > u erb test <%= 1+1 %>
17
+ # => erb test 2
@@ -0,0 +1,75 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ add_help 'favorite,fav ID', 'Favorite a status'
5
+
6
+ add_command %r'^(?:favorite|fav)\s+(\d+)\s*$' do |m, t|
7
+ id = m[1]
8
+ res = t.favorite(id)
9
+ if res.code == '200'
10
+ puts "Favorited status ##{id}"
11
+ else
12
+ puts "Failed: #{res}"
13
+ end
14
+ end
15
+
16
+ add_help 'favorite,fav USER', 'Favorite last status on the user'
17
+
18
+ add_command %r'^(?:favorite|fav)\s+@(.+)\s*$' do |m, t|
19
+ user = m[1].strip
20
+ statuses = t.get_user_timeline(user)
21
+ unless statuses.empty?
22
+ id = statuses[0].id
23
+ text = statuses[0].text
24
+ res = t.favorite(id)
25
+ if res.code == '200'
26
+ puts %Q(Favorited last status ##{id} on user @#{user}: "#{text}")
27
+ else
28
+ puts "Failed: #{res}"
29
+ end
30
+ end
31
+ end
32
+
33
+ if public_storage[:log]
34
+ add_help 'favorite,fav /WORD', 'Favorite a status by searching'
35
+
36
+ add_command %r'^(?:favorite|fav)\s+/(.+)$' do |m, t|
37
+ pat = Regexp.new(m[1])
38
+ statuses = public_storage[:log].select {|s| pat =~ s.text }
39
+ if statuses.size == 1
40
+ status = statuses.first
41
+ res = t.favorite(status.id)
42
+ if res.code == '200'
43
+ puts %Q(Favorited "#{status.user_screen_name}: #{status.text}")
44
+ else
45
+ puts "Failed: #{res}"
46
+ end
47
+ else
48
+ puts "#{pat} does not match single status"
49
+ end
50
+ end
51
+ end
52
+
53
+ add_completion do |input|
54
+ case input
55
+ when /^(favorite|fav)\s+@(.*)/
56
+ find_user_candidates $2, "#{$1} @%s"
57
+ when /^(favorite|fav)\s+(\d*)/
58
+ find_status_id_candidates $2, "#{$1} %s"
59
+ else
60
+ %w(favorite).grep(/^#{Regexp.quote input}/)
61
+ end
62
+ end
63
+ end
64
+
65
+ module Termtter
66
+ class Twitter
67
+ def favorite(id)
68
+ uri = "#{@connection.protocol}://twitter.com/favourings/create/#{id}.json"
69
+
70
+ @connection.start('twitter.com', @connection.port) do |http|
71
+ http.request(post_request(uri))
72
+ end
73
+ end
74
+ end
75
+ end
data/lib/plugin/fib.rb ADDED
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ def fib(n)i=0;j=1;n.times{j=i+i=j};i end
4
+ module Termtter::Client
5
+ add_command /^fib\s+(\d+)/ do|m,t|t.update_status x="fib(#{n=m[1].to_i}) = #{fib n}"
6
+ puts"=> #{x}"end
7
+ add_command /^fibyou\s(\w+)\s(\d+)/ do|m,t|puts"=> #{t.update_status("@#{m[1]} fib(#{n=m[2].to_i}) = #{fib n}")}"end end
8
+ # TODO: use add_macro
@@ -0,0 +1,69 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ module Termtter::Client
5
+ public_storage[:filters] = []
6
+ filters = Dir["#{File.dirname(__FILE__)}/../filter/*.rb"].map do |f|
7
+ f.match(%r|([^/]+).rb$|)[1]
8
+ end
9
+
10
+ register_command(
11
+ :name => :filter, :aliases => [],
12
+ :exec_proc => lambda {|arg|
13
+ begin
14
+ result = filter arg.strip
15
+ rescue LoadError
16
+ result = false
17
+ ensure
18
+ puts "=> #{result.inspect}"
19
+ end
20
+ },
21
+ :completion_proc => lambda {|cmd, args|
22
+ find_filter_candidates args, "#{cmd} %s", filters
23
+ },
24
+ :help => ['filter FILE', 'Apply a filter']
25
+ )
26
+
27
+ register_command(
28
+ :name => :unfilter, :aliases => [],
29
+ :exec_proc => lambda {|arg|
30
+ clear_filters
31
+ public_storage[:filters].clear
32
+ puts '=> filter cleared'
33
+ },
34
+ :help => ['ufilter', 'Clear all filters']
35
+ )
36
+
37
+ register_command(
38
+ :name => :filters, :aliases => [],
39
+ :exec_proc => lambda {|arg|
40
+ unless public_storage[:filters].empty?
41
+ puts public_storage[:filters].join(', ')
42
+ else
43
+ puts 'no filter was applied'
44
+ end
45
+ },
46
+ :help => ['filters', 'Show list of applied filters']
47
+ )
48
+
49
+ def self.find_filter_candidates(a, b, filters)
50
+ if a.empty?
51
+ filters.to_a
52
+ else
53
+ filters.grep(/^#{Regexp.quote a}/i)
54
+ end.
55
+ map {|u| b % u }
56
+ end
57
+ end
58
+
59
+ # filter.rb
60
+ # a dynamic filter loader
61
+ # example
62
+ # > list
63
+ # (15:49:00) termtter: こんにちは
64
+ # (15:48:02) termtter: hello
65
+ # > filter english
66
+ # => true
67
+ # > list
68
+ # (15:48:02) termtter: hello
69
+ # vim: fenc=utf8