jugyo-termtter 1.1.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/ChangeLog +115 -0
  2. data/README.rdoc +25 -10
  3. data/Rakefile +53 -34
  4. data/lib/plugins/cool.rb +2 -5
  5. data/lib/plugins/curry.rb +43 -0
  6. data/lib/plugins/db.rb +91 -0
  7. data/lib/plugins/{auto_reload.rb → defaults/auto_reload.rb} +5 -1
  8. data/lib/plugins/defaults/command_line.rb +111 -0
  9. data/lib/plugins/{exec.rb → defaults/exec.rb} +2 -7
  10. data/lib/plugins/{fib.rb → defaults/fib.rb} +1 -4
  11. data/lib/plugins/defaults/retweet.rb +34 -0
  12. data/lib/plugins/{standard_commands.rb → defaults/standard_commands.rb} +88 -162
  13. data/lib/plugins/defaults/standard_completion.rb +67 -0
  14. data/lib/plugins/defaults/stdout.rb +148 -0
  15. data/lib/plugins/defaults.rb +14 -0
  16. data/lib/plugins/en2ja.rb +11 -5
  17. data/lib/plugins/english.rb +2 -2
  18. data/lib/plugins/expand-tinyurl.rb +27 -6
  19. data/lib/plugins/github-issues.rb +192 -0
  20. data/lib/plugins/group.rb +30 -4
  21. data/lib/plugins/growl.rb +10 -1
  22. data/lib/plugins/http_server/favicon.ico +0 -0
  23. data/lib/plugins/http_server/index.html +117 -0
  24. data/lib/plugins/http_server.rb +82 -0
  25. data/lib/plugins/irb.rb +6 -0
  26. data/lib/plugins/l2.rb +1 -1
  27. data/lib/plugins/list_with_opts.rb +0 -3
  28. data/lib/plugins/log.rb +6 -9
  29. data/lib/plugins/modify_arg_hook_sample.rb +3 -5
  30. data/lib/plugins/multi_reply.rb +0 -5
  31. data/lib/plugins/notify-send.rb +1 -1
  32. data/lib/plugins/notify-send2.rb +1 -1
  33. data/lib/plugins/notify-send3.rb +11 -3
  34. data/lib/plugins/open_url.rb +5 -17
  35. data/lib/plugins/otsune.rb +3 -9
  36. data/lib/plugins/outputz.rb +1 -1
  37. data/lib/plugins/pool.rb +30 -0
  38. data/lib/plugins/protected_filter.rb +9 -0
  39. data/lib/plugins/quicklook.rb +1 -1
  40. data/lib/plugins/saykanji.rb +81 -0
  41. data/lib/plugins/shell.rb +1 -6
  42. data/lib/plugins/sl.rb +8 -8
  43. data/lib/plugins/tinyurl.rb +26 -7
  44. data/lib/plugins/trends.rb +84 -0
  45. data/lib/plugins/twitpic.rb +46 -0
  46. data/lib/plugins/uri-open.rb +33 -28
  47. data/lib/plugins/wassr.rb +0 -3
  48. data/lib/plugins/whois.rb +45 -0
  49. data/lib/plugins/yhara.rb +2 -6
  50. data/lib/termtter/client.rb +91 -103
  51. data/lib/termtter/command.rb +24 -9
  52. data/lib/termtter/config.rb +8 -6
  53. data/lib/termtter/config_setup.rb +1 -1
  54. data/lib/termtter/config_template.erb +1 -4
  55. data/lib/termtter/hook.rb +2 -2
  56. data/lib/termtter/optparse.rb +14 -1
  57. data/lib/termtter/system_extensions.rb +3 -2
  58. data/lib/termtter/task_manager.rb +1 -5
  59. data/lib/termtter/version.rb +1 -1
  60. data/spec/plugins/cool_spec.rb +1 -1
  61. data/spec/plugins/curry_spec.rb +13 -0
  62. data/spec/plugins/db_spec.rb +62 -0
  63. data/spec/plugins/english_spec.rb +2 -2
  64. data/spec/plugins/fib_spec.rb +2 -2
  65. data/spec/plugins/filter_spec.rb +2 -2
  66. data/spec/plugins/pause_spec.rb +1 -1
  67. data/spec/plugins/primes_spec.rb +2 -2
  68. data/spec/plugins/shell_spec.rb +1 -1
  69. data/spec/plugins/sl_spec.rb +1 -1
  70. data/spec/plugins/{standard_plugins_spec.rb → standard_commands_spec.rb} +2 -2
  71. data/spec/plugins/whois_spec.rb +20 -0
  72. data/spec/termtter/client_spec.rb +151 -33
  73. data/spec/termtter/command_spec.rb +68 -35
  74. data/spec/termtter/config_spec.rb +10 -0
  75. data/spec/termtter/optparse_spec.rb +16 -0
  76. data/spec/termtter_spec.rb +7 -8
  77. metadata +48 -19
  78. data/History.txt +0 -4
  79. data/lib/plugins/direct_messages.rb +0 -36
  80. data/lib/plugins/retweet.rb +0 -46
  81. data/lib/plugins/stdout.rb +0 -77
