twterm 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/twterm +1 -1
- data/lib/twterm.rb +2 -1
- data/lib/twterm/app.rb +13 -0
- data/lib/twterm/auth.rb +7 -2
- data/lib/twterm/client.rb +15 -4
- data/lib/twterm/status.rb +24 -8
- data/lib/twterm/tab/new/start.rb +13 -2
- data/lib/twterm/tab/new/user.rb +60 -0
- data/lib/twterm/tab/statuses_tab.rb +27 -12
- data/lib/twterm/tab/user_tab.rb +4 -0
- data/lib/twterm/tweetbox.rb +5 -1
- data/lib/twterm/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b83f1b22f92cf279b15fdb70358d86dca32a00d9
|
4
|
+
data.tar.gz: ea0d20227e837aa606fa27d73aaa0cad87e2d0ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aad2fda4667c871c79b556360280a160ee4bbbced590bc5bb6e18938c9e0949bd2f454e65c2c97e5c1a99bc016ee80e348426544d8bc50ccc5276dee89784af7
|
7
|
+
data.tar.gz: e90142ebc46ec3c38ed1bb9e7a8ea5f09030b6c1306e2823865ae916aee5cca6c65a1a0fe9220aaa9c812d85fda982b4a22213de7056159059996e313f8f75d7
|
data/bin/twterm
CHANGED
data/lib/twterm.rb
CHANGED
@@ -36,6 +36,7 @@ require 'twterm/tab/mentions_tab'
|
|
36
36
|
require 'twterm/tab/new/start'
|
37
37
|
require 'twterm/tab/new/list'
|
38
38
|
require 'twterm/tab/new/search'
|
39
|
+
require 'twterm/tab/new/user'
|
39
40
|
require 'twterm/tab/search_tab'
|
40
41
|
require 'twterm/tab/timeline_tab'
|
41
42
|
require 'twterm/tab/user_tab'
|
@@ -46,6 +47,6 @@ require 'twterm/version'
|
|
46
47
|
|
47
48
|
module Twterm
|
48
49
|
class Conf
|
49
|
-
REQUIRE_VERSION = '1.0.
|
50
|
+
REQUIRE_VERSION = '1.0.2'
|
50
51
|
end
|
51
52
|
end
|
data/lib/twterm/app.rb
CHANGED
@@ -25,6 +25,8 @@ module Twterm
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def run
|
28
|
+
run_periodic_cleanup
|
29
|
+
|
28
30
|
Screen.instance.wait
|
29
31
|
Screen.instance.refresh
|
30
32
|
end
|
@@ -41,5 +43,16 @@ module Twterm
|
|
41
43
|
exit
|
42
44
|
end
|
43
45
|
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def run_periodic_cleanup
|
50
|
+
Thread.new do
|
51
|
+
loop do
|
52
|
+
sleep 300
|
53
|
+
Status.cleanup
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
44
57
|
end
|
45
58
|
end
|
data/lib/twterm/auth.rb
CHANGED
@@ -7,8 +7,13 @@ module Twterm
|
|
7
7
|
site: 'https://api.twitter.com'
|
8
8
|
)
|
9
9
|
request_token = consumer.get_request_token
|
10
|
-
|
11
|
-
|
10
|
+
url = request_token.authorize_url
|
11
|
+
begin
|
12
|
+
Launchy.open(url)
|
13
|
+
rescue Launchy::CommandNotFoundError
|
14
|
+
puts "Open the following URL to authorize yourself: #{url}"
|
15
|
+
end
|
16
|
+
print 'Input PIN: '
|
12
17
|
pin = (STDIN.gets || '').strip
|
13
18
|
access_token = request_token.get_access_token(oauth_verifier: pin)
|
14
19
|
|
data/lib/twterm/client.rb
CHANGED
@@ -85,19 +85,19 @@ module Twterm
|
|
85
85
|
|
86
86
|
def home_timeline
|
87
87
|
send_request do
|
88
|
-
yield @rest_client.home_timeline(count:
|
88
|
+
yield @rest_client.home_timeline(count: 100).map(&CREATE_STATUS_PROC)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
92
|
def mentions
|
93
93
|
send_request do
|
94
|
-
yield @rest_client.mentions(count:
|
94
|
+
yield @rest_client.mentions(count: 100).map(&CREATE_STATUS_PROC)
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
98
|
def user_timeline(user_id)
|
99
99
|
send_request do
|
100
|
-
yield @rest_client.user_timeline(user_id, count:
|
100
|
+
yield @rest_client.user_timeline(user_id, count: 100).map(&CREATE_STATUS_PROC)
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
@@ -110,7 +110,7 @@ module Twterm
|
|
110
110
|
def list(list)
|
111
111
|
fail ArgumentError, 'argument must be an instance of List class' unless list.is_a? List
|
112
112
|
send_request do
|
113
|
-
yield @rest_client.list_timeline(list.id, count:
|
113
|
+
yield @rest_client.list_timeline(list.id, count: 100).map(&CREATE_STATUS_PROC)
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
@@ -126,6 +126,17 @@ module Twterm
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
|
+
def show_user(query)
|
130
|
+
send_request do
|
131
|
+
begin
|
132
|
+
user = User.new(@rest_client.user(query))
|
133
|
+
rescue Twitter::Error::NotFound
|
134
|
+
user = nil
|
135
|
+
end
|
136
|
+
yield user
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
129
140
|
def favorite(status)
|
130
141
|
return false unless status.is_a? Status
|
131
142
|
|
data/lib/twterm/status.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
module Twterm
|
2
2
|
class Status
|
3
|
-
|
3
|
+
MAX_CACHED_STATUSES_COUNT = 1000
|
4
|
+
|
5
|
+
attr_reader :id, :text, :created_at, :created_at_for_sort, :retweet_count, :favorite_count, :in_reply_to_status_id, :favorited, :retweeted, :user, :retweeted_by, :urls, :media, :touched_at
|
4
6
|
alias_method :favorited?, :favorited
|
5
7
|
alias_method :retweeted?, :retweeted
|
6
8
|
|
7
|
-
@@instances =
|
9
|
+
@@instances = {}
|
8
10
|
|
9
11
|
def self.new(tweet)
|
10
|
-
|
11
|
-
instance = @@instances.find(&detector)
|
12
|
+
instance = find(tweet.id)
|
12
13
|
instance.nil? ? super : instance.update!(tweet)
|
13
14
|
end
|
14
15
|
|
@@ -39,7 +40,9 @@ module Twterm
|
|
39
40
|
|
40
41
|
expand_url!
|
41
42
|
|
42
|
-
|
43
|
+
@touched_at = Time.now
|
44
|
+
|
45
|
+
@@instances[id] = self
|
43
46
|
end
|
44
47
|
|
45
48
|
def update!(tweet)
|
@@ -79,24 +82,37 @@ module Twterm
|
|
79
82
|
def in_reply_to_status(&block)
|
80
83
|
block.call(nil) if @in_reply_to_status_id.nil?
|
81
84
|
|
82
|
-
status = Status.
|
85
|
+
status = Status.find(@in_reply_to_status_id)
|
83
86
|
block.call(status) unless status.nil?
|
84
87
|
|
85
88
|
Client.current.show_status(@in_reply_to_status_id, &block)
|
86
89
|
end
|
87
90
|
|
91
|
+
def touch!
|
92
|
+
@touched_at = Time.now
|
93
|
+
end
|
94
|
+
|
88
95
|
def ==(other)
|
89
96
|
other.is_a?(self.class) && id == other.id
|
90
97
|
end
|
91
98
|
|
92
99
|
class << self
|
93
|
-
def
|
94
|
-
@@instances
|
100
|
+
def find(id)
|
101
|
+
@@instances[id]
|
95
102
|
end
|
96
103
|
|
97
104
|
def parse_time(time)
|
98
105
|
(time.is_a?(String) ? Time.parse(time) : time.dup).localtime
|
99
106
|
end
|
107
|
+
|
108
|
+
def cleanup
|
109
|
+
count = MAX_CACHED_STATUSES_COUNT
|
110
|
+
return if @@instances.count < count
|
111
|
+
|
112
|
+
statuses = @@instances.values.sort_by(&:touched_at).take(count)
|
113
|
+
status_ids = statuses.map(&:id)
|
114
|
+
@@instances = status_ids.zip(statuses).to_h
|
115
|
+
end
|
100
116
|
end
|
101
117
|
end
|
102
118
|
end
|
data/lib/twterm/tab/new/start.rb
CHANGED
@@ -19,6 +19,10 @@ module Twterm
|
|
19
19
|
tab = Tab::New::Search.new
|
20
20
|
TabManager.instance.switch(tab)
|
21
21
|
tab.invoke_input
|
22
|
+
when 'U'
|
23
|
+
tab = Tab::New::User.new
|
24
|
+
TabManager.instance.switch(tab)
|
25
|
+
tab.invoke_input
|
22
26
|
else
|
23
27
|
return false
|
24
28
|
end
|
@@ -53,10 +57,17 @@ module Twterm
|
|
53
57
|
@window.addstr('[S]')
|
54
58
|
end
|
55
59
|
|
56
|
-
@window.setpos(
|
60
|
+
@window.setpos(8, 5)
|
61
|
+
@window.addstr('- [U] Open user tab')
|
62
|
+
@window.bold do
|
63
|
+
@window.setpos(8, 7)
|
64
|
+
@window.addstr('[U]')
|
65
|
+
end
|
66
|
+
|
67
|
+
@window.setpos(11, 3)
|
57
68
|
@window.addstr('To cancel opening a new tab, just press [w] to close this tab.')
|
58
69
|
@window.bold do
|
59
|
-
@window.setpos(
|
70
|
+
@window.setpos(11, 43)
|
60
71
|
@window.addstr('[w]')
|
61
72
|
end
|
62
73
|
@window.refresh
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Twterm
|
2
|
+
module Tab
|
3
|
+
module New
|
4
|
+
class User
|
5
|
+
include Base
|
6
|
+
include Readline
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
|
11
|
+
@title = 'New tab'
|
12
|
+
@window.refresh
|
13
|
+
end
|
14
|
+
|
15
|
+
def respond_to_key(_)
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def invoke_input
|
20
|
+
resetter = proc do
|
21
|
+
reset_prog_mode
|
22
|
+
sleep 0.1
|
23
|
+
Screen.instance.refresh
|
24
|
+
end
|
25
|
+
|
26
|
+
input_thread = Thread.new do
|
27
|
+
close_screen
|
28
|
+
puts "\nSearch user"
|
29
|
+
screen_name = readline('> @').strip
|
30
|
+
resetter.call
|
31
|
+
|
32
|
+
Client.current.show_user(screen_name) do |user|
|
33
|
+
if screen_name.nil? || screen_name.empty? || user.nil?
|
34
|
+
Notifier.instance.show_error 'User not found' if user.nil?
|
35
|
+
tab = Tab::New::Start.new
|
36
|
+
else
|
37
|
+
tab = Tab::UserTab.new(user)
|
38
|
+
end
|
39
|
+
|
40
|
+
TabManager.instance.switch(tab)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
App.instance.register_interruption_handler do
|
45
|
+
input_thread.kill
|
46
|
+
resetter.call
|
47
|
+
tab = Tab::New::Start.new
|
48
|
+
TabManager.instance.switch(tab)
|
49
|
+
end
|
50
|
+
|
51
|
+
input_thread.join
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def update; end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -8,16 +8,30 @@ module Twterm
|
|
8
8
|
def initialize
|
9
9
|
super
|
10
10
|
|
11
|
-
@
|
11
|
+
@status_ids = []
|
12
|
+
|
13
|
+
Thread.new do
|
14
|
+
loop do
|
15
|
+
statuses.take(100).each(&:touch!)
|
16
|
+
sleep 60
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def statuses
|
22
|
+
statuses = @status_ids.map { |id| Status.find(id) }.reject(&:nil?)
|
23
|
+
@status_ids = statuses.map(&:id)
|
24
|
+
statuses
|
12
25
|
end
|
13
26
|
|
14
27
|
def prepend(status)
|
15
28
|
fail unless status.is_a? Status
|
16
29
|
|
17
|
-
return if @
|
30
|
+
return if @status_ids.include?(status.id)
|
18
31
|
|
19
|
-
@
|
32
|
+
@status_ids << status.id
|
20
33
|
status.split(@window.maxx - 4)
|
34
|
+
status.touch!
|
21
35
|
item_prepended
|
22
36
|
refresh
|
23
37
|
end
|
@@ -25,10 +39,11 @@ module Twterm
|
|
25
39
|
def append(status)
|
26
40
|
fail ArgumentError, 'argument must be an instance of Status class' unless status.is_a? Status
|
27
41
|
|
28
|
-
return if @
|
42
|
+
return if @status_ids.include?(status.id)
|
29
43
|
|
30
|
-
@
|
44
|
+
@status_ids.unshift(status.id)
|
31
45
|
status.split(@window.maxx - 4)
|
46
|
+
status.touch!
|
32
47
|
item_appended
|
33
48
|
refresh
|
34
49
|
end
|
@@ -59,8 +74,7 @@ module Twterm
|
|
59
74
|
end
|
60
75
|
|
61
76
|
def delete_status(status_id)
|
62
|
-
|
63
|
-
@statuses.delete_if(&detector)
|
77
|
+
@status_ids.delete(status_id)
|
64
78
|
refresh
|
65
79
|
end
|
66
80
|
|
@@ -93,7 +107,7 @@ module Twterm
|
|
93
107
|
|
94
108
|
@window.clear
|
95
109
|
|
96
|
-
|
110
|
+
statuses.reverse.drop(offset).each.with_index(offset) do |status, i|
|
97
111
|
formatted_lines = status.split(@window.maxx - 4).count
|
98
112
|
if current_line + formatted_lines + 2 > @window.maxy
|
99
113
|
@scrollable_last = i
|
@@ -202,18 +216,19 @@ module Twterm
|
|
202
216
|
private
|
203
217
|
|
204
218
|
def highlighted_status
|
205
|
-
@
|
219
|
+
id = @status_ids[count - index - 1]
|
220
|
+
Status.find(id)
|
206
221
|
end
|
207
222
|
|
208
223
|
def count
|
209
|
-
@
|
224
|
+
@status_ids.count
|
210
225
|
end
|
211
226
|
|
212
227
|
def offset_from_bottom
|
213
228
|
return @offset_from_bottom unless @offset_from_bottom.nil?
|
214
229
|
|
215
230
|
height = 0
|
216
|
-
|
231
|
+
statuses.each.with_index(-1) do |status, i|
|
217
232
|
height += status.split(@window.maxx - 4).count + 2
|
218
233
|
if height >= @window.maxy
|
219
234
|
@offset_from_bottom = i
|
@@ -224,7 +239,7 @@ module Twterm
|
|
224
239
|
end
|
225
240
|
|
226
241
|
def sort
|
227
|
-
@
|
242
|
+
@status_ids.sort_by! { |id| Status.find(id).created_at_for_sort }
|
228
243
|
end
|
229
244
|
|
230
245
|
def show_help
|
data/lib/twterm/tab/user_tab.rb
CHANGED
data/lib/twterm/tweetbox.rb
CHANGED
@@ -23,7 +23,11 @@ module Twterm
|
|
23
23
|
|
24
24
|
thread = Thread.new do
|
25
25
|
close_screen
|
26
|
-
|
26
|
+
if @in_reply_to.nil?
|
27
|
+
puts "\nCompose new tweet:"
|
28
|
+
else
|
29
|
+
puts "\nReply to @#{@in_reply_to.user.screen_name}'s tweet: \"#{@in_reply_to.text}\""
|
30
|
+
end
|
27
31
|
@status = readline(@in_reply_to.nil? ? '> ' : " @#{in_reply_to.user.screen_name} ", true)
|
28
32
|
resetter.call
|
29
33
|
post
|
data/lib/twterm/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twterm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryota Kameoka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -146,6 +146,7 @@ files:
|
|
146
146
|
- lib/twterm/tab/new/list.rb
|
147
147
|
- lib/twterm/tab/new/search.rb
|
148
148
|
- lib/twterm/tab/new/start.rb
|
149
|
+
- lib/twterm/tab/new/user.rb
|
149
150
|
- lib/twterm/tab/scrollable.rb
|
150
151
|
- lib/twterm/tab/search_tab.rb
|
151
152
|
- lib/twterm/tab/statuses_tab.rb
|