jugyo-termtter 0.8.14 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. data/README.rdoc +8 -8
  2. data/Rakefile +3 -5
  3. data/lib/{plugin → plugins}/april_fool.rb +0 -0
  4. data/lib/plugins/bomb.rb +42 -0
  5. data/lib/{plugin → plugins}/clear.rb +0 -0
  6. data/lib/{plugin → plugins}/confirm.rb +0 -0
  7. data/lib/{plugin → plugins}/cool.rb +0 -0
  8. data/lib/{plugin → plugins}/devel.rb +0 -0
  9. data/lib/{filter → plugins}/en2ja.rb +1 -1
  10. data/lib/plugins/english.rb +25 -0
  11. data/lib/{plugin → plugins}/erb.rb +0 -0
  12. data/lib/{filter → plugins}/expand-tinyurl.rb +6 -6
  13. data/lib/plugins/favorite.rb +63 -0
  14. data/lib/plugins/fib.rb +28 -0
  15. data/lib/{filter/fib.rb → plugins/fib_filter.rb} +1 -2
  16. data/lib/{plugin → plugins}/filter.rb +0 -0
  17. data/lib/{plugin → plugins}/graduatter.rb +1 -2
  18. data/lib/{plugin → plugins}/grass.rb +2 -2
  19. data/lib/{plugin → plugins}/group.rb +9 -9
  20. data/lib/{plugin → plugins}/growl.rb +11 -12
  21. data/lib/{plugin → plugins}/hatebu.rb +5 -5
  22. data/lib/{plugin → plugins}/history.rb +13 -13
  23. data/lib/plugins/ignore.rb +19 -0
  24. data/lib/plugins/keyword.rb +18 -0
  25. data/lib/{plugin → plugins}/log.rb +18 -12
  26. data/lib/{plugin → plugins}/me.rb +1 -2
  27. data/lib/{plugin → plugins}/modify_arg_hook_sample.rb +0 -0
  28. data/lib/{plugin → plugins}/msagent.rb +1 -1
  29. data/lib/plugins/multi_reply.rb +27 -0
  30. data/lib/{plugin → plugins}/notify-send.rb +1 -1
  31. data/lib/{plugin → plugins}/otsune.rb +0 -0
  32. data/lib/plugins/outputz.rb +33 -0
  33. data/lib/{plugin → plugins}/pause.rb +0 -0
  34. data/lib/{plugin → plugins}/plugin.rb +0 -0
  35. data/lib/{plugin → plugins}/post_exec_hook_sample.rb +0 -0
  36. data/lib/{plugin → plugins}/pre_exec_hook_sample.rb +0 -0
  37. data/lib/{plugin → plugins}/primes.rb +9 -2
  38. data/lib/plugins/quicklook.rb +41 -0
  39. data/lib/{plugin → plugins}/random.rb +0 -0
  40. data/lib/{plugin → plugins}/reblog.rb +3 -3
  41. data/lib/{plugin → plugins}/reload.rb +0 -0
  42. data/lib/{filter → plugins}/reply.rb +0 -0
  43. data/lib/{filter → plugins}/reverse.rb +1 -1
  44. data/lib/{plugin → plugins}/say.rb +1 -1
  45. data/lib/{plugin → plugins}/scrape.rb +4 -4
  46. data/lib/plugins/screen-notify.rb +13 -0
  47. data/lib/plugins/screen.rb +24 -0
  48. data/lib/{plugin → plugins}/shell.rb +0 -0
  49. data/lib/{plugin → plugins}/sl.rb +4 -4
  50. data/lib/plugins/spam.rb +13 -0
  51. data/lib/{plugin → plugins}/standard_plugins.rb +72 -18
  52. data/lib/plugins/stdout.rb +80 -0
  53. data/lib/plugins/storage/DB.rb +37 -0
  54. data/lib/plugins/storage/status.rb +48 -0
  55. data/lib/plugins/storage/status_mook.rb +30 -0
  56. data/lib/plugins/storage.rb +47 -0
  57. data/lib/plugins/system_status.rb +33 -0
  58. data/lib/{plugin → plugins}/translation.rb +15 -5
  59. data/lib/{plugin → plugins}/update_editor.rb +6 -6
  60. data/lib/plugins/uri-open.rb +64 -0
  61. data/lib/{filter → plugins}/url_addspace.rb +0 -0
  62. data/lib/{plugin → plugins}/wassr_post.rb +1 -1
  63. data/lib/{plugin → plugins}/yhara.rb +1 -1
  64. data/lib/plugins/yhara_filter.rb +8 -0
  65. data/lib/plugins/yonda.rb +21 -0
  66. data/lib/termtter/api.rb +28 -2
  67. data/lib/termtter/client.rb +90 -102
  68. data/lib/termtter/command.rb +32 -31
  69. data/lib/termtter/config.rb +64 -0
  70. data/lib/termtter/connection.rb +9 -7
  71. data/lib/termtter/hook.rb +11 -2
  72. data/lib/termtter/optparse.rb +14 -0
  73. data/lib/termtter/version.rb +1 -1
  74. data/lib/termtter.rb +19 -22
  75. data/spec/plugin/english_spec.rb +19 -0
  76. data/spec/plugin/favorite_spec.rb +10 -0
  77. data/spec/plugin/fib_spec.rb +1 -2
  78. data/spec/plugin/pause_spec.rb +8 -0
  79. data/spec/plugin/plugin_spec.rb +1 -1
  80. data/spec/plugin/primes_spec.rb +15 -0
  81. data/spec/plugin/sl_spec.rb +8 -0
  82. data/spec/plugin/spam_spec.rb +0 -13
  83. data/spec/plugin/standard_plugins_spec.rb +0 -7
  84. data/spec/plugin/storage/DB_spec.rb +12 -0
  85. data/spec/plugin/storage/status_spec.rb +24 -0
  86. data/spec/spec_helper.rb +3 -0
  87. data/spec/termtter/client_spec.rb +63 -1
  88. data/spec/termtter/command_spec.rb +6 -68
  89. data/spec/termtter/config_spec.rb +111 -0
  90. data/spec/termtter/hook_spec.rb +69 -0
  91. data/spec/termtter_spec.rb +22 -34
  92. metadata +81 -72
  93. data/lib/filter/english.rb +0 -8
  94. data/lib/filter/ignore.rb +0 -19
  95. data/lib/filter/yhara.rb +0 -20
  96. data/lib/plugin/bomb.rb +0 -29
  97. data/lib/plugin/english.rb +0 -59
  98. data/lib/plugin/favorite.rb +0 -75
  99. data/lib/plugin/fib.rb +0 -8
  100. data/lib/plugin/follow.rb +0 -60
  101. data/lib/plugin/keyword.rb +0 -18
  102. data/lib/plugin/multi_reply.rb +0 -36
  103. data/lib/plugin/outputz.rb +0 -35
  104. data/lib/plugin/quicklook.rb +0 -38
  105. data/lib/plugin/screen.rb +0 -24
  106. data/lib/plugin/spam.rb +0 -9
  107. data/lib/plugin/stdout.rb +0 -63
  108. data/lib/plugin/system_status.rb +0 -33
  109. data/lib/plugin/uri-open.rb +0 -69
  110. data/lib/plugin/yonda.rb +0 -20
  111. data/lib/termtter/status.rb +0 -26
  112. data/lib/termtter/twitter.rb +0 -188
  113. data/lib/termtter/user.rb +0 -13
  114. data/spec/termtter/user_spec.rb +0 -27
  115. data/test/test_termtter.rb +0 -86
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ register_command(
5
+ :name => :multi_reply, :aliases => [:mr],
6
+ :exec_proc => lambda {|arg|
7
+ text = ERB.new(arg).result(binding).gsub(/\n/, ' ')
8
+ unless text.empty?
9
+ /(@(.+))*\s+(.+)/ =~ text
10
+ if $1
11
+ msg = $3
12
+ text = $1.split(/\s+/).map {|u| "#{u} #{msg}" }
13
+ end
14
+ Array(text).each do |post|
15
+ Termtter::API.twitter.update(post)
16
+ puts "=> #{post}"
17
+ end
18
+ end
19
+ },
20
+ :completion_proc => lambda {|cmd, args|
21
+ if /(.*)@([^\s]*)$/ =~ args
22
+ find_user_candidates $2, "#{cmd} #{$1}@%s"
23
+ end
24
+ },
25
+ :help => ["multi_reply,mp TEXT", "Reply to multi user"]
26
+ )
27
+ end
@@ -7,7 +7,7 @@ Termtter::Client.add_hook do |statuses, event|
7
7
  text = statuses.take(max).map {|s|
8
8
  status_text = CGI.escapeHTML(s.text)
9
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>"
10
+ "<b>#{s.user.screen_name}:</b> <span font=\"9.0\">#{status_text}</span>"
11
11
  }.join("\n")
