termtter 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/Rakefile +1 -1
  2. data/lib/plugins/bomb.rb +9 -12
  3. data/lib/plugins/expand-tinyurl.rb +12 -3
  4. data/lib/plugins/group.rb +10 -6
  5. data/lib/plugins/history.rb +21 -10
  6. data/lib/plugins/log.rb +10 -10
  7. data/lib/plugins/msagent.rb +23 -11
  8. data/lib/plugins/notify-send.rb +17 -12
  9. data/lib/plugins/say.rb +8 -6
  10. data/lib/plugins/scrape.rb +1 -1
  11. data/lib/plugins/screen-notify.rb +17 -10
  12. data/lib/plugins/standard_plugins.rb +29 -17
  13. data/lib/plugins/stdout.rb +35 -54
  14. data/lib/plugins/storage.rb +17 -23
  15. data/lib/plugins/storage/status.rb +23 -20
  16. data/lib/plugins/update_editor.rb +1 -1
  17. data/lib/plugins/uri-open.rb +7 -5
  18. data/lib/plugins/url_addspace.rb +2 -2
  19. data/lib/termtter/api.rb +2 -1
  20. data/lib/termtter/client.rb +88 -108
  21. data/lib/termtter/command.rb +1 -0
  22. data/lib/termtter/hook.rb +5 -0
  23. data/lib/termtter/system_extensions.rb +13 -3
  24. data/lib/termtter/version.rb +1 -1
  25. data/spec/{plugin → plugins}/cool_spec.rb +0 -0
  26. data/spec/{plugin → plugins}/english_spec.rb +0 -0
  27. data/spec/{plugin → plugins}/favorite_spec.rb +0 -0
  28. data/spec/{plugin → plugins}/fib_spec.rb +0 -0
  29. data/spec/{plugin → plugins}/filter_spec.rb +0 -0
  30. data/spec/{plugin → plugins}/pause_spec.rb +0 -0
  31. data/spec/{plugin → plugins}/plugin_spec.rb +0 -0
  32. data/spec/{plugin → plugins}/primes_spec.rb +0 -0
  33. data/spec/{plugin → plugins}/shell_spec.rb +0 -0
  34. data/spec/{plugin → plugins}/sl_spec.rb +0 -0
  35. data/spec/{plugin → plugins}/spam_spec.rb +0 -0
  36. data/spec/{plugin → plugins}/standard_plugins_spec.rb +0 -0
  37. data/spec/{plugin → plugins}/storage/DB_spec.rb +0 -0
  38. data/spec/{plugin → plugins}/storage/status_spec.rb +1 -1
  39. data/spec/termtter/client_spec.rb +1 -4
  40. metadata +17 -17
data/Rakefile CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.add_dependency("json_pure", ">= 1.1.3")
27
27
  s.add_dependency("highline", ">= 1.5.0")
28
28
  s.add_dependency("termcolor", ">= 0.3.1")
29
- s.add_dependency("rubytter", ">= 0.4.8")
29
+ s.add_dependency("rubytter", ">= 0.5.0")
30
30
  s.add_dependency("sqlite3-ruby", ">= 1.2.4")
31
31
  s.authors = %w(jugyo ujihisa)
32
32
  s.email = 'jugyo.org@gmail.com'
data/lib/plugins/bomb.rb CHANGED
@@ -1,24 +1,21 @@
1
1
  # -*- coding: utf-8 -*-
2
+ require 'enumerator'
2
3
 
3
4
  module Termtter
4
-
5
5
  module Client
6
- config.plugins.bomb.color.set_default :foreground, 'white'
7
- config.plugins.bomb.color.set_default :background, 'red'
6
+ config.plugins.bomb.set_default :format, "<on_red><white>%s</white></on_red>"
8
7
 
