jugyo-termtter 1.0.7 → 1.0.8

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.
@@ -0,0 +1,47 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Termtter::Client
3
+ class << self
4
+ def delete_command(arg)
5
+ if @commands.delete(arg.to_sym)
6
+ puts "#{arg} command is deleted."
7
+ else
8
+ raise "#{arg} command is not found."
9
+ end
10
+ end
11
+
12
+ def alias_command(arg)
13
+ original, new = arg.split(/\s+/)
14
+ if @commands[original.to_sym]
15
+ @commands[new.to_sym] = @commands[original.to_sym].clone
16
+ @commands[new.to_sym].name = new.to_sym
17
+ @commands[new.to_sym].aliases = []
18
+ @commands[new.to_sym].help = ''
19
+ puts "alias '#{original}' to '#{new}'."
20
+ else
21
+ raise "#{original} command is not found."
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ module Termtter::Client
28
+ register_command(
29
+ :name => :delete_command,
30
+ :exec_proc => lambda {|arg|
31
+ Termtter::Client.delete_command(arg)
32
+ },
33
+ :completion_proc => lambda {|cmd, arg|
34
+ },
35
+ :help => ['delete_command command', 'delete command from command list (this command is experimental!)']
36
+ )
37
+
38
+ register_command(
39
+ :name => :alias_command,
40
+ :exec_proc => lambda {|arg|
41
+ Termtter::Client.alias_command(arg)
42
+ },
43
+ :completion_proc => lambda {|cmd, arg|
44
+ },
45
+ :help => ['alias_command A B', 'alias command A to B (this command is experimental!)']
46
+ )
47
+ end
@@ -1,12 +1,33 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ config.plugins.confirm.set_default(:commands, [:update, :reply, :direct])
4
+ config.plugins.confirm.set_default(
5
+ :conditions,
6
+ [
7
+ lambda { |cmd_name, arg|
8
+ if cmd_name == :direct && arg =~ /^(list|sent_list)$/
9
+ false
10
+ else
11
+ true
12
+ end
13
+ }
14
+ ]
15
+ )
16
+
3
17
  Termtter::Client.register_hook(
4
18
  :name => :confirm,
5
- :points => [:pre_exec_update],
19
+ :points => [/^pre_exec_/],
6
20
  :exec_proc => lambda {|cmd, arg|
7
- if /^y?$/i !~ Readline.readline("update? #{arg} [Y/n] ", false)
8
- puts 'canceled.'
9
- raise Termtter::CommandCanceled
21
+ if config.plugins.confirm.commands.include?(cmd.name) &&
22
+ config.plugins.confirm.conditions.any? { |cond| cond.call(cmd.name, arg) }
23
+
24
+ prompt = "\"#{cmd.name} #{arg}".strip + "\" [Y/n] "
25
+
26
+ if /^y?$/i !~ Readline.readline(prompt, false)
27
+ puts 'canceled.'
28
+ raise Termtter::CommandCanceled
29
+ end
30
+
10
31
  end
11
32
  }
12
33
  )
