tw 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/History.txt +5 -0
- data/Manifest.txt +1 -0
- data/README.rdoc +15 -5
- data/Rakefile +1 -0
- data/lib/tw.rb +6 -1
- data/lib/tw/app/cmds.rb +25 -0
- data/lib/tw/app/helper.rb +11 -0
- data/lib/tw/app/main.rb +4 -1
- data/lib/tw/app/render.rb +5 -9
- data/lib/tw/client/request.rb +27 -0
- data/lib/tw/conf.rb +10 -1
- data/test/test_tw.rb +10 -1
- metadata +145 -144
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/README.rdoc
CHANGED
@@ -2,27 +2,37 @@
|
|
2
2
|
|
3
3
|
* http://github.com/shokai/tw
|
4
4
|
|
5
|
+
== INSTALL:
|
6
|
+
|
7
|
+
* gem install tw
|
8
|
+
|
5
9
|
== DESCRIPTION:
|
6
10
|
|
7
11
|
* twitter client.
|
8
12
|
|
9
|
-
|
10
13
|
== SYNOPSIS:
|
11
14
|
|
12
|
-
|
15
|
+
show help
|
16
|
+
|
17
|
+
% tw --help
|
18
|
+
|
19
|
+
read Timeline
|
13
20
|
|
14
21
|
% tw @username
|
15
22
|
% tw @username @user2 @user3
|
16
23
|
% tw @username/listname
|
24
|
+
% tw --timeline
|
25
|
+
% tw --search=ruby
|
17
26
|
|
18
|
-
|
27
|
+
Tweet
|
19
28
|
|
20
29
|
% tw hello hello
|
21
30
|
|
31
|
+
DM
|
22
32
|
|
23
|
-
|
33
|
+
% tw --dm
|
34
|
+
% tw --dm:to=shokai "hello!"
|
24
35
|
|
25
|
-
* gem install tw
|
26
36
|
|
27
37
|
== LICENSE:
|
28
38
|
|
data/Rakefile
CHANGED
data/lib/tw.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__)) unless
|
2
2
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
|
+
require 'backports'
|
4
5
|
require 'oauth'
|
5
6
|
require 'twitter'
|
6
7
|
require 'yaml'
|
@@ -13,5 +14,9 @@ require 'tw/client/request'
|
|
13
14
|
require 'tw/client/error'
|
14
15
|
|
15
16
|
module Tw
|
16
|
-
VERSION = '0.0
|
17
|
+
VERSION = '0.1.0'
|
18
|
+
class Conf
|
19
|
+
REQUIRE_VERSION = '0.1.0'
|
20
|
+
end
|
17
21
|
end
|
22
|
+
|
data/lib/tw/app/cmds.rb
CHANGED
@@ -44,6 +44,31 @@ module Tw::App
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
cmd :dm do |v|
|
48
|
+
auth
|
49
|
+
Render.display client.direct_messages
|
50
|
+
on_exit
|
51
|
+
end
|
52
|
+
|
53
|
+
cmd 'dm:to' do |to|
|
54
|
+
message = @parser.argv.join(' ')
|
55
|
+
len = message.split(//u).size
|
56
|
+
if len > 140
|
57
|
+
STDERR.puts "message too long (#{len} chars)"
|
58
|
+
on_error
|
59
|
+
elsif len < 1
|
60
|
+
STDERR.puts 'e.g. tw --dm:to=USERNAME "hello"'
|
61
|
+
on_error
|
62
|
+
else
|
63
|
+
puts "dm \"#{message}\"? (#{len} chars)"
|
64
|
+
puts '[Y/n]'
|
65
|
+
on_exit if STDIN.gets.strip =~ /^n/i
|
66
|
+
auth
|
67
|
+
client.direct_message_create to, message
|
68
|
+
end
|
69
|
+
on_exit
|
70
|
+
end
|
71
|
+
|
47
72
|
cmd :search do |v|
|
48
73
|
if v.class == String
|
49
74
|
auth
|
data/lib/tw/app/main.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
require File.expand_path 'opt_parser', File.dirname(__FILE__)
|
3
3
|
require File.expand_path 'cmds', File.dirname(__FILE__)
|
4
4
|
require File.expand_path 'render', File.dirname(__FILE__)
|
5
|
+
require File.expand_path 'helper', File.dirname(__FILE__)
|
5
6
|
|
6
7
|
module Tw::App
|
7
8
|
|
@@ -47,6 +48,8 @@ module Tw::App
|
|
47
48
|
arg 'user:list', 'show user list'
|
48
49
|
arg 'user:default', 'set default user'
|
49
50
|
arg :timeline, 'show timeline', :alias => :tl
|
51
|
+
arg :dm, 'show direct messages'
|
52
|
+
arg 'dm:to', 'create direct message'
|
50
53
|
arg :search, 'search public timeline', :alias => :s
|
51
54
|
arg :pipe, 'pipe tweet'
|
52
55
|
arg :version, 'show version', :alias => :v
|
@@ -80,7 +83,7 @@ module Tw::App
|
|
80
83
|
else
|
81
84
|
message = @parser.argv.join(' ')
|
82
85
|
if (len = message.split(//u).size) > 140
|
83
|
-
puts "tweet too long (#{len} chars)"
|
86
|
+
STDERR.puts "tweet too long (#{len} chars)"
|
84
87
|
on_error
|
85
88
|
else
|
86
89
|
puts "tweet \"#{message}\"? (#{len} chars)"
|
data/lib/tw/app/render.rb
CHANGED
@@ -7,17 +7,13 @@ module Tw::App
|
|
7
7
|
return colors[n%colors.size]
|
8
8
|
end
|
9
9
|
|
10
|
-
def self.display(
|
11
|
-
|
10
|
+
def self.display(arr)
|
11
|
+
arr.flatten.sort{|a,b|
|
12
12
|
a[:id] <=> b[:id]
|
13
13
|
}.uniq.each{|m|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
term = term.color(color_code term).bright.underline
|
18
|
-
end
|
19
|
-
term
|
20
|
-
}.join('')
|
14
|
+
user = m[:user].kind_of?(Hash) ? "@#{m[:user][:from]} > @#{m[:user][:to]}" : "@#{m[:user]}"
|
15
|
+
line = "#{m[:time].strftime '[%m/%d %a] (%H:%M:%S)'} #{user} : #{m[:text]}"
|
16
|
+
puts line.colorize(/@[a-zA-Z0-9_]+/)
|
21
17
|
}
|
22
18
|
end
|
23
19
|
end
|
data/lib/tw/client/request.rb
CHANGED
@@ -57,6 +57,27 @@ module Tw
|
|
57
57
|
}
|
58
58
|
end
|
59
59
|
|
60
|
+
def direct_messages
|
61
|
+
[Twitter.direct_messages.map{|m|
|
62
|
+
{
|
63
|
+
:id => m.id,
|
64
|
+
:user => m.sender.screen_name,
|
65
|
+
:text => m.text,
|
66
|
+
:time => m.created_at
|
67
|
+
}
|
68
|
+
}, Twitter.direct_messages_sent.map{|m|
|
69
|
+
{
|
70
|
+
:id => m.id,
|
71
|
+
:user => {
|
72
|
+
:from => m.sender.screen_name,
|
73
|
+
:to => m.recipient.screen_name
|
74
|
+
},
|
75
|
+
:text => m.text,
|
76
|
+
:time => m.created_at
|
77
|
+
}
|
78
|
+
}].flatten
|
79
|
+
end
|
80
|
+
|
60
81
|
def tweet(message)
|
61
82
|
res = Twitter.update message
|
62
83
|
puts res.text
|
@@ -64,5 +85,11 @@ module Tw
|
|
64
85
|
puts res.created_at
|
65
86
|
end
|
66
87
|
|
88
|
+
def direct_message_create(to, message)
|
89
|
+
res = Twitter.direct_message_create to, message
|
90
|
+
puts res.text
|
91
|
+
puts res.created_at
|
92
|
+
end
|
93
|
+
|
67
94
|
end
|
68
95
|
end
|
data/lib/tw/conf.rb
CHANGED
@@ -29,8 +29,17 @@ module Tw
|
|
29
29
|
res = default
|
30
30
|
if File.exists? conf_file
|
31
31
|
begin
|
32
|
+
data = nil
|
32
33
|
open_conf_file do |f|
|
33
|
-
|
34
|
+
data = YAML::load f.read
|
35
|
+
end
|
36
|
+
if data['version'] < REQUIRE_VERSION
|
37
|
+
puts "This is tw version #{Tw::VERSION}."
|
38
|
+
puts "Your config file is old ("+data['version']+"). Reset tw settings?"
|
39
|
+
puts "[Y/n]"
|
40
|
+
res = data if STDIN.gets =~ /^n/i
|
41
|
+
else
|
42
|
+
res = data
|
34
43
|
end
|
35
44
|
rescue => e
|
36
45
|
STDERR.puts e
|
data/test/test_tw.rb
CHANGED
@@ -7,11 +7,16 @@ class TestTw < Test::Unit::TestCase
|
|
7
7
|
@client.auth
|
8
8
|
end
|
9
9
|
|
10
|
+
def user?(str)
|
11
|
+
return false unless str.kind_of? String
|
12
|
+
str =~ /^[a-zA-Z0-9_]+$/
|
13
|
+
end
|
14
|
+
|
10
15
|
def response?(arr)
|
11
16
|
return false unless arr.kind_of? Array
|
12
17
|
arr.each do |i|
|
13
18
|
return false if !(i[:id].class == Fixnum and
|
14
|
-
i[:user]
|
19
|
+
(user? i[:user] or (user? i[:user][:to] and user? i[:user][:from])) and
|
15
20
|
i[:text].kind_of? String and
|
16
21
|
i[:time].kind_of? Time)
|
17
22
|
end
|
@@ -37,4 +42,8 @@ class TestTw < Test::Unit::TestCase
|
|
37
42
|
def test_list_timeline
|
38
43
|
assert response? @client.list_timeline('shokai', 'arr')
|
39
44
|
end
|
45
|
+
|
46
|
+
def test_direct_message
|
47
|
+
assert response? @client.direct_messages
|
48
|
+
end
|
40
49
|
end
|
metadata
CHANGED
@@ -1,168 +1,173 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: tw
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 3
|
10
|
-
version: 0.0.3
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Sho Hashimoto
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
date: 2012-10-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: oauth
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.4.7
|
22
|
+
- - <
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.0.0
|
25
|
+
type: :runtime
|
21
26
|
prerelease: false
|
22
|
-
|
23
|
-
none: false
|
24
|
-
requirements:
|
25
|
-
- -
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
hash: 1
|
28
|
-
segments:
|
29
|
-
- 0
|
30
|
-
- 4
|
31
|
-
- 7
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
32
|
version: 0.4.7
|
33
33
|
- - <
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
hash: 23
|
36
|
-
segments:
|
37
|
-
- 1
|
38
|
-
- 0
|
39
|
-
- 0
|
34
|
+
- !ruby/object:Gem::Version
|
40
35
|
version: 1.0.0
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: twitter
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 4.0.0
|
44
|
+
- - <
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 5.0.0
|
41
47
|
type: :runtime
|
42
|
-
name: oauth
|
43
|
-
version_requirements: *id001
|
44
|
-
- !ruby/object:Gem::Dependency
|
45
48
|
prerelease: false
|
46
|
-
|
47
|
-
none: false
|
48
|
-
requirements:
|
49
|
-
- -
|
50
|
-
- !ruby/object:Gem::Version
|
51
|
-
hash: 63
|
52
|
-
segments:
|
53
|
-
- 4
|
54
|
-
- 0
|
55
|
-
- 0
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
56
54
|
version: 4.0.0
|
57
55
|
- - <
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
hash: 55
|
60
|
-
segments:
|
61
|
-
- 5
|
62
|
-
- 0
|
63
|
-
- 0
|
56
|
+
- !ruby/object:Gem::Version
|
64
57
|
version: 5.0.0
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: args_parser
|
60
|
+
requirement: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.1.0
|
65
66
|
type: :runtime
|
66
|
-
name: twitter
|
67
|
-
version_requirements: *id002
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
67
|
prerelease: false
|
70
|
-
|
71
|
-
none: false
|
72
|
-
requirements:
|
73
|
-
- -
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
hash: 27
|
76
|
-
segments:
|
77
|
-
- 0
|
78
|
-
- 1
|
79
|
-
- 0
|
68
|
+
version_requirements: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
80
73
|
version: 0.1.0
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
name: backports
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 2.6.4
|
81
82
|
type: :runtime
|
82
|
-
name: args_parser
|
83
|
-
version_requirements: *id003
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
83
|
prerelease: false
|
86
|
-
|
87
|
-
none: false
|
88
|
-
requirements:
|
89
|
-
- -
|
90
|
-
- !ruby/object:Gem::Version
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 2.6.4
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: rainbow
|
92
|
+
requirement: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
96
97
|
version: 1.1.4
|
97
98
|
- - <
|
98
|
-
- !ruby/object:Gem::Version
|
99
|
-
hash: 15
|
100
|
-
segments:
|
101
|
-
- 2
|
102
|
-
- 0
|
103
|
-
- 0
|
99
|
+
- !ruby/object:Gem::Version
|
104
100
|
version: 2.0.0
|
105
101
|
type: :runtime
|
106
|
-
name: rainbow
|
107
|
-
version_requirements: *id004
|
108
|
-
- !ruby/object:Gem::Dependency
|
109
102
|
prerelease: false
|
110
|
-
|
103
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
104
|
none: false
|
112
|
-
requirements:
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 1.1.4
|
109
|
+
- - <
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 2.0.0
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: rdoc
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
113
117
|
- - ~>
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
|
116
|
-
segments:
|
117
|
-
- 3
|
118
|
-
- 10
|
119
|
-
version: "3.10"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '3.10'
|
120
120
|
type: :development
|
121
|
-
name: rdoc
|
122
|
-
version_requirements: *id005
|
123
|
-
- !ruby/object:Gem::Dependency
|
124
121
|
prerelease: false
|
125
|
-
|
126
|
-
none: false
|
127
|
-
requirements:
|
128
|
-
- -
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ~>
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '3.10'
|
128
|
+
- !ruby/object:Gem::Dependency
|
129
|
+
name: newgem
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ! '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
135
|
version: 1.5.3
|
136
136
|
type: :development
|
137
|
-
name: newgem
|
138
|
-
version_requirements: *id006
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
137
|
prerelease: false
|
141
|
-
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ! '>='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: 1.5.3
|
144
|
+
- !ruby/object:Gem::Dependency
|
145
|
+
name: hoe
|
146
|
+
requirement: !ruby/object:Gem::Requirement
|
142
147
|
none: false
|
143
|
-
requirements:
|
148
|
+
requirements:
|
144
149
|
- - ~>
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
|
147
|
-
segments:
|
148
|
-
- 3
|
149
|
-
- 1
|
150
|
-
version: "3.1"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '3.1'
|
151
152
|
type: :development
|
152
|
-
|
153
|
-
version_requirements:
|
154
|
-
|
155
|
-
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
none: false
|
156
|
+
requirements:
|
157
|
+
- - ~>
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '3.1'
|
160
|
+
description: ! '* twitter client.'
|
161
|
+
email:
|
156
162
|
- hashimoto@shokai.org
|
157
|
-
executables:
|
163
|
+
executables:
|
158
164
|
- tw
|
159
165
|
extensions: []
|
160
|
-
|
161
|
-
extra_rdoc_files:
|
166
|
+
extra_rdoc_files:
|
162
167
|
- History.txt
|
163
168
|
- Manifest.txt
|
164
169
|
- README.rdoc
|
165
|
-
files:
|
170
|
+
files:
|
166
171
|
- Gemfile
|
167
172
|
- Gemfile.lock
|
168
173
|
- History.txt
|
@@ -172,6 +177,7 @@ files:
|
|
172
177
|
- bin/tw
|
173
178
|
- lib/tw.rb
|
174
179
|
- lib/tw/app/cmds.rb
|
180
|
+
- lib/tw/app/helper.rb
|
175
181
|
- lib/tw/app/main.rb
|
176
182
|
- lib/tw/app/opt_parser.rb
|
177
183
|
- lib/tw/app/render.rb
|
@@ -187,38 +193,33 @@ files:
|
|
187
193
|
- .gemtest
|
188
194
|
homepage: http://github.com/shokai/tw
|
189
195
|
licenses: []
|
190
|
-
|
191
196
|
post_install_message:
|
192
|
-
rdoc_options:
|
197
|
+
rdoc_options:
|
193
198
|
- --main
|
194
199
|
- README.rdoc
|
195
|
-
require_paths:
|
200
|
+
require_paths:
|
196
201
|
- lib
|
197
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
202
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
198
203
|
none: false
|
199
|
-
requirements:
|
200
|
-
- -
|
201
|
-
- !ruby/object:Gem::Version
|
202
|
-
|
203
|
-
segments:
|
204
|
+
requirements:
|
205
|
+
- - ! '>='
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '0'
|
208
|
+
segments:
|
204
209
|
- 0
|
205
|
-
|
206
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
210
|
+
hash: -3893906850154543404
|
211
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
207
212
|
none: false
|
208
|
-
requirements:
|
209
|
-
- -
|
210
|
-
- !ruby/object:Gem::Version
|
211
|
-
|
212
|
-
segments:
|
213
|
-
- 0
|
214
|
-
version: "0"
|
213
|
+
requirements:
|
214
|
+
- - ! '>='
|
215
|
+
- !ruby/object:Gem::Version
|
216
|
+
version: '0'
|
215
217
|
requirements: []
|
216
|
-
|
217
218
|
rubyforge_project: tw
|
218
219
|
rubygems_version: 1.8.24
|
219
220
|
signing_key:
|
220
221
|
specification_version: 3
|
221
|
-
summary:
|
222
|
-
test_files:
|
222
|
+
summary: ! '* twitter client.'
|
223
|
+
test_files:
|
223
224
|
- test/test_helper.rb
|
224
225
|
- test/test_tw.rb
|