@@ -20,6 +20,6 @@ end
20
20
  # select English posts only
21
21
  #
22
22
  # config sample:
23
- # plugin 'english'
23
+ # t.plug 'english'
24
24
  # or,
25
- # plugin 'english', :only => [:list_friends_timeline, :update_friends_timeline]
25
+ # t.plug 'english', :only => [:list_friends_timeline, :update_friends_timeline]
@@ -4,13 +4,34 @@ URL_SHORTTERS = [
4
4
  { :host => "tinyurl.com", :pattern => %r'(http://tinyurl\.com(/[\w/]+))' },
5
5
  { :host => "is.gd", :pattern => %r'(http://is\.gd(/[\w/]+))' },
6
6
  { :host => "bit.ly", :pattern => %r'(http://bit\.ly(/[\w/]+))' },
7
- { :host => "ff.im", :pattern => %r'(http://ff\.im(/[\w/]+))'},
7
+ { :host => "ff.im", :pattern => %r'(http://ff\.im(/[-\w/]+))'},
8
8
  ]
9
9
 
10
- module Termtter::Client
11
- add_filter do |statuses, event|
10
+ config.plugins.expand_tinyurl.set_default(:shortters, [])
11
+ config.plugins.expand_tinyurl.set_default(:skip_users, [])
12
+
13
+ # for Ruby 1.8
14
+ unless String.public_method_defined?(:force_encoding)
15
+ class String
16
+ def force_encoding(enc)
17
+ self
18
+ end
19
+ end
20
+
21
+ module Encoding
22
+ UTF_8 = nil
23
+ end
24
+ end
25
+
26
+ Termtter::Client::register_hook(
27
+ :name => :expand_tinyurl,
28
+ :point => :filter_for_output,
29
+ :exec_proc => lambda do |statuses, event|
30
+ shortters = URL_SHORTTERS + config.plugins.expand_tinyurl.shortters
31
+ skip_users = config.plugins.expand_tinyurl.skip_users
12
32
  statuses.each do |s|
13
- URL_SHORTTERS.each do |site|
33
+ skip_users.include?(s.user.screen_name) and next
34
+ shortters.each do |site|
14
35
  s.text.gsub!(site[:pattern]) do |m|
15
36
  expand_url(site[:host], $2) || $1
16
37
  end
@@ -18,7 +39,7 @@ module Termtter::Client
18
39
  end
19
40
  statuses
20
41
  end
21
- end
42
+ )
22
43
 
23
44
  def expand_url(host, path)
24
45
  http_class = Net::HTTP
@@ -30,5 +51,5 @@ def expand_url(host, path)
30
51
  end
31
52
  res = http_class.new(host).head(path)
32
53
  return nil unless res.code == "301" or res.code == "302"
33
- res['Location']
54
+ res['Location'].force_encoding(Encoding::UTF_8)
34
55
  end