12
12
 
13
13
  text << %Q|\n<a href="http://twitter.com/">more...</a>| if statuses.size > max
File without changes
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ config.plugins.outputz.set_default(:uri, 'termtter://twitter.com/status/update')
5
+
6
+ key = config.plugins.outputz.secret_key
7
+ if key.empty?
8
+ puts 'Need your secret key'
9
+ puts 'please set config.plugins.outputz.secret_key'
10
+ else
11
+ register_hook(
12
+ :name => :outputz,
13
+ :points => [:pre_exec_update],
14
+ :exec_proc => lambda {|cmd, arg|
15
+ Thead.new do
16
+ Termtter::API.connection.start('outputz.com', 80) do |http|
17
+ key = CGI.escape key
18
+ uri = CGI.escape config.plugins.outputz.uri
19
+ size = arg.split(//).size
20
+ http.post('/api/post', "key=#{key}&uri=#{uri}&size=#{size}")
21
+ end
22
+ end
23
+ }
24
+ )
25
+ end
26
+ end
27
+
28
+ # outputz.rb
29
+ # a plugin that report to outputz your post
30
+ #
31
+ # settings (note: must this order)
32
+ # config.plugins.outputz.secret_key = 'your secret key'
33
+ # plugin 'outputz'
File without changes
File without changes
File without changes
File without changes
@@ -1,6 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  def primes(n)
4
+ return "" if n < 3
4
5
  table = []
5
6
  (2 .. n).each do |i|
6
7
  table << i
@@ -18,6 +19,12 @@ def primes(n)
18
19
  end
19
20
 
20
21
  module Termtter::Client
21
- add_command /^primes\s(\d+)/ do|m,t|t.update_status x="primes(#{n=m[1].to_i}) = {#{primes n}}"
22
- puts "=> #{x}" end
22
+ register_command(
23
+ :name => :primes,
24
+ :exec_proc => lambda {|arg|
25
+ n = arg.to_i
26
+ text = "primes(#{n}) = {#{primes n}}}"
27
+ puts "=> " << text
28
+ }
29
+ )
23
30
  end
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'uri'
4
+ require 'open-uri'
5
+ require 'pathname'
6
+ require 'tmpdir'
7
+
8
+ config.plugins.quicklook.set_default(:quicklook_tmpdir, "#{Dir.tmpdir}/termtter-quicklook-tmpdir")
9
+ tmpdir = Pathname.new(config.plugins.quicklook.quicklook_tmpdir)
10
+ tmpdir.mkdir unless tmpdir.exist?
11
+
12
+ def quicklook(url)
13
+ tmpdir = Pathname.new(config.plugins.quicklook.quicklook_tmpdir)
14
+ path = tmpdir + Pathname.new(url).basename
15
+
16
+ Thread.new do
17
+ open(path, 'w') do |f|
18
+ f.write(open(url).read)
19
+ end
20
+ system("qlmanage -p #{path} > /dev/null 2>&1")
21
+ end
22
+ end
23
+
24
+ module Termtter::Client
25
+ register_command(
26
+ :name => :quicklook, :aliases => [:ql],
27
+ :exec_proc => proc{|arg|
28
+ status = Termtter::API.twitter.show(arg)
29
+ if (status)
30
+ uris = URI.regexp.match(status.text).to_a
31
+ quicklook(uris.first) unless uris.empty?
32
+ end
33
+ }
34
+ )
35
+ end
36
+
37
+ # quicklook.rb
38
+ # REQUIREMENTS:
39
+ # plugin 'expand-tinyurl'
40
+ # TODO:
41
+ # Close quicklook window automatically.
File without changes
@@ -17,7 +17,7 @@ module Termtter::Client
17
17
  status = t.show(id).first
18
18
  end
19
19
 
20
- Tumblr::API.write(configatron.plugins.reblog.email, configatron.plugins.reblog.password) do
20
+ Tumblr::API.write(config.plugins.reblog.email, config.plugins.reblog.password) do
21
21
  quote("#{status.text}", "<a href=\"http://twitter.com/#{status.user_screen_name}/status/#{status.id}\">Twitter / #{status.user_name}</a>")
22
22
  end
23
23
  end
@@ -34,7 +34,7 @@ end
34
34
  # reblog.rb
35
35
  # tumblr reblog it!
36
36
  #
37
- # configatron.plugins.reblog.email = 'your-email-on-tumblr'
38
- # configatron.plugins.reblog.password = 'your-password-on-tumblr'
37
+ # config.plugins.reblog.email = 'your-email-on-tumblr'
38
+ # config.plugins.reblog.password = 'your-password-on-tumblr'
39
39
  #
40
40
  # reblog 1114860346
File without changes
File without changes
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module Termtter::Client
4
- add_filter do |statuses|
4
+ add_filter do |statuses, _|
5
5
  statuses.map do |s|
6
6
  s.text = s.text.split(//).reverse.to_s
7
7
  s
@@ -14,7 +14,7 @@ module Termtter::Client
14
14
  if !statuses.empty? && event == :update_friends_timeline
15
15
  statuses.reverse.each do |s|
16
16
  text_without_uri = s.text.gsub(%r|https?://[^\s]+|, 'U.R.I.')
17
- say s.user_screen_name, text_without_uri
17
+ say s.user.screen_name, text_without_uri
18
18
  end
19
19
  end
20
20
  end
@@ -6,13 +6,13 @@ module Termtter::Client
6
6
  statuses = []
7
7
  members.each_with_index do |member, index|
8
8
  puts "member #{index+1}/#{members.size} #{member}"
9
- statuses += Termtter::API.twitter.get_user_timeline(member)
9
+ statuses += Termtter::API.twitter.user_timeline(member)
10
10
  end
11
11
  statuses
12
12
  end
13
13
 
14
14
  def self.scrape_group(group)
15
- members = configatron.plugins.group.groups[group] || []
15
+ members = config.plugins.group.groups[group] || []
16
16
  scrape_members(members)
17
17
  end
18
18
 
@@ -21,12 +21,12 @@ module Termtter::Client
21
21
  :exec_proc => lambda{ |args|
22
22
  groups = args.split(' ').map{|g| g.to_sym}
23
23
  if groups.include? :all
24
- groups = configatron.plugins.group.groups.keys
24
+ groups = config.plugins.group.groups.keys
25
25
  puts "get all groups..."
26
26
  end
27
27
  members = []
28
28
  groups.each do |group|
29
- members += configatron.plugins.group.groups[group]
29
+ members += config.plugins.group.groups[group]
30
30
  end
31
31
  statuses = scrape_members(members.uniq.compact.sort)
32
32
  call_hooks(statuses, :pre_filter)
@@ -0,0 +1,13 @@
1
+
2
+ if config.screen_notify.format.nil? or config.screen_notify.format.empty?
3
+ config.screen_notify.format = "[termtter] @%s"
4
+ end
5
+
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
13
+ end
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter
4
+ module Plugin
5
+ module Screen
6
+ def self.set_title(title)
7
+ print "\033k#{title}\033\\\n"
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ # Add below to your ~/.termtter
14
+ #
15
+ # require 'plugins/yonda'
16
+ # require 'plugins/screen'
17
+ # module Termtter::Client
18
+ # register_hook(:name => :screen,
19
+ # :points => [:post_exec__update_timeline, :plugin_yonda_yonda, :post_exec_yonda],
20
+ # :exec_proc => lambda { |cmd, arg, result|
21
+ # Termtter::Plugin::Screen::set_title("termtter(#{public_storage[:unread_count]})")
22
+ # }
23
+ # )
24
+ # end
File without changes
@@ -5,8 +5,8 @@ module Termtter
5
5
  module Client
6
6
 
7
7
  public_storage[:current] = ''
8
- public_storage[:orig_prompt] = configatron.prompt
9
- configatron.prompt = "~/ #{public_storage[:orig_prompt]}"
8
+ public_storage[:orig_prompt] = config.prompt
9
+ config.prompt = "~/ #{public_storage[:orig_prompt]}"
10
10
 
11
11
  register_command(
12
12
  :name => :sl, :aliases => [],
@@ -23,7 +23,7 @@ module Termtter
23
23
  register_command(
24
24
  :name => :ls, :aliases => [],
25
25
  :exec_proc => lambda {|arg|
26
- call_commands("list #{arg.empty? ? public_storage[:current] : arg}", API.twitter)
26
+ call_commands("list #{arg.empty? ? public_storage[:current] : arg}")
27
27
  },
28
28
  :completion_proc => lambda {|cmd, args|
29
29
  find_user_candidates args, "#{cmd} %s"
@@ -36,7 +36,7 @@ module Termtter
36
36
  :exec_proc => lambda {|arg|
37
37
  public_storage[:current] =
38
38
  (arg.nil? || /\~/ =~ arg) ? '' : arg
39
- configatron.prompt = "~/#{public_storage[:current]} #{public_storage[:orig_prompt]}"
39
+ config.prompt = "~/#{public_storage[:current]} #{public_storage[:orig_prompt]}"
40
40
  },
41
41
  :completion_proc => lambda {|cmd, args|
42
42
  find_user_candidates args, "#{cmd} %s"
@@ -0,0 +1,13 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::API.twitter.update('*super spam time*')
4
+ Termtter::Client.register_hook(
5
+ :name => :span,
6
+ :points => [/^pre_exec/],
7
+ :exec_proc => lambda{|*arg|
8
+ text = arg.join(' ')
9
+ Termtter::API.twitter.update(text)
10
+ puts "=> #{text}"
11
+ false
12
+ }
13
+ )
@@ -9,9 +9,12 @@ module Termtter::Client
9
9
  register_command(
10
10
  :name => :update, :aliases => [:u],
11
11
  :exec_proc => lambda {|arg|
12
- text = ERB.new(arg).result(binding).gsub(/\n/, ' ')
13
- Termtter::API.twitter.update_status(text)
14
- puts "=> #{text}"
12
+ unless arg =~ /^\s*$/
13
+ text = ERB.new(arg).result(binding).gsub(/\n/, ' ')
14
+ result = Termtter::API.twitter.update(text)
15
+ puts "=> #{text}"
16
+ result
17
+ end
15
18
  },
16
19
  :completion_proc => lambda {|cmd, args|
17
20
  if /(.*)@([^\s]*)$/ =~ args
@@ -39,7 +42,7 @@ module Termtter::Client
39
42
  register_command(
40
43
  :name => :profile, :aliases => [:p],
41
44
  :exec_proc => lambda {|arg|
42
- user = Termtter::API.twitter.get_user_profile(arg)
45
+ user = Termtter::API.twitter.user(arg.strip)
43
46
  attrs = %w[ name screen_name url description profile_image_url location protected following
44
47
  friends_count followers_count statuses_count favourites_count
45
48
  id time_zone created_at utc_offset notifications
@@ -58,19 +61,27 @@ module Termtter::Client
58
61
  register_command(
59
62
  :name => :followers,
60
63
  :exec_proc => lambda {|arg|
61
- followers = Termtter::API.twitter.followers
64
+ user_name = arg.strip
65
+ user_name = config.user_name if user_name.empty?
66
+
67
+ followers = []
68
+ page = 0
69
+ begin
70
+ followers += tmp = Termtter::API.twitter.followers(user_name, :page => page+=1)
71
+ end until tmp.empty?
62
72
  Termtter::Client.public_storage[:followers] = followers
63
73
  puts followers.map{|f|f.screen_name}.join(' ')
64
74
  }
75
+ # TODO :completion_proc
65
76
  )
66
77
 
67
78
  register_command(
68
79
  :name => :list, :aliases => [:l],
69
80
  :exec_proc => lambda {|arg|
70
81
  unless arg.empty?
71
- call_hooks(Termtter::API.twitter.get_user_timeline(arg), :list_user_timeline)
82
+ call_hooks(Termtter::API.twitter.user_timeline(arg), :list_user_timeline)
72
83
  else
73
- call_hooks(Termtter::API.twitter.get_friends_timeline(), :list_friends_timeline)
84
+ call_hooks(Termtter::API.twitter.friends_timeline(), :list_friends_timeline)
74
85
  end
75
86
  },
76
87
  :completion_proc => lambda {|cmd, arg|
@@ -122,13 +133,43 @@ module Termtter::Client
122
133
  :completion_proc => get_command(:show).completion_proc
123
134
  )
124
135
 
136
+ register_command(
137
+ :name => :follow, :aliases => [],
138
+ :exec_proc => lambda {|args|
139
+ args.split(' ').each do |arg|
140
+ if arg =~ /^(\w+)/
141
+ res = Termtter::API::twitter.follow($1.strip)
142
+ end
143
+ end
144
+ },
145
+ :completion_proc => lambda {|cmd, args|
146
+ find_user_candidates args, "#{cmd} %s"
147
+ },
148
+ :help => ['follow USER', 'Follow user']
149
+ )
150
+
151
+ register_command(
152
+ :name => :leave, :aliases => [],
153
+ :exec_proc => lambda {|args|
154
+ args.split(' ').each do |arg|
155
+ if arg =~ /^(\w+)/
156
+ res = Termtter::API::twitter.leave($1.strip)
157
+ end
158
+ end
159
+ },
160
+ :completion_proc => lambda {|cmd, args|
161
+ find_user_candidates args, "#{cmd} %s"
162
+ },
163
+ :help => ['leave USER', 'Leave user']
164
+ )
165
+
125
166
  # TODO: Change colors when remaining_hits is low.
126
167
  # TODO: Simmulate remaining_hits.
127
168
  register_command(
128
169
  :name => :limit, :aliases => [:lm],
129
170
  :exec_proc => lambda {|arg|
130
- limit = Termtter::API.twitter.get_rate_limit_status
131
- remaining_time = "%dmin %dsec" % (limit.reset_time - Time.now).divmod(60)
171
+ limit = Termtter::API.twitter.limit_status
172
+ remaining_time = "%dmin %dsec" % (Time.parse(limit.reset_time) - Time.now).divmod(60)
132
173
  remaining_color =
133
174
  case limit.remaining_hits / limit.hourly_limit.to_f
134
175
  when 0.2..0.4 then :yellow
@@ -162,10 +203,20 @@ module Termtter::Client
162
203
  :name => :default_error_handler,
163
204
  :points => [:on_error],
164
205
  :exec_proc => lambda {|e|
165
- puts "Error: #{e}"
166
- if configatron.devel == true
167
- puts e.backtrace.join("\n")
206
+ case e
207
+ when Rubytter::APIError
208
+ case e.response.code
209
+ when /401/
210
+ warn '[ERROR] Unauthorized: maybe you tried to show protected user status'
211
+ when /403/
212
+ warn '[ERROR] Access denied: maybe that user is protected'
213
+ when /404/
214
+ warn '[ERROR] Not found: maybe there is no such user'
215
+ end
216
+ else
217
+ warn "[ERROR] Something wrong: #{e.message}"
168
218
  end
219
+ raise e if config.system.devel == true
169
220
  }
170
221
  )
171
222
 
@@ -197,7 +248,7 @@ module Termtter::Client
197
248
  if arg
198
249
  `#{arg}`.each_line do |line|
199
250
  unless line.strip.empty?
200
- Termtter::API.twitter.update_status(line)
251
+ Termtter::API.twitter.update(line)
201
252
  puts "=> #{line}"
202
253
  end
203
254
  end
@@ -222,11 +273,14 @@ module Termtter::Client
222
273
  public_storage[:status_ids] ||= Set.new
223
274
 
224
275
  add_hook do |statuses, event, t|
225
- statuses.each do |s|
226
- public_storage[:users].add(s.user_screen_name)
227
- public_storage[:users] += s.text.scan(/@([a-zA-Z_0-9]*)/).flatten
228
- public_storage[:status_ids].add(s.id.to_s)
229
- public_storage[:status_ids].add(s.in_reply_to_status_id.to_s) if s.in_reply_to_status_id
276
+ case event
277
+ when :update_friends_timeline, :list_friends_timeline, :list_user_timeline, :replies
278
+ statuses.each do |s|
279
+ public_storage[:users].add(s.user.screen_name)
280
+ 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
283
+ end
230
284
  end
231
285
  end
232
286
 
@@ -0,0 +1,80 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'termcolor'
4
+ require 'erb'
5
+
6
+ config.plugins.stdout.set_default(
7
+ :colors,
8
+ [:none, :red, :green, :yellow, :blue, :magenta, :cyan])
9
+ config.plugins.stdout.set_default(
10
+ :timeline_format,
11
+ '<90><%=time%></90> <<%=status_color%>><%=status%></<%=status_color%>> <90><%=id%></90>')
12
+ config.plugins.stdout.set_default(:search_highlihgt_format, '<on_magenta><white>\1</white></on_magenta>')
13
+
14
+ $highline = HighLine.new
15
+
16
+ def color(str, value)
17
+ return str if value == :none
18
+ case value
19
+ when String, Symbol
20
+ $highline.color(str, value)
21
+ else
22
+ "\e[#{value}m#{str}\e[0m"
23
+ end
24
+ end
25
+
26
+ module Termtter::Client
27
+
28
+ def self.print_statuses(statuses, sort = true, time_format = '%H:%M:%S')
29
+ (sort ? statuses.sort_by{ |s| s.id} : statuses).each do |s|
30
+ text = s.text
31
+ status_color = config.plugins.stdout.colors[s.user.screen_name.hash % config.plugins.stdout.colors.size]
32
+ status = "#{s.user.screen_name}: #{text}"
33
+ if s.in_reply_to_status_id
34
+ status += " (repl. to #{s.in_reply_to_status_id})"
35
+ end
36
+
37
+ time = "(#{Time.parse(s.created_at).strftime(time_format)})"
38
+ id = s.id
39
+ erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
40
+ puts TermColor.parse(erbed_text)
41
+ end
42
+ end
43
+
44
+ def self.print_statuses_with_date(statuses, sort = true)
45
+ print_statuses(statuses, sort, '%m-%d %H:%M')
46
+ end
47
+
48
+ def self.print_search_results(result, time_format = '%H:%M:%S')
49
+ result.results.sort_by{|r| r.created_at}.each do |r|
50
+ text = r.text.
51
+ gsub(/(\n|\r)/, '').
52
+ gsub(/(#{Regexp.escape(result.query)})/i, config.plugins.stdout.search_highlihgt_format)
53
+ status_color = config.plugins.stdout.colors[r.from_user_id.to_i.hash % config.plugins.stdout.colors.size]
54
+ status = "#{r.from_user}: #{text}"
55
+ time = "(#{Time.parse(r.created_at).strftime(time_format)})"
56
+ id = r.id
57
+ erbed_text = ERB.new(config.plugins.stdout.timeline_format).result(binding)
58
+ puts TermColor.parse(erbed_text)
59
+ end
60
+ end
61
+
62
+ add_hook do |result, event|
63
+ case event
64
+ when :update_friends_timeline, :list_friends_timeline
65
+ print_statuses(result) unless result.empty?
66
+ when :list_user_timeline, :replies
67
+ print_statuses_with_date(result) unless result.empty?
68
+ when :show
69
+ print_statuses_with_date([result])
70
+ when :search
71
+ print_search_results(result)
72
+ end
73
+ end
74
+
75
+ end
76
+ # stdout.rb
77
+ # output statuses to stdout
78
+ # example config
79
+ # config.plugins.stdout.colors = [:none, :red, :green, :yellow, :blue, :magenta, :cyan]
80
+ # config.plugins.stdout.timeline_format = '<90><%=time%></90> <<%=status_color%>><%=status%></<%=status_color%>> <90><%=id%></90>'
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'sqlite3'
4
+ require 'singleton'
5
+
6
+ module Termtter::Storage
7
+ class DB
8
+ include Singleton
9
+ attr_reader :db
10
+
11
+ def initialize
12
+ @db = SQLite3::Database.new(Termtter::CONF_DIR + '/storage.db')
13
+ @db.type_translation = true
14
+ create_table
15
+ end
16
+
17
+ def create_table
18
+ sql =<<-SQL
19
+ CREATE TABLE IF NOT EXISTS user (
20
+ id int NOT NULL,
21
+ screen_name text,
22
+ PRIMARY KEY (id)
23
+ );
24
+ CREATE TABLE IF NOT EXISTS post (
25
+ post_id int NOT NULL, -- twitter側のpostのid
26
+ created_at int, -- 日付(RubyでUNIX時間に変換)
27
+ in_reply_to_status_id int, -- あったほうがよいらしい
28
+ in_reply_to_user_id int, -- あったほうがよいらしい
29
+ post_text text,
30
+ user_id int NOT NULL,
31
+ PRIMARY KEY (post_id)
32
+ );
33
+ SQL
34
+ @db.execute_batch(sql)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,48 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require File.dirname(__FILE__) + '/DB'
4
+ require 'sqlite3'
5
+
6
+ module Termtter::Storage
7
+ class Status
8
+ KEYS = %w[post_id created_at in_reply_to_status_id in_reply_to_user_id post_text user_id screen_name]
9
+
10
+ def size
11
+ DB.instance.db.get_first_value("select count(*) from post").to_i
12
+ end
13
+
14
+ def self.search(query)
15
+ raise "query must be Hash(#{query}, #{query.class})" unless query.kind_of? Hash
16
+
17
+ DB.instance.db.execute("select created_at, screen_name, post_text, in_reply_to_status_id, post_id from post inner join user on post.user_id = user.id where post_text like '%' || ? || '%' ", query[:post_text]) do |created_at, screen_name, post_text, in_reply_to_status_id, post_id|
18
+
19
+ # DB.instance.db.execute("select created_at, screen_name, post_text, in_reply_to_status_id, post_id from post inner join user on post.user_id = user.id where post_text like '%of%' ", query[:post_text]) do |created_at, screen_name, post_text, in_reply_to_status_id, post_id|
20
+ p [created_at, screen_name, post_text, in_reply_to_status_id, post_id]
21
+ end
22
+ end
23
+
24
+ def self.insert(data)
25
+ raise "data must be Hash(#{data}, #{data.class})" unless data.kind_of? Hash
26
+ # 条件しぼりたいけどやりかたがうまくわからない
27
+ # raise "unko" unless data.keys.all?{|c| KEYS.include? c}
28
+ begin
29
+ DB.instance.db.execute(
30
+ "insert into post values(?,?,?,?,?,?)",
31
+ data[:post_id],
32
+ data[:created_at],
33
+ data[:in_reply_to_status_id],
34
+ data[:in_reply_to_user_id],
35
+ data[:post_text],
36
+ data[:user_id])
37
+ begin
38
+ DB.instance.db.execute(
39
+ "insert into user values(?,?)",
40
+ data[:user_id],
41
+ data[:screen_name])
42
+ rescue # FIXME: specify exceptions here
43
+ end
44
+ rescue # FIXME: specify exceptions here
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,30 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'sqlite3'
4
+
5
+ module Termtter::Storage
6
+ class Status
7
+ def initialize
8
+ end
9
+
10
+ def self.create
11
+ end
12
+
13
+ def self.all
14
+ []
15
+ end
16
+
17
+ def self.search
18
+ end
19
+
20
+ private
21
+ def db
22
+ @db ||= connect
23
+ end
24
+
25
+ def connect
26
+ @db = SQLite3::Database.new(File.expand_path('~/test.db'))
27
+ @db.type_translation = true
28
+ end
29
+ end
30
+ end