@@ -0,0 +1,23 @@
1
+ module Termtter::Client
2
+ register_command(
3
+ :name => :countter,
4
+ :exec_proc => lambda {|arg|
5
+ count = {}
6
+ public_storage[:log].each do |l|
7
+ source = l.source =~ /(?:<a href=\".+?\">)(.+)(?:<\/a>)/ ? $1 : l.source
8
+ count[source] = 0 unless count[source]
9
+ count[source] += 1
10
+ end
11
+
12
+ format = "%24s %6s"
13
+ puts format % %w(sources count)
14
+ puts format % ['-'*24, '-'*6]
15
+ count.to_a.sort{|a,b|b[1]<=>a[1]}.each do |k,v|
16
+ puts format % [k, v]
17
+ end
18
+ },
19
+ :completion_proc => lambda {|cmd, arg|
20
+ },
21
+ :help => ['countter', 'count sources']
22
+ )
23
+ end
data/lib/plugins/devel.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ begin
4
+ require 'ruby-debug'
5
+ rescue LoadError
6
+ end
7
+
3
8
  module Termtter::Client
4
9
  register_command(
5
10
  :name => :eval,
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Termtter::Client
3
+ register_command(
4
+ :name => :direct_messages,
5
+ :aliases => [:ds],
6
+ :exec_proc => lambda {|arg|
7
+ event = :list_user_timeline
8
+ ds = Termtter::API.twitter.direct_messages
9
+ DM = Struct.new :id, :text, :user, :created_at, :in_reply_to_status_id
10
+ statuses = ds.map do |d|
11
+ DM.new(d.id, d.text, d.sender, d.created_at)
12
+ end
13
+ output(statuses, event)
14
+ },
15
+ :completion_proc => lambda {|cmd, arg|
16
+ },
17
+ :help => ['direct_messages,ds', 'List direct messages for you']
18
+ )
19
+
20
+ register_command(
21
+ :name => :sent_direct_messages,
22
+ :aliases => [:sds],
23
+ :exec_proc => lambda {|arg|
24
+ event = :list_user_timeline
25
+ ds = Termtter::API.twitter.sent_direct_messages
26
+ DM = Struct.new :id, :text, :user, :created_at, :in_reply_to_status_id
27
+ statuses = ds.map do |d|
28
+ DM.new(d.id, "@#{d.recipient.screen_name} #{d.text}", d.sender, d.created_at)
29
+ end
30
+ output(statuses, event)
31
+ },
32
+ :completion_proc => lambda {|cmd, arg|
33
+ },
34
+ :help => ['sent_direct_messages, sds', 'List direct messages from you']
35
+ )
36
+ end
data/lib/plugins/erb.rb CHANGED
@@ -4,7 +4,7 @@ require 'erb'
4
4
 
5
5
  Termtter::Client.register_hook(
6
6
  :name => :erb,
7
- :points => [:pre_exec_update],
7
+ :point => :modify_arg_for_update,
8
8
  :exec_proc => lambda {|cmd, arg|
9
9
  ERB.new(arg).result(binding)
10
10
  }
@@ -0,0 +1,17 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ register_command(
5
+ :name => :exec,
6
+ :exec_proc => lambda{|arg|
7
+ return unless arg
8
+ begin
9
+ pause
10
+ system *arg.split(/\s+/)
11
+ ensure
12
+ resume
13
+ end
14
+ },
15
+ :help => ['exec SHELL_COMMAND', 'execute a shell command']
16
+ )
17
+ end
@@ -0,0 +1,14 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Termtter::Client.register_command(
4
+ :name => :exec_and_update,
5
+ :exec_proc => lambda{|arg|
6
+ return unless arg
7
+ `#{arg}`.each_line do |line|
8
+ next if line =~ /^\s*$/
9
+ Termtter::API.twitter.update(line)
10
+ puts "=> #{line}"
11
+ end
12
+ },
13
+ :help => ['exec_and_update COMMAND', 'execute the command']
14
+ )
@@ -0,0 +1,143 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'open-uri'
4
+ require 'uri'
5
+ require 'fileutils'
6
+ require 'cgi'
7
+
8
+ begin
9
+ require 'meow'
10
+ growl = Meow.new('termtter', 'update_friends_timeline')
11
+ rescue LoadError
12
+ growl = nil
13
+ end
14
+
15
+ config.plugins.growl.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
16
+ config.plugins.growl.set_default(:growl_user, [])
17
+ config.plugins.growl.set_default(:growl_keyword, [])
18
+ config.plugins.growl.set_default(:priority_veryhigh_user, [])
19
+ config.plugins.growl.set_default(:priority_high_user, [])
20
+ config.plugins.growl.set_default(:priority_normal_user, [])
21
+ config.plugins.growl.set_default(:priority_low_user, [])
22
+ config.plugins.growl.set_default(:priority_verylow_user, [])
23
+ config.plugins.growl.set_default(:priority_veryhigh_keyword, [])
24
+ config.plugins.growl.set_default(:priority_high_keyword, [])
25
+ config.plugins.growl.set_default(:priority_normal_keyword, [])
26
+ config.plugins.growl.set_default(:priority_low_keyword, [])
27
+ config.plugins.growl.set_default(:priority_verylow_keyword, [])
28
+ config.plugins.growl.set_default(:sticky_user, [])
29
+ config.plugins.growl.set_default(:sticky_keyword, [])
30
+ growl_keys = { 'user' => config.plugins.growl.growl_user,
31
+ 'keyword' => Regexp.union(*config.plugins.growl.growl_keyword) }
32
+ priority_keys = { 'user' => [config.plugins.growl.priority_veryhigh_user,
33
+ config.plugins.growl.priority_high_user,
34
+ config.plugins.growl.priority_normal_user,
35
+ config.plugins.growl.priority_low_user,
36
+ config.plugins.growl.priority_verylow_user],
37
+ 'keyword' => [Regexp.union(*config.plugins.growl.priority_veryhigh_keyword),
38
+ Regexp.union(*config.plugins.growl.priority_high_keyword),
39
+ Regexp.union(*config.plugins.growl.priority_normal_keyword),
40
+ Regexp.union(*config.plugins.growl.priority_low_keyword),
41
+ Regexp.union(*config.plugins.growl.priority_verylow_keyword) ] }
42
+ sticky_keys = { 'user' => config.plugins.growl.sticky_user,
43
+ 'keyword' => Regexp.union(*config.plugins.growl.sticky_keyword) }
44
+
45
+ FileUtils.mkdir_p(config.plugins.growl.icon_cache_dir) unless File.exist?(config.plugins.growl.icon_cache_dir)
46
+ Dir.glob("#{config.plugins.growl.icon_cache_dir}/*") {|f| File.delete(f) unless File.size?(f) }
47
+ unless File.exist?("#{config.plugins.growl.icon_cache_dir}/default.png")
48
+ File.open("#{config.plugins.growl.icon_cache_dir}/default.png", "wb") do |f|
49
+ f << open("http://static.twitter.com/images/default_profile_normal.png").read
50
+ end
51
+ end
52
+
53
+ def get_icon_path(s)
54
+ /https?:\/\/.+\/(\d+)\/.*?$/ =~ s.user.profile_image_url
55
+ cache_file = "%s/%s-%s%s" % [ config.plugins.growl.icon_cache_dir,
56
+ s.user.screen_name,
57
+ $+,
58
+ File.extname(s.user.profile_image_url) ]
59
+ unless File.exist?(cache_file)
60
+ Thread.new(s,cache_file) do |s,cache_file|
61
+ Dir.glob("#{config.plugins.growl.icon_cache_dir}/#{s.user.screen_name}-*") {|f| File.delete(f) }
62
+ begin
63
+ s.user.profile_image_url.sub!(/^https/,'http')
64
+ File.open(cache_file, 'wb') do |f|
65
+ f << open(URI.escape(s.user.profile_image_url)).read
66
+ end
67
+ rescue OpenURI::HTTPError
68
+ cache_file = "#{config.plugins.growl.icon_cache_dir}/default.png"
69
+ end
70
+ end
71
+ end
72
+ return cache_file
73
+ end
74
+
75
+ def get_priority(s,priority_keys)
76
+ priority = 2
77
+ 5.times {|n|
78
+ return priority.to_s if priority_keys['user'][n].include?(s.user.screen_name) ||
79
+ priority_keys['keyword'][n] =~ s.text
80
+ priority -= 1
81
+ }
82
+ return '0'
83
+ end
84
+
85
+ def is_growl(s,growl_keys)
86
+ return true if (growl_keys['user'].empty? && growl_keys['keyword'] == /(?!)/) ||
87
+ (growl_keys['user'].include?(s.user.screen_name) || growl_keys['keyword'] =~ s.text)
88
+ return false
89
+ end
90
+
91
+ def is_sticky(s,sticky_keys)
92
+ return true if sticky_keys['user'].include?(s.user.screen_name) || sticky_keys['keyword'] =~ s.text
93
+ return false
94
+ end
95
+
96
+ Termtter::Client.register_hook(
97
+ :name => :growl2,
98
+ :points => [:output],
99
+ :exec_proc => lambda {|statuses, event|
100
+ return unless event == :update_friends_timeline
101
+ Thread.start do
102
+ statuses.each do |s|
103
+ next unless is_growl(s,growl_keys)
104
+ growl_title = s.user.screen_name
105
+ growl_title += " (#{s.user.name})" unless s.user.screen_name == s.user.name
106
+ unless growl
107
+ arg = ['growlnotify', growl_title, '-m', s.text.gsub("\n",''), '-n', 'termtter', '-p', get_priority(s,priority_keys), '--image', get_icon_path(s)]
108
+ arg.push('-s') if is_sticky(s,sticky_keys)
109
+ system *arg
110
+ else
111
+ begin
112
+ icon = Meow.import_image(get_icon_path(s))
113
+ rescue
114
+ icon = Meow.import_image("#{config.plugins.growl.icon_cache_dir}/default.png")
115
+ end
116
+ growl.notify(growl_title, CGI.unescape(CGI.unescapeHTML(s.text)),
117
+ {:icon => icon,
118
+ :priority => get_priority(s,priority_keys),
119
+ :sticky => is_sticky(s,sticky_keys) }) do
120
+ s.text.gsub(URI.regexp) {|uri| system "open #{uri}"}
121
+ end
122
+ end
123
+ sleep 0.1
124
+ end
125
+ end
126
+ }
127
+ )
128
+ #Optional setting example.
129
+ # Growl ON setting.
130
+ # config.plugins.growl.growl_user = ['p2pquake', 'jihou']
131
+ # config.plugins.growl.growl_keyword = ['地震', /^@screen_name/]
132
+ # Priority setting.
133
+ # config.plugins.growl.priority_veryhigh_user = ['veryhigh_user']
134
+ # config.plugins.growl.priority_veryhigh_keyword = ['veryhigh_keyword', /^@screen_name']
135
+ # config.plugins.growl.priority_high_user = ['high_user']
136
+ # config.plugins.growl.priority_high_keyword = ['high_keyword']
137
+ # config.plugins.growl.priority_low_user = ['low_user']
138
+ # config.plugins.growl.priority_low_keyword = ['low_keyword']
139
+ # config.plugins.growl.priority_verylow_user = ['verylow_user']
140
+ # config.plugins.growl.priority_verylow_keyword = ['verylow_keyword']
141
+ # Sticky setting.
142
+ # config.plugins.growl.sticky_user = ['screen_name']
143
+ # config.plugins.growl.sticky_keyword = [/^@screen_name/, '#termtter']
@@ -43,10 +43,10 @@ module Termtter::Client
43
43
  },
44
44
  :completion_proc => lambda {|cmd, args|
45
45
  if args =~ /^(\d*)$/
46
- find_status_id_candidates $1, "#{cmd} %s"
46
+ find_status_ids($1){|id| "#{cmd} #{id}"}
47
47
  end
48
48
  },
49
- :help => ['hatebu ID', 'Hatena bookmark a status']
49
+ :help => ['hatebu ID', 'Hatena bookmark a status']
50
50
  )
51
51
  end
52
52
 
@@ -0,0 +1,58 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'atomutil'
5
+ require 'nokogiri'
6
+
7
+ module Termtter::Client
8
+ register_command(
9
+ :name => :hatebu_and_update, :aliases => [:hau],
10
+ :exec_proc => lambda {|arg|
11
+ url, comment = arg.split(/\s/)
12
+ if url =~ URI.regexp
13
+ auth = auth = Atompub::Auth::Wsse.new({
14
+ :username => config.plugins.hatebu.username,
15
+ :password => config.plugins.hatebu.password,
16
+ })
17
+ link = Atom::Link.new({
18
+ :href => url,
19
+ :rel => 'related',
20
+ :type => 'text/html',
21
+ })
22
+ entry = Atom::Entry.new({
23
+ :link => link,
24
+ :title => 'dummy',
25
+ :summary => comment,
26
+ })
27
+ req = Net::HTTP::Post.new 'http://b.hatena.ne.jp/atom/post'
28
+ req['User-Agent'] = 'Mozilla/5.0'
29
+ req['Content-Type'] = 'application/atom+xml'
30
+ req['Slug'] = 'termtter'
31
+ req.body = entry.to_s
32
+ auth.authorize(req)
33
+ title = nil
34
+ tinyurl = nil
35
+ Termtter::API.connection.start('b.hatena.ne.jp', 80) do |http|
36
+ res = http.request(req)
37
+ title = Nokogiri::XML(res.body).search('link[title]').first['title'] rescue nil
38
+ end
39
+ if title
40
+ Termtter::API.connection.start('tinyurl.com', 80) do |http|
41
+ tinyurl = http.get('/api-create.php?url=' + URI.escape(url)).body
42
+ end
43
+
44
+ Termtter::API.twitter.update("[はてぶ] #{title} #{tinyurl}")
45
+ end
46
+ end
47
+ },
48
+ :help => ['hatebu2 URL', 'Hatena bookmark a URL, and update']
49
+ )
50
+ end
51
+
52
+ # hatebu.rb
53
+ # hatena bookmark it, and post
54
+ #
55
+ # config.plugins.hatebu.username = 'your-username-on-hatena'
56
+ # config.plugins.hatebu.password = 'your-password-on-hatena'
57
+ #
58
+ # hatebu_and_update http://www.yahoo.co.jp/ [yahoo]
data/lib/plugins/l2.rb ADDED
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Termtter::Client
4
+ register_command(
5
+ :name => :list2,
6
+ :aliases => [:l2],
7
+ :exec_proc => lambda {|arg|
8
+ unless arg.empty?
9
+ targets = arg.split.uniq
10
+ statuses = targets ? targets.map { |target|
11
+ public_storage[:tweet][target]
12
+ }.flatten.uniq.compact.sort_by{ |s| s[:id]} : []
13
+ output(statuses, :search)
14
+ end
15
+ },
16
+ :completion_proc => lambda {|cmd, arg|
17
+ #todo
18
+ },
19
+ :help => ['list2,l2 A B (C..)', "List statuses of A's and B's (and C's..)"]
20
+ )
21
+ end
22
+
23
+ # l2.rb
24
+ # plugin 'l2'
25
+ # NOTE: l2.rb needs plugin/log
@@ -2,23 +2,36 @@
2
2
 
3
3
  require 'fileutils'
4
4
 
5
- # notify-send.rb からコピペ。共通化したいところ。
6
5
  config.plugins.notify_send.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
6
+
7
+ FileUtils.mkdir_p(config.plugins.notify_send.icon_cache_dir) unless File.exist?(config.plugins.notify_send.icon_cache_dir)
8
+ Dir.glob("#{config.plugins.notify_send.icon_cache_dir}/*") {|f| File.delete(f) unless File.size?(f) }
9
+ unless File.exist?("#{config.plugins.notify_send.icon_cache_dir}/default.png")
10
+ File.open("#{config.plugins.notify_send.icon_cache_dir}/default.png", "wb") do |f|
11
+ f << open("http://static.twitter.com/images/default_profile_normal.png").read
12
+ end
13
+ end
14
+
7
15
  def get_icon_path(s)
8
- FileUtils.mkdir_p(config.plugins.notify_send.icon_cache_dir) unless File.exist?(config.plugins.notify_send.icon_cache_dir)
9
- cache_file = "%s/%s%s" % [ config.plugins.notify_send.icon_cache_dir,
10
- s.user.screen_name,
11
- File.extname(s.user.profile_image_url) ]
12
- if !File.exist?(cache_file) || (File.atime(cache_file) + 24*60*60) < Time.now
13
- File.open(cache_file, "wb") do |f|
16
+ /https?:\/\/.+\/(\d+)\/.*?$/ =~ s.user.profile_image_url
17
+ cache_file = "%s/%s-%s%s" % [ config.plugins.notify_send.icon_cache_dir,
18
+ s.user.screen_name,
19
+ $+,
20
+ File.extname(s.user.profile_image_url) ]
21
+ unless File.exist?(cache_file)
22
+ Thread.new(s,cache_file) do |s,cache_file|
23
+ Dir.glob("#{config.plugins.notify_send.icon_cache_dir}/#{s.user.screen_name}-*") {|f| File.delete(f) }
14
24
  begin
15
- f << open(URI.escape(s.user.profile_image_url)).read
25
+ s.user.profile_image_url.sub!(/^https/,'http')
26
+ File.open(cache_file, 'wb') do |f|
27
+ f << open(URI.escape(s.user.profile_image_url)).read
28
+ end
16
29
  rescue OpenURI::HTTPError
17
- return nil
30
+ cache_file = "#{config.plugins.notify_send.icon_cache_dir}/default.png"
18
31
  end
19
32
  end
20
33
  end
21
- cache_file
34
+ return cache_file
22
35
  end
23
36
 
24
37
  Termtter::Client.register_hook(
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'fileutils'
4
+ require 'RMagick'
5
+
6
+ # Copy from notify-send2.rb
7
+ config.plugins.notify_send.set_default(:icon_cache_dir, "#{Termtter::CONF_DIR}/tmp/user_profile_images")
8
+ def get_icon_path(s)
9
+ FileUtils.mkdir_p(config.plugins.notify_send.icon_cache_dir) unless File.exist?(config.plugins.notify_send.icon_cache_dir)
10
+ cache_file = "%s/%s%s" % [ config.plugins.notify_send.icon_cache_dir,
11
+ s.user.screen_name,
12
+ File.extname(s.user.profile_image_url) ]
13
+ if !File.exist?(cache_file) || (File.atime(cache_file) + 24*60*60) < Time.now
14
+ File.open(cache_file, "wb") do |f|
15
+ begin
16
+ image = open(URI.escape(s.user.profile_image_url)).read
17
+ rimage = Magick::Image.from_blob(image).first
18
+ rimage = rimage.resize_to_fill(48, 48)
19
+ f << rimage.to_blob
20
+ rescue OpenURI::HTTPError
21
+ return nil
22
+ end
23
+ end
24
+ end
25
+ cache_file
26
+ end
27
+
28
+ Termtter::Client.register_hook(
29
+ :name => :notify_send3,
30
+ :points => [:output],
31
+ :exec_proc => lambda {|statuses, event|
32
+ return unless event == :update_friends_timeline
33
+ Thread.start do
34
+ statuses.each do |s|
35
+ text = CGI.escapeHTML(s.text)
36
+ text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
37
+ system 'notify-send', s.user.screen_name, text, '-i', get_icon_path(s)
38
+ sleep 0.1
39
+ end
40
+ end
41
+ }
42
+ )
43
+
44
+ # notify-send3.rb
45
+ # caching resized profile image.
@@ -0,0 +1,59 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'uri'
4
+
5
+ module Termtter::Client
6
+ def self.open_uri(uri)
7
+ unless config.plugins.open_url.browser.empty?
8
+ system config.plugins.open_url.browser, uri
9
+ else
10
+ case RUBY_PLATFORM
11
+ when /linux/
12
+ system 'firefox', uri
13
+ when /mswin(?!ce)|mingw|bccwin/
14
+ system 'explorer', uri
15
+ else
16
+ system 'open', uri
17
+ end
18
+ end
19
+ end
20
+
21
+ register_command(
22
+ :name => :open_url,
23
+ :help => ['open_url (TYPABLE|ID|@USER)', 'Open url'],
24
+ :exec_proc => lambda {|arg|
25
+ Thread.new(arg) do |arg|
26
+ if public_storage[:typable_id] && status = typable_id_status(arg)
27
+ status.text.gsub(URI.regexp) {|uri|
28
+ open_uri(uri)
29
+ }
30
+ else
31
+ case arg
32
+ when /^@([A-Za-z0-9_]+)/
33
+ user = $1
34
+ statuses = Termtter::API.twitter.user_timeline(user)
35
+ return if statuses.empty?
36
+ statuses[0].text.gsub(URI.regexp) {|uri| open_uri(uri) }
37
+ when /^\d+/
38
+ Termtter::API.twitter.show(arg).text.gsub(URI.regexp) {|uri| open_uri(uri) }
39
+ end
40
+ end
41
+ end
42
+ },
43
+ :completion_proc => lambda {|cmd, arg|
44
+ if public_storage[:typable_id] && typable_id?(arg)
45
+ "#{cmd} #{typable_id_convert(arg)}"
46
+ else
47
+ case arg
48
+ when /@(.*)/
49
+ find_user_candidates $1, "#{cmd} @%s"
50
+ when /(\d+)/
51
+ find_status_ids(arg).map{|id| "#{cmd} #{$1}"}
52
+ end
53
+ end
54
+ }
55
+ )
56
+ end
57
+
58
+ #Optional Setting
59
+ # config.plugins.open_url.browser = firefox
@@ -16,7 +16,7 @@ module Termtter::Client
16
16
  else
17
17
  status = t.show(id).first
18
18
  end
19
-
19
+
20
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
@@ -24,7 +24,7 @@ module Termtter::Client
24
24
  },
25
25
  :completion_proc => lambda {|cmd, args|
26
26
  if args =~ /^(\d*)$/
27
- find_status_id_candidates $1, "#{cmd} %s"
27
+ find_status_ids($1){|id| "#{cmd} #{id}"}
28
28
  end
29
29
  },
30
30
  :help => ['reblog ID', 'Tumblr Reblog a status']
@@ -0,0 +1,46 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ config.plugins.retweet.set_default(:format, 'RT @<%=s.user.screen_name%>: <%=s.text%>')
4
+
5
+ module Termtter::Client
6
+ def self.post_retweet(s)
7
+ text = ERB.new(config.plugins.retweet.format).result(binding)
8
+ Termtter::API.twitter.update(text)
9
+ puts "=> #{text}"
10
+ end
11
+
12
+ register_command(
13
+ :name => :retweet,
14
+ :aliases => [:rt],
15
+ :help => ['retweet,rt (TYPABLE|ID|@USER)', 'Post a retweet message'],
16
+ :exec_proc => lambda {|arg|
17
+ if public_storage[:typable_id] && s = typable_id_status(arg)
18
+ post_retweet(s)
19
+ else
20
+ case arg
21
+ when /(\d+)/
22
+ post_retweet(Termtter::API.twitter.show(arg))
23
+ #s = Twitter::API.twitter.show(arg)
24
+ #post_retweet(s)
25
+ when /@([A-Za-z0-9_]+)/
26
+ user = $1
27
+ statuses = Termtter::API.twitter.user_timeline(user)
28
+ return if statuses.empty?
29
+ post_retweet(statuses[0])
30
+ end
31
+ end
32
+ },
33
+ :completion_proc => lambda {|cmd, arg|
34
+ if public_storage[:typable_id] && s = typable_id_status(arg)
35
+ "u #{ERB.new(config.plugins.retweet.format).result(binding)}"
36
+ else
37
+ case arg
38
+ when /@(.*)/
39
+ find_user_candidates $1, "#{cmd} @%s"
40
+ when /(\d+)/
41
+ find_status_ids(arg).map{|id| "#{cmd} #{$1}"}
42
+ end
43
+ end
44
+ }
45
+ )
46
+ end