9
- add_hook do |statuses, event|
10
- case event
11
- when :post_filter
12
- fg = config.plugins.bomb.color.foreground
13
- bg = config.plugins.bomb.color.background
14
- statuses = [statuses] unless statuses.instance_of? Array
8
+ register_hook(
9
+ :name => :bomb,
10
+ :points => [:post_filter],
11
+ :exec_proc => lambda{|statuses, event|
15
12
  statuses.each do |status|
16
13
  if /爆発|bomb/ =~ status.text
17
- status.text = "<on_#{bg}><#{fg}>#{status.text}</#{fg}></on_#{bg}>"
14
+ status.text = config.plugins.bomb.format % status.text
18
15
  end
19
16
  end
20
- end
21
- end
17
+ }
18
+ )
22
19
 
23
20
  register_command(
24
21
  :name => :bomb, :aliases => [],
@@ -1,17 +1,25 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ URL_SHORTTERS = [
4
+ { :host => "tinyurl.com", :pattern => %r'(http://tinyurl\.com(/[\w/]+))' },
5
+ { :host => "is.gd", :pattern => %r'(http://is\.gd(/[\w/]+))' },
6
+ # { :host => "bit.ly", :pattern => %r'(http://bit\.ly(/[\w/]+))' }
7
+ ]
8
+
3
9
  module Termtter::Client
4
10
  add_filter do |statuses, event|
5
11
  statuses.each do |s|
6
- s.text.gsub!(%r'(http://tinyurl\.com(/[\w/]+))') do |m|
7
- expand_tinyurl($2) || $1
12
+ URL_SHORTTERS.each do |site|
13
+ s[:text].gsub!(site[:pattern]) do |m|
14
+ expand_url(site[:host], $2) || $1
15
+ end
8
16
  end
9
17
  end
10
18
  statuses
11
19
  end
12
20
  end
13
21
 
14
- def expand_tinyurl(path)
22
+ def expand_url(host, path)
15
23
  http_class = Net::HTTP
16
24
  unless config.proxy.host.nil? or config.proxy.host.empty?
17
25
  http_class = Net::HTTP::Proxy(config.proxy.host,
@@ -20,5 +28,6 @@ def expand_tinyurl(path)
20
28
  config.proxy.password)
21
29
  end
22
30
  res = http_class.new('tinyurl.com').head(path)
31
+ return nil unless res.code == "301" or res.code == "302"
23
32
  res['Location']
24
33
  end
data/lib/plugins/group.rb CHANGED
@@ -22,6 +22,10 @@ module Termtter::Client
22
22
  map {|u| b % u }
23
23
  end
24
24
 
25
+ def self.get_group_of(screen_name)
26
+ config.plugins.group.groups.select{ |k, v| v.include? screen_name}.map{|a| a.first}
27
+ end
28
+
25
29
  register_command(
26
30
  :name => :group,
27
31
  :aliases => [:g],
@@ -29,14 +33,14 @@ module Termtter::Client
29
33
  unless arg.empty?
30
34
  group_name = arg.to_sym
31
35
  if group_name == :all
32
- group = config.plugins.group.groups.values.flatten.uniq
36
+ targets = config.plugins.group.groups.values.flatten.uniq
33
37
  else
34
- group = config.plugins.group.groups[group_name]
38
+ targets = config.plugins.group.groups[group_name]
35
39
  end
36
- statuses = group ? public_storage[:log].select { |s|
37
- group.include?(s.user.screen_name)
38
- } : []
39
- call_hooks(statuses, :search)
40
+ statuses = targets ? targets.map { |target|
41
+ public_storage[:tweet][target]
42
+ }.flatten.uniq.compact.sort_by{ |s| s[:id]} : []
43
+ output(statuses, :search)
40
44
  else
41
45
  config.plugins.group.groups.each_pair do |key, value|
42
46
  puts "#{key}: #{value.join(',')}"
@@ -3,9 +3,9 @@
3
3
  require 'zlib'
4
4
 
5
5
  config.plugins.history.
6
- set_default(:filename, '~/.termtter_history')
6
+ set_default(:filename, Termtter::CONF_DIR + '/history')
7
7
  config.plugins.history.
8
- set_default(:keys, [:log, :users, :status_ids])
8
+ set_default(:keys, [:users, :status_ids])
9
9
  config.plugins.history.
10
10
  set_default(:max_of_history, 100)
11
11
  config.plugins.history.
@@ -51,14 +51,17 @@ module Termtter::Client
51
51
  puts "history saved(#{File.size(filename)/1000}kb)"
52
52
  end
53
53
 
54
- add_hook do |statuses, event|
55
- case event
56
- when :initialize
57
- load_history
58
- when :exit
59
- save_history
60
- end
61
- end
54
+ register_hook(
55
+ :name => :history_initialize,
56
+ :points => [:initialize],
57
+ :exec_proc => lambda { load_history; logger.debug('load_history') }
58
+ )
59
+
60
+ register_hook(
61
+ :name => :history_exit,
62
+ :points => [:exit],
63
+ :exec_proc => lambda { save_history; logger.debug('save_history') }
64
+ )
62
65
 
63
66
  if config.plugins.history.enable_autosave
64
67
  Termtter::Client.add_task(:interval => config.plugins.history.autosave_interval,
@@ -75,6 +78,14 @@ module Termtter::Client
75
78
  :help => ['save', 'Save hisory']
76
79
  )
77
80
 
81
+ register_command(
82
+ :name => :load,
83
+ :exec_proc => lambda{|arg|
84
+ load_history
85
+ },
86
+ :help => ['load', 'Load hisory']
87
+ )
88
+
78
89
 
79
90
  end
80
91
 
data/lib/plugins/log.rb CHANGED
@@ -6,19 +6,19 @@ module Termtter::Client
6
6
  config.plugins.log.set_default('max_size', 1/0.0)
7
7
  config.plugins.log.set_default('print_max_size', 30)
8
8
 
9
- add_hook do |statuses, event|
10
- case event
11
- when :pre_filter
9
+ register_hook(
10
+ :name => :log,
11
+ :points => [:pre_filter],
12
+ :exec_proc => lambda {|statuses, event|
12
13
  # log(sequential storage)
13
14
  public_storage[:log] += statuses
14
15
  max_size = config.plugins.log.max_size
15
16
  if public_storage[:log].size > max_size
16
17
  public_storage[:log] = public_storage[:log][-max_size..-1]
17
18
  end
18
- public_storage[:log] = public_storage[:log].uniq.sort_by{|a| a.created_at} if statuses.first
19
+ public_storage[:log] = public_storage[:log].uniq.sort_by{|s| s.created_at} if statuses.first
19
20
 
20
21
  # tweet(storage for each user)
21
-
22
22
  statuses.each do |s|
23
23
  public_storage[:tweet][s.user.screen_name] = [] unless public_storage[:tweet][s.user.screen_name]
24
24
  public_storage[:tweet][s.user.screen_name] << s
@@ -26,8 +26,8 @@ module Termtter::Client
26
26
  public_storage[:tweet] = public_storage[:tweet][-max_size..-1]
27
27
  end
28
28
  end
29
- end
30
- end
29
+ }
30
+ )
31
31
 
32
32
  register_command(
33
33
  :name => :log,
@@ -37,7 +37,7 @@ module Termtter::Client
37
37
  statuses = public_storage[:log]
38
38
  print_max = config.plugins.log.print_max_size
39
39
  print_max = 0 if statuses.size < print_max
40
- call_hooks(statuses[-print_max..-1], :search)
40
+ output(statuses[-print_max..-1], :search)
41
41
  else
42
42
  # log (user) (max)
43
43
  vars = arg.split(' ')
@@ -45,7 +45,7 @@ module Termtter::Client
45
45
  id = vars
46
46
  statuses = id.first ? public_storage[:log].select{ |s| id.include? s.user.screen_name} : public_storage[:log]
47
47
  print_max = 0 if statuses.size < print_max
48
- call_hooks(statuses[-print_max..-1], :search)
48
+ output(statuses[-print_max..-1], :search)
49
49
  end
50
50
  },
51
51
  :completion_proc => lambda {|cmd, arg|
@@ -60,7 +60,7 @@ module Termtter::Client
60
60
  unless arg.strip.empty?
61
61
  pat = Regexp.new arg
62
62
  statuses = public_storage[:log].select { |s| s.text =~ pat }
63
- call_hooks(statuses, :search)
63
+ output(statuses, :search)
64
64
  end
65
65
  },
66
66
  :help => [ 'search_log WORD', 'Search log for WORD' ]
@@ -11,16 +11,28 @@ achar = agent.characters.character("Merlin")
11
11
  achar.languageID = 0x411
12
12
  achar.show
13
13
 
14
- Termtter::Client.add_hook do |statuses, event, t|
15
- if event == :exit
14
+ Termtter::Client.register_hook(
15
+ :name => :msagent,
16
+ :points => [:post_filter],
17
+ :exec_proc => lambda {|statuses, event|
18
+ if !statuses.empty? && event == :update_friends_timeline
19
+ Thread.start do
20
+ statuses.reverse.each do |s|
21
+ req = achar.speak("#{s[:screen_name]}: #{s[:post_text]}".tosjis)
22
+ sleep 1
23
+ WIN32OLE_EVENT.message_loop
24
+ achar.stop(req)
25
+ end
26
+ end
27
+ end
28
+ }
29
+ )
30
+
31
+ Termtter::Client.register_hook(
32
+ :name => :msagent_exit,
33
+ :points => [:exit],
34
+ :exec_proc => lambda {
16
35
  achar.hide
17
36
  GC.start
18
- elsif !statuses.empty? && event == :update_friends_timeline
19
- statuses.reverse.each do |s|
20
- req = achar.speak("#{s.user.screen_name}: #{s.text}".tosjis)
21
- sleep 3
22
- WIN32OLE_EVENT.message_loop
23
- achar.stop(req)
24
- end
25
- end
26
- end
37
+ }
38
+ )
@@ -1,17 +1,22 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- Termtter::Client.add_hook do |statuses, event|
4
- if !statuses.empty? && event == :update_friends_timeline
5
- max = 10
3
+ Termtter::Client.register_hook(
4
+ :name => :notify_send,
5
+ :points => [:post_filter],
6
+ :exec_proc => lambda {|statuses, event|
7
+ if event == :update_friends_timeline
8
+ max = 10
6
9
 
7
- text = statuses.take(max).map {|s|
8
- status_text = CGI.escapeHTML(s.text)
9
- status_text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
10
- "<b>#{s.user.screen_name}:</b> <span font=\"9.0\">#{status_text}</span>"
11
- }.join("\n")
10
+ text = statuses.take(max).map {|s|
11
+ status_text = CGI.escapeHTML(s[:post_text])
12
+ status_text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
13
+ "<b>#{s[:screen_name]}:</b> <span font=\"9.0\">#{status_text}</span>"
14
+ }.join("\n")
12
15
 
13
- text << %Q|\n<a href="http://twitter.com/">more...</a>| if statuses.size > max
16
+ text << %Q|\n<a href="http://twitter.com/">more...</a>| if statuses.size > max
17
+
18
+ system 'notify-send', 'Termtter', text, '-t', '60000'
19
+ end
20
+ }
21
+ )
14
22
 
15
- system 'notify-send', 'Termtter', text, '-t', '60000'
16
- end
17
- end
data/lib/plugins/say.rb CHANGED
@@ -10,14 +10,16 @@ def say(who, what)
10
10
  end
11
11
 
12
12
  module Termtter::Client
13
- add_hook do |statuses, event, t|
14
- if !statuses.empty? && event == :update_friends_timeline
13
+ register_hook(
14
+ :name => :say,
15
+ :points => [:post_filter],
16
+ :exec_proc => lambda {|statuses, event|
15
17
  statuses.reverse.each do |s|
16
- text_without_uri = s.text.gsub(%r|https?://[^\s]+|, 'U.R.I.')
17
- say s.user.screen_name, text_without_uri
18
+ text_without_uri = s[:post_text].gsub(%r|https?://[^\s]+|, 'U.R.I.')
19
+ say s[:screen_name], text_without_uri
18
20
  end
19
- end
20
- end
21
+ }
22
+ )
21
23
  end
22
24
 
23
25
  # KNOWN BUG:
@@ -29,7 +29,7 @@ module Termtter::Client
29
29
  members += config.plugins.group.groups[group]
30
30
  end
31
31
  statuses = scrape_members(members.uniq.compact.sort)
32
- call_hooks(statuses, :pre_filter)
32
+ output(statuses_to_hash(statuses), :pre_filter)
33
33
  },
34
34
  :completion_proc => lambda {|cmd, args|
35
35
  arg = args.split(' ').last
@@ -1,13 +1,20 @@
1
+ # -*- coding: utf-8 -*-
1
2
 
2
- if config.screen_notify.format.nil? or config.screen_notify.format.empty?
3
- config.screen_notify.format = "[termtter] @%s"
4
- end
3
+ config.screen_notify.set_default(:format, "[termtter] %s")
5
4
 
6
- Termtter::Client.add_hook do |statuses, event|
7
- if !statuses.empty? && event == :update_friends_timeline
8
- statuses.reverse.each do |s|
9
- msg = config.screen_notify.format % [s.user.screen_name, s.text]
10
- system 'screen', '-X', 'eval', "bell_msg '#{msg}'", 'bell'
11
- end
12
- end
5
+ module Termtter::Client
6
+ register_hook(
7
+ :name => :screen_notify,
8
+ :points => [:post_filter],
9
+ :exec_proc => lambda{|statuses, event|
10
+ return unless event = :update_friends_timeline
11
+ Thread.new(statuses) do |ss|
12
+ ss.each do |s|
13
+ msg = config.screen_notify.format % s.user.screen_name
14
+ system 'screen', '-X', 'eval', "bell_msg '#{msg}'", 'bell'
15
+ sleep 1
16
+ end
17
+ end
18
+ }
19
+ )
13
20
  end
@@ -2,6 +2,10 @@
2
2
 
3
3
  require 'erb'
4
4
 
5
+ config.plugins.standard.set_default(
6
+ :limit_format,
7
+ '<<%=remaining_color%>><%=limit.remaining_hits%></<%=remaining_color%>>/<%=limit.hourly_limit%> until <%=limit.reset_time%> (<%=remaining_time%> remaining)')
8
+
5
9
  module Termtter::Client
6
10
 
7
11
  # standard commands
@@ -10,8 +14,9 @@ module Termtter::Client
10
14
  :name => :update, :aliases => [:u],
11
15
  :exec_proc => lambda {|arg|
12
16
  unless arg =~ /^\s*$/
17
+ # TODO: Change to able to disable erb.
13
18
  text = ERB.new(arg).result(binding).gsub(/\n/, ' ')
14
- result = Termtter::API.twitter.update(text, :source=>Termtter::APP_NAME)
19
+ result = Termtter::API.twitter.update(text)
15
20
  puts "=> #{text}"
16
21
  result
17
22
  end
@@ -78,11 +83,14 @@ module Termtter::Client
78
83
  register_command(
79
84
  :name => :list, :aliases => [:l],
80
85
  :exec_proc => lambda {|arg|
81
- unless arg.empty?
82
- call_hooks(Termtter::API.twitter.user_timeline(arg), :list_user_timeline)
86
+ if arg.empty?
87
+ event = :list_friends_timeline
88
+ statuses = Termtter::API.twitter.friends_timeline()
83
89
  else
84
- call_hooks(Termtter::API.twitter.friends_timeline(), :list_friends_timeline)
90
+ event = :list_user_timeline
91
+ statuses = Termtter::API.twitter.user_timeline(arg)
85
92
  end
93
+ output(statuses, event)
86
94
  },
87
95
  :completion_proc => lambda {|cmd, arg|
88
96
  find_user_candidates arg, "#{cmd} %s"
@@ -92,14 +100,15 @@ module Termtter::Client
92
100
  register_command(
93
101
  :name => :search, :aliases => [:s],
94
102
  :exec_proc => lambda {|arg|
95
- call_hooks(Termtter::API.twitter.search(arg), :search)
103
+ statuses = Termtter::API.twitter.search(arg)
104
+ output(statuses, :search)
96
105
  }
97
106
  )
98
107
 
99
108
  register_command(
100
109
  :name => :replies, :aliases => [:r],
101
110
  :exec_proc => lambda {|arg|
102
- call_hooks(Termtter::API.twitter.replies(), :replies)
111
+ output(Termtter::API.twitter.replies(), :replies)
103
112
  }
104
113
  )
105
114
 
@@ -107,7 +116,7 @@ module Termtter::Client
107
116
  :name => :show,
108
117
  :exec_proc => lambda {|arg|
109
118
  id = arg.gsub(/.*:\s*/, '')
110
- call_hooks(Termtter::API.twitter.show(id), :show)
119
+ output([Termtter::API.twitter.show(id)], :show)
111
120
  },
112
121
  :completion_proc => lambda {|cmd, arg|
113
122
  case arg
@@ -128,7 +137,8 @@ module Termtter::Client
128
137
  :name => :shows,
129
138
  :exec_proc => lambda {|arg|
130
139
  id = arg.gsub(/.*:\s*/, '')
131
- call_hooks(Termtter::API.twitter.show(id, true), :show)
140
+ # TODO: Implement
141
+ output([Termtter::API.twitter.show(id)], :show)
132
142
  },
133
143
  :completion_proc => get_command(:show).completion_proc
134
144
  )
@@ -176,7 +186,8 @@ module Termtter::Client
176
186
  when 0..0.2 then :red
177
187
  else :green
178
188
  end
179
- puts "=> #{color(limit.remaining_hits, remaining_color)}/#{limit.hourly_limit} until #{limit.reset_time} (#{remaining_time} remaining)"
189
+ erbed_text = ERB.new(config.plugins.standard.limit_format).result(binding)
190
+ puts TermColor.parse(erbed_text)
180
191
  },
181
192
  :help => ["limit,lm", "Show the API limit status"]
182
193
  )
@@ -229,7 +240,7 @@ module Termtter::Client
229
240
  ["list,l", "List the posts in your friends timeline"],
230
241
  ["list,l USERNAME", "List the posts in the the given user's timeline"],
231
242
  ["update,u TEXT", "Post a new message"],
232
- ["direct,d @USERNAME TEXT", "Send direct message"],
243
+ ["direct,d USERNAME TEXT", "Send direct message"],
233
244
  ["profile,p USERNAME", "Show user's profile"],
234
245
  ["replies,r", "List the most recent @replies for the authenticating user"],
235
246
  ["search,s TEXT", "Search for Twitter"],
@@ -272,17 +283,18 @@ module Termtter::Client
272
283
  public_storage[:users] ||= Set.new
273
284
  public_storage[:status_ids] ||= Set.new
274
285
 
275
- add_hook do |statuses, event, t|
276
- case event
277
- when :update_friends_timeline, :list_friends_timeline, :list_user_timeline, :replies
286
+ register_hook(
287
+ :name => :for_completion,
288
+ :points => [:pre_filter],
289
+ :exec_proc => lambda {|statuses, event|
278
290
  statuses.each do |s|
279
291
  public_storage[:users].add(s.user.screen_name)
280
292
  public_storage[:users] += s.text.scan(/@([a-zA-Z_0-9]*)/).flatten
281
- public_storage[:status_ids].add(s.id.to_s)
282
- public_storage[:status_ids].add(s.in_reply_to_status_id.to_s) if s.in_reply_to_status_id
293
+ public_storage[:status_ids].add(s.id)
294
+ public_storage[:status_ids].add(s.in_reply_to_status_id) if s.in_reply_to_status_id
283
295
  end
284
- end
285
- end
296
+ }
297
+ )
286
298
 
287
299
  def self.find_status_ids(text)
288
300
  public_storage[:status_ids].select{|id| id =~ /#{Regexp.quote(text)}/}