@@ -0,0 +1,192 @@
1
+ # -*- coding: utf-8 -*
2
+
3
+ require 'tempfile'
4
+ require 'rubygems'
5
+ require 'giic'
6
+
7
+ module Termtter::Client
8
+ editor = ENV['EDITOR'] or
9
+ config.editor or
10
+ config.plugins.update_editor.editor
11
+ config.plugins.github_issues.set_default('editor', editor)
12
+
13
+ config.plugins.github_issues.set_default('user', 'jugyo')
14
+ config.plugins.github_issues.set_default('repo', 'termtter')
15
+
16
+ register_command('isearch', :alias => 'ise', :help => ['isearch, ise WORD', 'search issue']) do |word|
17
+ if word.empty?
18
+ warn 'need search word'
19
+ next
20
+ end
21
+ res = gi_project.search(word)
22
+ if res.has_key?('error')
23
+ warn 'failed'
24
+ next
25
+ end
26
+ no_length = res['issues'].map {|i| i.number.to_s.size }.max
27
+ list = res['issues'].map {|i| "##{i.number.to_s.ljust(no_length)} #{i.title}" }
28
+ list.empty? ? warn('no issue found') : puts(list.join("\n"))
29
+ end
30
+
31
+ register_command('ilist', :alias => 'il', :help => ['ilist, il', 'list all issues']) do |state|
32
+ state = state.empty? ? 'open' : state
33
+ list = gi_project.list(state)['issues']
34
+ no_length = list.map {|i| i.number.to_s.size }.max
35
+ list = list.map {|i| "##{i.number.to_s.ljust(no_length)} #{i.title}" }
36
+ puts list.join("\n")
37
+ end
38
+
39
+ register_command('ishow', :alias => 'is', :help => ['ishow,is NO', 'show specific issue']) do |no|
40
+ if no.empty?
41
+ warn 'need issue number'
42
+ next
43
+ end
44
+ res = gi_project.show(no.to_i)
45
+ if res.has_key?('error')
46
+ warn 'no such issue'
47
+ next
48
+ end
49
+ issue = res['issue']
50
+ label_length = issue.keys.map(&:size).max
51
+ issue.each do |key, value|
52
+ puts "#{key.rjust(label_length)}: #{value}"
53
+ end
54
+ end
55
+
56
+ register_command('iopen', :alias => 'io', :help => ['iopen,io TITLE', 'open new issue']) do |title|
57
+ if title.empty?
58
+ warn 'need issue title'
59
+ next
60
+ end
61
+ login
62
+ body = input_editor
63
+ res = login.open(title, body)
64
+ if res.has_key?('error')
65
+ warn 'failed'
66
+ next
67
+ end
68
+ res = res['issue']
69
+ label_length = res.keys.map(&:size).max
70
+ puts 'success:'
71
+ puts
72
+ res.each do |key, value|
73
+ puts "#{key.rjust(label_length)}: #{value}"
74
+ end
75
+ end
76
+
77
+ register_command('iedit', :alias => 'ie', :help => ['iedit,ie NO', 'edit issue']) do |no|
78
+ if no.empty?
79
+ warn 'need issue no'
80
+ next
81
+ end
82
+ no = no.to_i
83
+ target = gi_project.show(no)
84
+ if target.has_key?('error')
85
+ warn 'no such issue'
86
+ next
87
+ end
88
+ issue_body = target['issue']['body']
89
+ login
90
+ body = input_editor(issue_body)
91
+ res = login.edit(no, body)
92
+ if res.has_key?('error')
93
+ warn 'failed'
94
+ next
95
+ end
96
+ res = res['issue']
97
+ label_length = res.keys.map(&:size).max
98
+ puts 'success:'
99
+ puts
100
+ res.each do |key, value|
101
+ puts "#{key.rjust(label_length)}: #{value}"
102
+ end
103
+ end
104
+
105
+ register_command('icommand', :alias => 'icom', :help => ['icommand, icom NO', 'write comment to issue']) do |no|
106
+ if no.empty?
107
+ warn 'need issue no'
108
+ next
109
+ end
110
+ login
111
+ comment = input_editor
112
+ res = login.comment(no.to_i, comment)
113
+ res.has_key?('error') ? warn('failed') : puts('success')
114
+ end
115
+
116
+ register_command('ilabel', :alias => 'ilab', :help => ['ilabel,ilab (add | remove) LABEL NO', 'add or remove label to issue']) do |args|
117
+ op, label, no = args.split(/\s/)
118
+ unless [op, label, no].all?
119
+ warn 'need op, label, no'
120
+ next
121
+ end
122
+ case op
123
+ when 'add'
124
+ res = login.add_label(label, no)
125
+ res.has_key?('error') ? warn('failed') : puts('success')
126
+ when 'remove'
127
+ res = login.remove_label(label, no)
128
+ res.has_key?('error') ? warn('failed') : puts('success')
129
+ else
130
+ warn 'no such operate'
131
+ end
132
+ end
133
+
134
+ register_command('iclose', :alias => 'ic', :help => ['iclose,ic NO', 'close issue']) do |no|
135
+ if no.empty?
136
+ warn 'need issue title'
137
+ next
138
+ end
139
+ res = login.close(no.to_i)
140
+ res.has_key?('error') ? warn('failed') : puts('success')
141
+ end
142
+
143
+ register_command('ireopen', :alias => 'iro', :help => ['ireopen,ire NO', 'reopen closed issue']) do |no|
144
+ if no.empty?
145
+ warn 'need issue title'
146
+ next
147
+ end
148
+ res = login.reopen(no.to_i)
149
+ res.has_key?('error') ? warn('failed') : puts('success')
150
+ end
151
+
152
+ register_command('irepo', :alias => 'ir', :help => ['irepo, ir USER REPO', 'change user and repo']) do |user_repo|
153
+ user, repo = user_repo.split(/\s/)
154
+ unless [user, repo].all?
155
+ puts "now: user => #{gi_config.user}, repo => #{gi_config.repo}"
156
+ next
157
+ end
158
+ gi_config.user = user
159
+ gi_config.repo = repo
160
+ puts "changed: user => #{user}, repo => #{repo}"
161
+ end
162
+
163
+ private
164
+
165
+ def self.gi_config; config.plugins.github_issues end
166
+ def self.gi_project; Giic.new(gi_config.user, gi_config.repo) end
167
+
168
+ def self.login
169
+ if config.plugins.github_issues.login.empty?
170
+ print 'login > '; $stdout.flush
171
+ config.plugins.github_issues.login = gets.chomp
172
+ end
173
+ if config.plugins.github_issues.token.empty?
174
+ print 'token > '; $stdout.flush
175
+ config.plugins.github_issues.token = gets.chomp
176
+ end
177
+ gi_project.login(gi_config.login, gi_config.token)
178
+ end
179
+
180
+ def self.input_editor(body = nil)
181
+ file = Tempfile.new('termtter')
182
+ editor = config.plugins.github_issues.editor
183
+ file.write body if body
184
+ file.close
185
+ system("#{editor} #{file.path}")
186
+ result = file.open.read
187
+ file.flush
188
+ file.close(false)
189
+ result
190
+ end
191
+ end
192
+
data/lib/plugins/group.rb CHANGED
@@ -4,9 +4,9 @@ module Termtter
4
4
  class Status
