jugyo-termtter 0.8.14 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +8 -8
- data/Rakefile +3 -5
- data/lib/{plugin → plugins}/april_fool.rb +0 -0
- data/lib/plugins/bomb.rb +42 -0
- data/lib/{plugin → plugins}/clear.rb +0 -0
- data/lib/{plugin → plugins}/confirm.rb +0 -0
- data/lib/{plugin → plugins}/cool.rb +0 -0
- data/lib/{plugin → plugins}/devel.rb +0 -0
- data/lib/{filter → plugins}/en2ja.rb +1 -1
- data/lib/plugins/english.rb +25 -0
- data/lib/{plugin → plugins}/erb.rb +0 -0
- data/lib/{filter → plugins}/expand-tinyurl.rb +6 -6
- data/lib/plugins/favorite.rb +63 -0
- data/lib/plugins/fib.rb +28 -0
- data/lib/{filter/fib.rb → plugins/fib_filter.rb} +1 -2
- data/lib/{plugin → plugins}/filter.rb +0 -0
- data/lib/{plugin → plugins}/graduatter.rb +1 -2
- data/lib/{plugin → plugins}/grass.rb +2 -2
- data/lib/{plugin → plugins}/group.rb +9 -9
- data/lib/{plugin → plugins}/growl.rb +11 -12
- data/lib/{plugin → plugins}/hatebu.rb +5 -5
- data/lib/{plugin → plugins}/history.rb +13 -13
- data/lib/plugins/ignore.rb +19 -0
- data/lib/plugins/keyword.rb +18 -0
- data/lib/{plugin → plugins}/log.rb +18 -12
- data/lib/{plugin → plugins}/me.rb +1 -2
- data/lib/{plugin → plugins}/modify_arg_hook_sample.rb +0 -0
- data/lib/{plugin → plugins}/msagent.rb +1 -1
- data/lib/plugins/multi_reply.rb +27 -0
- data/lib/{plugin → plugins}/notify-send.rb +1 -1
- data/lib/{plugin → plugins}/otsune.rb +0 -0
- data/lib/plugins/outputz.rb +33 -0
- data/lib/{plugin → plugins}/pause.rb +0 -0
- data/lib/{plugin → plugins}/plugin.rb +0 -0
- data/lib/{plugin → plugins}/post_exec_hook_sample.rb +0 -0
- data/lib/{plugin → plugins}/pre_exec_hook_sample.rb +0 -0
- data/lib/{plugin → plugins}/primes.rb +9 -2
- data/lib/plugins/quicklook.rb +41 -0
- data/lib/{plugin → plugins}/random.rb +0 -0
- data/lib/{plugin → plugins}/reblog.rb +3 -3
- data/lib/{plugin → plugins}/reload.rb +0 -0
- data/lib/{filter → plugins}/reply.rb +0 -0
- data/lib/{filter → plugins}/reverse.rb +1 -1
- data/lib/{plugin → plugins}/say.rb +1 -1
- data/lib/{plugin → plugins}/scrape.rb +4 -4
- data/lib/plugins/screen-notify.rb +13 -0
- data/lib/plugins/screen.rb +24 -0
- data/lib/{plugin → plugins}/shell.rb +0 -0
- data/lib/{plugin → plugins}/sl.rb +4 -4
- data/lib/plugins/spam.rb +13 -0
- data/lib/{plugin → plugins}/standard_plugins.rb +72 -18
- data/lib/plugins/stdout.rb +80 -0
- data/lib/plugins/storage/DB.rb +37 -0
- data/lib/plugins/storage/status.rb +48 -0
- data/lib/plugins/storage/status_mook.rb +30 -0
- data/lib/plugins/storage.rb +47 -0
- data/lib/plugins/system_status.rb +33 -0
- data/lib/{plugin → plugins}/translation.rb +15 -5
- data/lib/{plugin → plugins}/update_editor.rb +6 -6
- data/lib/plugins/uri-open.rb +64 -0
- data/lib/{filter → plugins}/url_addspace.rb +0 -0
- data/lib/{plugin → plugins}/wassr_post.rb +1 -1
- data/lib/{plugin → plugins}/yhara.rb +1 -1
- data/lib/plugins/yhara_filter.rb +8 -0
- data/lib/plugins/yonda.rb +21 -0
- data/lib/termtter/api.rb +28 -2
- data/lib/termtter/client.rb +90 -102
- data/lib/termtter/command.rb +32 -31
- data/lib/termtter/config.rb +64 -0
- data/lib/termtter/connection.rb +9 -7
- data/lib/termtter/hook.rb +11 -2
- data/lib/termtter/optparse.rb +14 -0
- data/lib/termtter/version.rb +1 -1
- data/lib/termtter.rb +19 -22
- data/spec/plugin/english_spec.rb +19 -0
- data/spec/plugin/favorite_spec.rb +10 -0
- data/spec/plugin/fib_spec.rb +1 -2
- data/spec/plugin/pause_spec.rb +8 -0
- data/spec/plugin/plugin_spec.rb +1 -1
- data/spec/plugin/primes_spec.rb +15 -0
- data/spec/plugin/sl_spec.rb +8 -0
- data/spec/plugin/spam_spec.rb +0 -13
- data/spec/plugin/standard_plugins_spec.rb +0 -7
- data/spec/plugin/storage/DB_spec.rb +12 -0
- data/spec/plugin/storage/status_spec.rb +24 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/termtter/client_spec.rb +63 -1
- data/spec/termtter/command_spec.rb +6 -68
- data/spec/termtter/config_spec.rb +111 -0
- data/spec/termtter/hook_spec.rb +69 -0
- data/spec/termtter_spec.rb +22 -34
- metadata +81 -72
- data/lib/filter/english.rb +0 -8
- data/lib/filter/ignore.rb +0 -19
- data/lib/filter/yhara.rb +0 -20
- data/lib/plugin/bomb.rb +0 -29
- data/lib/plugin/english.rb +0 -59
- data/lib/plugin/favorite.rb +0 -75
- data/lib/plugin/fib.rb +0 -8
- data/lib/plugin/follow.rb +0 -60
- data/lib/plugin/keyword.rb +0 -18
- data/lib/plugin/multi_reply.rb +0 -36
- data/lib/plugin/outputz.rb +0 -35
- data/lib/plugin/quicklook.rb +0 -38
- data/lib/plugin/screen.rb +0 -24
- data/lib/plugin/spam.rb +0 -9
- data/lib/plugin/stdout.rb +0 -63
- data/lib/plugin/system_status.rb +0 -33
- data/lib/plugin/uri-open.rb +0 -69
- data/lib/plugin/yonda.rb +0 -20
- data/lib/termtter/status.rb +0 -26
- data/lib/termtter/twitter.rb +0 -188
- data/lib/termtter/user.rb +0 -13
- data/spec/termtter/user_spec.rb +0 -27
- data/test/test_termtter.rb +0 -86
data/lib/termtter/twitter.rb
DELETED
@@ -1,188 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
require 'highline'
|
4
|
-
require 'termcolor'
|
5
|
-
require 'time'
|
6
|
-
|
7
|
-
module Termtter
|
8
|
-
class Twitter
|
9
|
-
|
10
|
-
def initialize(user_name, password, connection, host = "twitter.com")
|
11
|
-
@user_name = user_name
|
12
|
-
@password = password
|
13
|
-
@connection = connection
|
14
|
-
@host = host
|
15
|
-
end
|
16
|
-
|
17
|
-
def update_status(status)
|
18
|
-
@connection.start(@host, @connection.port) do |http|
|
19
|
-
uri = '/statuses/update.xml'
|
20
|
-
http.request(post_request(uri), "status=#{CGI.escape(status)}&source=#{APP_NAME}")
|
21
|
-
end
|
22
|
-
status
|
23
|
-
end
|
24
|
-
|
25
|
-
def direct_message(user, status)
|
26
|
-
@connection.start(@host, @connection.port) do |http|
|
27
|
-
uri = '/direct_messages/new.xml'
|
28
|
-
http.request(post_request(uri), "user=#{CGI.escape(user)}&text=#{CGI.escape(status)}&source=#{APP_NAME}")
|
29
|
-
end
|
30
|
-
[user, status]
|
31
|
-
end
|
32
|
-
|
33
|
-
def get_user_profile(screen_name)
|
34
|
-
result = fetch_as_json(url_for("/users/show/#{screen_name}.json"))
|
35
|
-
return hash_to_user(result)
|
36
|
-
end
|
37
|
-
|
38
|
-
def get_friends_timeline(since_id = nil)
|
39
|
-
uri = url_for("/statuses/friends_timeline.json")
|
40
|
-
uri << "?since_id=#{since_id}" if since_id
|
41
|
-
return get_timeline(uri)
|
42
|
-
end
|
43
|
-
|
44
|
-
def get_user_timeline(screen_name)
|
45
|
-
return get_timeline(url_for("/statuses/user_timeline/#{screen_name}.json"))
|
46
|
-
rescue OpenURI::HTTPError => e
|
47
|
-
case e.message
|
48
|
-
when /404/
|
49
|
-
warn "No such user: #{screen_name}"
|
50
|
-
nears = near_users(screen_name)
|
51
|
-
puts "near users: #{nears}" unless nears.empty?
|
52
|
-
return []
|
53
|
-
end
|
54
|
-
raise
|
55
|
-
end
|
56
|
-
|
57
|
-
configatron.search.set_default(:highlihgt_text_format, '<on_magenta><white>\1</white></on_magenta>')
|
58
|
-
def search(query)
|
59
|
-
results = fetch_as_json(search_url_for("/search.json?q=#{CGI.escape(query)}"))['results']
|
60
|
-
return results.map do |s|
|
61
|
-
status = Status.new
|
62
|
-
status.id = s['id']
|
63
|
-
status.text = s['text'].
|
64
|
-
gsub(/(\n|\r)/, '').
|
65
|
-
gsub(/(#{Regexp.escape(query)})/i, configatron.search.highlihgt_text_format)
|
66
|
-
status.created_at = Time.parse(s["created_at"])
|
67
|
-
status.user_screen_name = s['from_user']
|
68
|
-
status
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def show(id, rth = false)
|
73
|
-
get_status = lambda { get_timeline(url_for("/statuses/show/#{id}.json"))[0] }
|
74
|
-
statuses = []
|
75
|
-
statuses << status = Array(Client.public_storage[:log]).detect(get_status) {|s| s.id == id.to_i }
|
76
|
-
statuses << show(id, true) if rth && status && id = status.in_reply_to_status_id
|
77
|
-
statuses.flatten.compact
|
78
|
-
end
|
79
|
-
|
80
|
-
def replies
|
81
|
-
return get_timeline(url_for("/statuses/replies.json"))
|
82
|
-
end
|
83
|
-
|
84
|
-
def followers
|
85
|
-
users = []
|
86
|
-
page = 0
|
87
|
-
begin
|
88
|
-
users += tmp = fetch_as_json(url_for("/statuses/followers.json?page=#{page+=1}"))
|
89
|
-
end until tmp.empty?
|
90
|
-
return users.map{|u| hash_to_user(u)}
|
91
|
-
end
|
92
|
-
|
93
|
-
def get_timeline(uri)
|
94
|
-
data = fetch_as_json(uri)
|
95
|
-
data = [data] unless data.instance_of? Array
|
96
|
-
return data.map do |s|
|
97
|
-
status = Status.new
|
98
|
-
status.created_at = Time.parse(s["created_at"])
|
99
|
-
%w(id text truncated in_reply_to_status_id in_reply_to_user_id in_reply_to_screen_name).each do |key|
|
100
|
-
status.__send__("#{key}=".to_sym, s[key])
|
101
|
-
end
|
102
|
-
%w(id name screen_name url profile_image_url).each do |key|
|
103
|
-
status.__send__("user_#{key}=".to_sym, s["user"][key])
|
104
|
-
end
|
105
|
-
status.text = status.text.gsub(/(\n|\r)/, '')
|
106
|
-
status
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# note: APILimit.reset_time_in_seconds == APILimit.reset_time.to_i
|
111
|
-
APILIMIT = Struct.new("APILimit", :reset_time, :reset_time_in_seconds, :remaining_hits, :hourly_limit)
|
112
|
-
def get_rate_limit_status
|
113
|
-
data = fetch_as_json(url_for("/account/rate_limit_status.json"))
|
114
|
-
reset_time = Time.parse(data['reset_time'])
|
115
|
-
reset_time_in_seconds = data['reset_time_in_seconds'].to_i
|
116
|
-
|
117
|
-
APILIMIT.new(reset_time, reset_time_in_seconds, data['remaining_hits'], data['hourly_limit'])
|
118
|
-
end
|
119
|
-
|
120
|
-
alias :api_limit :get_rate_limit_status
|
121
|
-
|
122
|
-
private
|
123
|
-
|
124
|
-
def hash_to_user(hash)
|
125
|
-
user = User.new
|
126
|
-
%w[ name favourites_count url id description protected utc_offset time_zone
|
127
|
-
screen_name notifications statuses_count followers_count friends_count
|
128
|
-
profile_image_url location following created_at
|
129
|
-
].each do |attr|
|
130
|
-
user.__send__("#{attr}=".to_sym, hash[attr])
|
131
|
-
end
|
132
|
-
return user
|
133
|
-
end
|
134
|
-
|
135
|
-
def fetch_as_json(uri)
|
136
|
-
JSON.parse(open_uri(uri).read)
|
137
|
-
rescue OpenURI::HTTPError => e
|
138
|
-
case e.message
|
139
|
-
when /403/, /401/
|
140
|
-
warn '[PROTECTED USER] You must add to show his/her tweet.'
|
141
|
-
return []
|
142
|
-
end
|
143
|
-
raise
|
144
|
-
end
|
145
|
-
|
146
|
-
def open_uri(uri)
|
147
|
-
return open(uri, :http_basic_authentication => [user_name, password], :proxy => @connection.proxy_uri)
|
148
|
-
end
|
149
|
-
|
150
|
-
def url_for(path)
|
151
|
-
return "#{@connection.protocol}://#{@host}/#{path.sub(/^\//, '')}"
|
152
|
-
end
|
153
|
-
|
154
|
-
def search_url_for(path)
|
155
|
-
return "#{@connection.protocol}://search.#{@host}/#{path.sub(/^\//, '')}"
|
156
|
-
end
|
157
|
-
|
158
|
-
def user_name
|
159
|
-
unless @user_name.instance_of? String
|
160
|
-
Termtter::Client.create_highline.ask('your twitter username: ')
|
161
|
-
end
|
162
|
-
@user_name
|
163
|
-
end
|
164
|
-
|
165
|
-
def password
|
166
|
-
unless @password.instance_of? String
|
167
|
-
@password = Termtter::Client.create_highline.ask('your twitter password: ') { |q| q.echo = false }
|
168
|
-
end
|
169
|
-
@password
|
170
|
-
end
|
171
|
-
|
172
|
-
def near_users(screen_name)
|
173
|
-
Client::public_storage[:users].select {|user|
|
174
|
-
/#{user}/i =~ screen_name || /#{screen_name}/i =~ user
|
175
|
-
}.join(', ')
|
176
|
-
end
|
177
|
-
|
178
|
-
def post_request(uri)
|
179
|
-
req = Net::HTTP::Post.new(uri)
|
180
|
-
req.basic_auth(user_name, password)
|
181
|
-
req.add_field('User-Agent', 'Termtter http://github.com/jugyo/termtter')
|
182
|
-
req.add_field('X-Twitter-Client', 'Termtter')
|
183
|
-
req.add_field('X-Twitter-Client-URL', 'http://github.com/jugyo/termtter')
|
184
|
-
req.add_field('X-Twitter-Client-Version', '0.1')
|
185
|
-
req
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
data/lib/termtter/user.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
module Termtter
|
4
|
-
class User
|
5
|
-
%w[ name favourites_count url id description protected utc_offset time_zone
|
6
|
-
screen_name notifications statuses_count followers_count friends_count
|
7
|
-
profile_image_url location following created_at
|
8
|
-
].each do |attr|
|
9
|
-
attr_accessor attr.to_sym
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
data/spec/termtter/user_spec.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|
4
|
-
|
5
|
-
module Termtter
|
6
|
-
describe User do
|
7
|
-
before do
|
8
|
-
@user = User.new
|
9
|
-
@params = %w[ name favourites_count url id description protected utc_offset time_zone
|
10
|
-
screen_name notifications statuses_count followers_count friends_count
|
11
|
-
profile_image_url location following created_at
|
12
|
-
]
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should access to properties' do
|
16
|
-
@params.each do |attr|
|
17
|
-
@user.__send__(attr.to_sym).should == nil
|
18
|
-
end
|
19
|
-
|
20
|
-
@params.each do |attr|
|
21
|
-
@user.__send__("#{attr}=".to_sym, 'foo')
|
22
|
-
@user.__send__(attr.to_sym).should == 'foo'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
data/test/test_termtter.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'configatron'
|
5
|
-
require 'test/unit'
|
6
|
-
require 'kagemusha'
|
7
|
-
require File.dirname(__FILE__) + '/../lib/termtter'
|
8
|
-
|
9
|
-
# TODO: もっとテスト書く!
|
10
|
-
|
11
|
-
class TestTermtter < Test::Unit::TestCase
|
12
|
-
def setup
|
13
|
-
@twitter = Termtter::Twitter.new('test', 'test')
|
14
|
-
|
15
|
-
Termtter::Client.add_hook do |statuses, event|
|
16
|
-
@statuses = statuses
|
17
|
-
@event = event
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_search
|
22
|
-
statuses = swap_open('search.json') { @twitter.search('') }
|
23
|
-
assert_equal 3, statuses.size
|
24
|
-
assert_equal 'test2', statuses[0].user_screen_name
|
25
|
-
assert_equal 'texttext 2', statuses[0].text
|
26
|
-
assert_equal 'Sat Jan 03 21:49:09 +0900 2009', statuses[0].created_at.to_s
|
27
|
-
assert_equal 'test0', statuses[2].user_screen_name
|
28
|
-
assert_equal 'texttext 0', statuses[2].text
|
29
|
-
assert_equal 'Sat Jan 03 21:49:09 +0900 2009', statuses[2].created_at.to_s
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_add_hook
|
33
|
-
statuses = nil
|
34
|
-
event = nil
|
35
|
-
twitter = nil
|
36
|
-
Termtter::Client.add_hook do |s, e, t|
|
37
|
-
statuses = s
|
38
|
-
event = e
|
39
|
-
twitter = t
|
40
|
-
end
|
41
|
-
|
42
|
-
Termtter::Client.call_hooks([], :foo, @twitter)
|
43
|
-
|
44
|
-
assert_equal [], statuses
|
45
|
-
assert_equal :foo, event
|
46
|
-
assert_equal @twitter, twitter
|
47
|
-
|
48
|
-
Termtter::Client.clear_hooks()
|
49
|
-
statuses = nil
|
50
|
-
event = nil
|
51
|
-
Termtter::Client.call_hooks([], :foo, @twitter)
|
52
|
-
|
53
|
-
assert_equal nil, statuses
|
54
|
-
assert_equal nil, event
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_add_command
|
58
|
-
command_text = nil
|
59
|
-
matche_text = nil
|
60
|
-
twitter = nil
|
61
|
-
Termtter::Client.add_command /foo\s+(.*)/ do |m, t|
|
62
|
-
command_text = m[0]
|
63
|
-
matche_text = m[1]
|
64
|
-
twitter = t
|
65
|
-
end
|
66
|
-
|
67
|
-
Termtter::Client.call_commands('foo xxxxxxxxxxxxxx', @twitter)
|
68
|
-
assert_equal 'foo xxxxxxxxxxxxxx', command_text
|
69
|
-
assert_equal 'xxxxxxxxxxxxxx', matche_text
|
70
|
-
assert_equal @twitter, twitter
|
71
|
-
|
72
|
-
Termtter::Client.clear_commands()
|
73
|
-
assert_raise Termtter::CommandNotFound do
|
74
|
-
Termtter::Client.call_commands('foo xxxxxxxxxxxxxx', @twitter)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def swap_open(name)
|
79
|
-
Kagemusha.new(Termtter::Twitter).def(:open) {
|
80
|
-
File.open(File.dirname(__FILE__) + "/../test/#{name}")
|
81
|
-
}.swap do
|
82
|
-
yield
|
83
|
-
end
|
84
|
-
end
|
85
|
-
private :swap_open
|
86
|
-
end
|