5
5
  def is_member?(group = nil)
6
6
  if group
7
- config.plugins.group.groups[group].include? self.user_screen_name
7
+ config.plugins.group.groups[group].include? self.user.screen_name
8
8
  else
9
- config.plugins.group.groups.values.flatten.include? self.user_screen_name
9
+ config.plugins.group.groups.values.flatten.include? self.user.screen_name
10
10
  end
11
11
  end
12
12
  end
@@ -15,6 +15,8 @@ end
15
15
  module Termtter::Client
16
16
  config.plugins.group.
17
17
  set_default(:groups, {})
18
+ config.plugins.group.
19
+ set_default(:default_filter, nil)
18
20
 
19
21
  def self.find_group_candidates(a, b)
20
22
  config.plugins.group.groups.keys.map {|k| k.to_s}.
@@ -52,11 +54,35 @@ module Termtter::Client
52
54
  },
53
55
  :help => ['group,g GROUPNAME', 'Filter by group members']
54
56
  )
55
-
57
+
58
+ def self.is_member?(status, group = nil)
59
+ if group
60
+ config.plugins.group.groups[group].include? status.user.screen_name
61
+ else
62
+ config.plugins.group.groups.values.flatten.include? status.user.screen_name
63
+ end
64
+ end
65
+
66
+ register_hook(
67
+ :name => :group_filter,
68
+ :point => :filter_for_output,
69
+ :exec_proc => lambda do |statuses, event|
70
+ return statuses unless event == :update_friends_timeline
71
+ return statuses unless config.plugins.group.default_filter
72
+ skip_group = config.plugins.group.default_filter
73
+ r = []
74
+ statuses.each do |s|
75
+ unless self.is_member?(s, :dqn)
76
+ r << s
77
+ end
78
+ end
79
+ r
80
+ end
81
+ )
56
82
  end
57
83
 
58
84
  # group.rb
59
- # plugin 'group'
85
+ # t.plug 'group'
60
86
  # config.plugins.group.groups = {
61
87
  # :rits => %w(hakobe isano hitode909)
62
88
  # }
data/lib/plugins/growl.rb CHANGED
@@ -13,6 +13,8 @@ rescue LoadError
13
13
  growl = nil
14
14
  end
15
15
 
16
+ config.plugins.growl.set_default(:sticky, false)
17
+ config.plugins.growl.set_default(:priority, 0)
16
18
  config.plugins.growl.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
17
19
  FileUtils.mkdir_p(config.plugins.growl.icon_cache_dir) unless File.exist?(config.plugins.growl.icon_cache_dir)
18
20
 
@@ -41,9 +43,16 @@ Termtter::Client.register_hook(
41
43
  Thread.start do
42
44
  statuses.each do |s|
43
45
  unless growl
46
+ # TODO: Add option for priority and sticky
44
47
  system 'growlnotify', s.user.screen_name, '-m', s.text.gsub("\n",''), '-n', 'termtter', '--image', get_icon_path(s)
45
48
  else
46
- growl.notify "update_friends_timeline", s.user.screen_name, CGI.unescapeHTML(s.text)
49
+ growl.notify(
50
+ "update_friends_timeline",
51
+ s.user.screen_name,
52
+ CGI.unescapeHTML(s.text),
53
+ config.plugins.growl.priority,
54
+ config.plugins.growl.sticky
55
+ )
47
56
  end
48
57
  sleep 0.1
49
58
  end
Binary file
@@ -0,0 +1,117 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <title>Termtter</title>
6
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
7
+ </head>
8
+ <style type="text/css">
9
+ body {
10
+ margin: 0;
11
+ padding: 0;
12
+ font-size: 12px;
13
+ font-family: Verdana,Helvetica;
14
+ color: #98FF68;
15
+ background-color: #141414;
16
+ }
17
+ img {
18
+ border: none;
19
+ }
20
+ #wrap {
21
+ padding: 8px;
22
+ }
23
+ .error_message {
24
+ color: red;
25
+ }
26
+ #execute_text {
27
+ width: 96%;
28
+ color: #98FF68;
29
+ background-color: #141414;
30
+ border: none;
31
+ font-size: 12px;
32
+ }
33
+ .status_line {
34
+ margin: 1px 0;
35
+ }
36
+ .profile_image {
37
+ margin: 0 4px;
38
+ }
39
+ .status_info {
40
+ color: #5C5C5C;
41
+ }
42
+ .status_text {
43
+ margin-right: 4px;
44
+ }
45
+ </style>
46
+ <body>
47
+ <div id="wrap">
48
+ <div id="result"></div>
49
+ <div id="input_area">
50
+ <form id="execute_command">
51
+ <span id="prompt">&gt; </span><input id="execute_text" type="text" size="80" autocomplete=off />
52
+ </form>
53
+ </div>
54
+ <div id="loading" style="display: none;">...</div>
55
+ </div>
56
+ <script type="text/javascript">
57
+ <!--
58
+ $(document).ready(function(){
59
+ $("#execute_text").focus();
60
+ execute_command('reload.html');
61
+ setInterval(function(){
62
+ execute_command('reload.html');
63
+ }, 10 * 1000)
64
+ })
65
+
66
+ $("#result").bind("ajaxError", function(event, reqest){
67
+ $('<div class="error_message"/>').text(reqest.responseText).appendTo(this);
68
+ scrollTo(0, document.height);
69
+ $("#prompt").show();
70
+ });
71
+
72
+ $("#execute_command").submit(function () {
73
+ var command = $("#execute_text").val();
74
+ $('<div class="status_line"/>').text('> ' + command).appendTo('#result');
75
+ scrollTo(0, document.height);
76
+ if (command.match(/^\s*$/)) {
77
+ return false;
78
+ }
79
+ $("#execute_text").val('');
80
+ $("#prompt").hide();
81
+ execute_command(command);
82
+ return false;
83
+ });
84
+
85
+ function execute_command(command) {
86
+ var path = "/" + command
87
+ $.getJSON(path,
88
+ function(data){
89
+ $.each(data, function(i, status){
90
+ var status_line = $('<div class="status_line"/>');
91
+ $('<span class="status_info"/>').text('(' + format_datetime(status.created_at) + ') ').appendTo(status_line);
92
+ var user_link = $('<a/>').attr('href', 'http://twitter.com/' + status.user.screen_name).attr('target', '_blank');
93
+ $('<img class="profile_image"/>').attr('src', status.user.profile_image_url).attr('height', '14').attr('width', '14').appendTo(user_link);
94
+ user_link.appendTo(status_line);
95
+ $('<span class="status_text"/>').text(' ' + status.user.screen_name + ': ' + status.text).appendTo(status_line);
96
+ $('<span class="status_info"/>').text(' ' + status.id).appendTo(status_line);
97
+ status_line.appendTo("#result");
98
+ });
99
+ scrollTo(0, document.height);
100
+ $("#prompt").show();
101
+ }
102
+ );
103
+ }
104
+
105
+ function format_datetime(time_value) {
106
+ var values = time_value.split(/\s+/);
107
+ time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
108
+ var date = new Date(time_value);
109
+ date.setMinutes(date.getMinutes() - (new Date()).getTimezoneOffset());
110
+ return (date.getHours() < 10 ? '0' : '') + date.getHours() + ':' +
111
+ (date.getMinutes() < 10 ? '0' : '') + date.getMinutes() + ':' +
112
+ (date.getSeconds() < 10 ? '0' : '') + date.getSeconds();
113
+ }
114
+ -->
115
+ </script>
116
+ </body>
117
+ </html>
@@ -0,0 +1,82 @@
1
+ # http_server
2
+ #
3
+ # = REQUIREMENTS
4
+ # * mime-types
5
+ # * rubytter >= 0.8.0 (for web client)
6
+ #
7
+
8
+ require 'mime/types'
9
+ require 'pathname'
10
+ require 'webrick'
11
+ require 'logger'
12
+
13
+ config.plugins.http_server.set_default(:port, 5678)
14
+ config.plugins.http_server.set_default(:reload_max_count, 100)
15
+
16
+ module Termtter::Client
17
+ if @http_server
18
+ @http_server.shutdown # for reload
19
+ end
20
+
21
+ @http_server_statuses_store = []
22
+
23
+ register_hook(:http_server_output, :point => :output) do |statuses, event|
24
+ @http_server_output = statuses.to_json
25
+ if event == :update_friends_timeline
26
+ @http_server_statuses_store += statuses
27
+ max = config.plugins.http_server.reload_max_count
28
+ if @http_server_statuses_store.size > max
29
+ from = @http_server_statuses_store.size - max
30
+ @http_server_statuses_store = @http_server_statuses_store[from..-1]
31
+ end
32
+ end
33
+ end
34
+
35
+ register_hook(:http_server_shutdown, :point => :exit) do
36
+ @http_server.shutdown
37
+ end
38
+
39
+ @http_server_logger = Logger.new(nil)
40
+ @http_server_logger.level = Logger::WARN
41
+ @http_server = WEBrick::HTTPServer.new(
42
+ :BindAddress => '127.0.0.1',
43
+ :Port => config.plugins.http_server.port,
44
+ :Logger => @http_server_logger,
45
+ :AccessLog => []
46
+ )
47
+
48
+ @http_server.mount_proc('/reload.html') do |req, res|
49
+ # MEMO: ブラウザで画面を二つ開いてるとデータの取り合いになっておかしな感じになる。。。
50
+ res['Content-Type'] = 'text/javascript; charset=utf-8';
51
+ res.body = @http_server_statuses_store.to_json
52
+ @http_server_statuses_store.clear
53
+ end
54
+
55
+ @http_server.mount_proc('/') do |req, res|
56
+ request_path = req.path == '/' ? 'index.html' : req.path
57
+ base_name = Pathname.new(request_path).basename.to_s
58
+ file_path = File.dirname(__FILE__) + '/http_server/' + base_name
59
+
60
+ if File.file?(file_path)
61
+ # send a file
62
+ res.header["Content-Type"] = MIME::Types.type_for(file_path).first.content_type
63
+ res.body = File.open(file_path, 'rb').read
64
+ else
65
+ # execute a command
66
+ @http_server_output = ''
67
+ begin
68
+ command = req.path.sub(/^\//, '')
69
+ call_commands(command)
70
+ res['Content-Type'] = 'text/javascript; charset=utf-8';
71
+ res.body = @http_server_output
72
+ rescue Termtter::CommandNotFound => e
73
+ res.status = 404
74
+ res.body = "Command Not Found!!"
75
+ end
76
+ end
77
+ end
78
+
79
+ Thread.start do
80
+ @http_server.start
81
+ end
82
+ end
@@ -0,0 +1,6 @@
1
+ require 'irb'
2
+ Termtter::Client.register_command(:irb) do |*args|
3
+ args.unshift('irb')
4
+ args.delete_if{|i| i == ""}
5
+ system *args
6
+ end
data/lib/plugins/l2.rb CHANGED
@@ -21,5 +21,5 @@ module Termtter::Client
21
21
  end
22
22
 
23
23
  # l2.rb
24
- # plugin 'l2'
24
+ # t.plug 'l2'
25
25
  # NOTE: l2.rb needs plugin/log
@@ -24,9 +24,6 @@ module Termtter::Client
24
24
  end
25
25
  output(statuses, event)
26
26
  },
27
- :completion_proc => lambda {|cmd, arg|
28
- find_user_candidates arg, "#{cmd} %s"
29
- },
30
27
  :help => ["list,l [USERNAME]", "List the posts"]
31
28
  )
32
29
  end
data/lib/plugins/log.rb CHANGED
@@ -34,8 +34,8 @@ module Termtter::Client
34
34
  )
35
35
 
36
36
  register_command(
37
- :name => :log,
38
- :exec_proc => lambda{|arg|
37
+ :name => :log,
38
+ :exec_proc => lambda{|arg|
39
39
  if arg.empty?
40
40
  # log
41
41
  statuses = public_storage[:log]
@@ -44,19 +44,16 @@ module Termtter::Client
44
44
  output(statuses[-print_max..-1], :search)
45
45
  else
46
46
  # log (user) (max)
47
- vars = arg.split(' ')
47
+ vars = arg.split(/\s/).map{ |i| normalize_as_user_name(i) }
48
48
  print_max = vars.last =~ /^\d+$/ ? vars.pop.to_i : config.plugins.log.print_max_size
49
49
  id = vars
50
50
  statuses = id.first ? public_storage[:log].select{ |s| id.include? s.user.screen_name} : public_storage[:log]
51
51
  print_max = 0 if statuses.size < print_max
52
52
  output(statuses[-print_max..-1], :search)
53
53
  end
54
- },
55
- :completion_proc => lambda {|cmd, arg|
56
- find_user_candidates arg, "#{cmd} %s"
57
- },
58
- :help => [ 'log (USER(S)) (MAX)', 'Show local log of the user(s)']
59
- )
54
+ },
55
+ :help => [ 'log (USER(S)) (MAX)', 'Show local log of the user(s)']
56
+ )
60
57
 
61
58
  register_command(
62
59
  :name => :search_log, :aliases => [:sl],
@@ -1,7 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- Termtter::Client.register_hook(
4
- :name => :modify_arg_hook_sample,
5
- :points => [:modify_arg_for_update],
6
- :exec_proc => lambda {|cmd, arg| arg + '\(^o^)/'}
7
- )
3
+ Termtter::Client.register_hook(:modify_arg_hook_sample, :point => :modify_arg_for_update) do |cmd, arg|
4
+ arg + ' \(^o^)/'
5
+ end
@@ -17,11 +17,6 @@ module Termtter::Client
17
17
  end
18
18
  end
19
19
  },
20
- :completion_proc => lambda {|cmd, args|
21
- if /(.*)@([^\s]*)$/ =~ args
22
- find_user_candidates $2, "#{cmd} #{$1}@%s"
23
- end
24
- },
25
20
  :help => ["multi_reply,mp TEXT", "Reply to multi user"]
26
21
  )
27
22
  end
@@ -15,7 +15,7 @@ Termtter::Client.register_hook(
15
15
 
16
16
  text << %Q|\n<a href="http://twitter.com/">more...</a>| if statuses.size > max
17
17
 
18
- system 'notify-send', 'Termtter', text, '-t', '60000'
18
+ system 'notify-send', '-t', '60000', '--', 'Termtter', text
19
19
  end
20
20
  }
21
21
  )
@@ -43,7 +43,7 @@ Termtter::Client.register_hook(
43
43
  statuses.each do |s|
44
44
  text = CGI.escapeHTML(s.text)
45
45
  text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
46
- system 'notify-send', s.user.screen_name, text, '-i', get_icon_path(s)
46
+ system 'notify-send', '-i', get_icon_path(s), '--', s.user.screen_name, text
47
47
  sleep 0.1
48
48
  end
49
49
  end
@@ -14,11 +14,19 @@ def get_icon_path(s)
14
14
  if !File.exist?(cache_file) || (File.atime(cache_file) + 24*60*60) < Time.now
15
15
  File.open(cache_file, "wb") do |f|
16
16
  begin
17
- image = open(URI.escape(s.user.profile_image_url)).read
17
+ http_class = Net::HTTP
18
+ unless config.proxy.host.nil? or config.proxy.host.empty?
19
+ http_class = Net::HTTP::Proxy(config.proxy.host,
20
+ config.proxy.port,
21
+ config.proxy.user_name,
22
+ config.proxy.password)
23
+ end
24
+ uri = URI.parse(URI.escape(s.user.profile_image_url))
25
+ image = http_class.get(uri.host, uri.path, uri.port)
18
26
  rimage = Magick::Image.from_blob(image).first
19
27
  rimage = rimage.resize_to_fill(48, 48)
20
28
  f << rimage.to_blob
21
- rescue OpenURI::HTTPError
29
+ rescue Net::ProtocolError
22
30
  return nil
23
31
  end
24
32
  end
@@ -37,7 +45,7 @@ Termtter::Client.register_hook(
37
45
  text = %Q{"#{text}"} if text =~ /^-/
38
46
  text.gsub!(URI.regexp,'<a href="\0">\0</a>')
39
47
  begin
40
- system 'notify-send', s.user.screen_name, text, '-i', get_icon_path(s)
48
+ system 'notify-send', '-i', get_icon_path(s), '--', s.user.screen_name, text
41
49
  sleep 0.05
42
50
  rescue
43
51
  end