twterm 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/bin/twterm +4 -4
  3. data/lib/twterm/app.rb +19 -4
  4. data/lib/twterm/client.rb +8 -470
  5. data/lib/twterm/direct_message.rb +82 -0
  6. data/lib/twterm/direct_message_composer.rb +74 -0
  7. data/lib/twterm/direct_message_manager.rb +52 -0
  8. data/lib/twterm/event/base.rb +22 -0
  9. data/lib/twterm/event/direct_message/fetched.rb +10 -0
  10. data/lib/twterm/event/favorite.rb +18 -0
  11. data/lib/twterm/event/follow.rb +17 -0
  12. data/lib/twterm/event/notification.rb +33 -0
  13. data/lib/twterm/event/open_uri.rb +11 -0
  14. data/lib/twterm/event/screen/resize.rb +13 -0
  15. data/lib/twterm/event/status/base.rb +14 -0
  16. data/lib/twterm/event/status/delete.rb +13 -0
  17. data/lib/twterm/event/status/mention.rb +10 -0
  18. data/lib/twterm/event/status/timeline.rb +10 -0
  19. data/lib/twterm/event_dispatcher.rb +59 -0
  20. data/lib/twterm/filter_query_window.rb +11 -5
  21. data/lib/twterm/filterable_list.rb +6 -1
  22. data/lib/twterm/notifier.rb +39 -15
  23. data/lib/twterm/promise.rb +2 -2
  24. data/lib/twterm/publisher.rb +16 -0
  25. data/lib/twterm/rest_client.rb +401 -0
  26. data/lib/twterm/screen.rb +16 -13
  27. data/lib/twterm/status.rb +12 -1
  28. data/lib/twterm/streaming_client.rb +103 -0
  29. data/lib/twterm/subscriber.rb +33 -0
  30. data/lib/twterm/tab/base.rb +13 -6
  31. data/lib/twterm/tab/direct_message/conversation.rb +103 -0
  32. data/lib/twterm/tab/direct_message/conversation_list.rb +99 -0
  33. data/lib/twterm/tab/key_assignments_cheatsheet.rb +3 -2
  34. data/lib/twterm/tab/new/list.rb +5 -3
  35. data/lib/twterm/tab/new/search.rb +3 -2
  36. data/lib/twterm/tab/new/start.rb +17 -2
  37. data/lib/twterm/tab/new/user.rb +6 -3
  38. data/lib/twterm/tab/statuses/base.rb +18 -11
  39. data/lib/twterm/tab/statuses/conversation.rb +3 -2
  40. data/lib/twterm/tab/statuses/favorites.rb +3 -2
  41. data/lib/twterm/tab/statuses/home.rb +10 -4
  42. data/lib/twterm/tab/statuses/list_timeline.rb +3 -2
  43. data/lib/twterm/tab/statuses/mentions.rb +6 -6
  44. data/lib/twterm/tab/statuses/search.rb +4 -3
  45. data/lib/twterm/tab/statuses/user_timeline.rb +3 -2
  46. data/lib/twterm/tab/user_tab.rb +26 -16
  47. data/lib/twterm/tab/users/base.rb +3 -2
  48. data/lib/twterm/tab/users/followers.rb +3 -2
  49. data/lib/twterm/tab/users/friends.rb +3 -2
  50. data/lib/twterm/tab_manager.rb +20 -8
  51. data/lib/twterm/tweetbox.rb +5 -2
  52. data/lib/twterm/uri_opener.rb +25 -0
  53. data/lib/twterm/user.rb +11 -1
  54. data/lib/twterm/utils.rb +13 -0
  55. data/lib/twterm/version.rb +1 -1
  56. data/lib/twterm.rb +0 -3
  57. data/spec/twterm/event/screen/resize_spec.rb +11 -0
  58. data/spec/twterm/event_dispatcher_spec.rb +19 -0
  59. data/twterm.gemspec +1 -1
  60. metadata +29 -7
  61. data/lib/twterm/notification/base.rb +0 -24
  62. data/lib/twterm/notification/error.rb +0 -19
  63. data/lib/twterm/notification/message.rb +0 -19
@@ -1,12 +1,20 @@
1
+ require 'twterm/event/screen/resize'
2
+ require 'twterm/publisher'
3
+ require 'twterm/subscriber'
4
+ require 'twterm/utils'
5
+
1
6
  module Twterm
2
7
  class TabManager
3
8
  include Singleton
4
9
  include Curses
10
+ include Publisher
11
+ include Subscriber
12
+ include Utils
5
13
 
6
14
  DUMPED_TABS_FILE = "#{ENV['HOME']}/.twterm/dumped_tabs"
7
15
 
8
16
  def add(tab_to_add)
9
- fail ArgumentError, 'argument must be an instance of Tab::Base' unless tab_to_add.is_a? Tab::Base
17
+ check_type Tab::Base, tab_to_add
10
18
 
11
19
  @tabs.each.with_index do |tab, i|
12
20
  next unless tab == tab_to_add
@@ -37,7 +45,7 @@ module Twterm
37
45
  current_tab.refresh
38
46
  refresh_window
39
47
  rescue Tab::NotClosableError
40
- Notifier.instance.show_error 'This tab cannot be closed'
48
+ publish(Event::Notification.new(:error, 'this tab cannot be closed'))
41
49
  end
42
50
 
43
51
  def current_tab
@@ -67,6 +75,8 @@ module Twterm
67
75
  @history = []
68
76
 
69
77
  @window = stdscr.subwin(3, stdscr.maxx, 0, 0)
78
+
79
+ subscribe(Event::Screen::Resize, :resize)
70
80
  end
71
81
 
72
82
  def open_my_profile
@@ -93,7 +103,7 @@ module Twterm
93
103
  add(tab)
94
104
  end
95
105
  rescue
96
- Notifier.instance.show_error 'Failed to recover tabs'
106
+ publish(Event::Notification.new(:error, 'Failed to recover tabs'))
97
107
  end
98
108
 
99
109
  def refresh_window
@@ -116,11 +126,6 @@ module Twterm
116
126
  @window.refresh
117
127
  end
118
128
 
119
- def resize
120
- @window.resize(3, stdscr.maxx)
121
- @window.move(0, 0)
122
- end
123
-
124
129
  def respond_to_key(key)
125
130
  case key
126
131
  when ?1..?9
@@ -163,5 +168,12 @@ module Twterm
163
168
  close
164
169
  add_and_show(tab)
165
170
  end
171
+
172
+ private
173
+
174
+ def resize(event)
175
+ @window.resize(3, stdscr.maxx)
176
+ @window.move(0, 0)
177
+ end
166
178
  end
167
179
  end
@@ -1,3 +1,5 @@
1
+ require 'twterm/publisher'
2
+
1
3
  module Twterm
2
4
  class Tweetbox
3
5
  class EmptyTextError < StandardError; end
@@ -7,6 +9,7 @@ module Twterm
7
9
  include Singleton
8
10
  include Readline
9
11
  include Curses
12
+ include Publisher
10
13
 
11
14
  def compose(in_reply_to = nil)
12
15
  @text = ''
@@ -94,9 +97,9 @@ module Twterm
94
97
  rescue EmptyTextError
95
98
  # do nothing
96
99
  rescue InvalidCharactersError
97
- Notifier.instance.show_error 'Text contains invalid characters'
100
+ publish(Event::Notification.new(:error, 'Text contains invalid characters'))
98
101
  rescue TextTooLongError
99
- Notifier.instance.show_error "Text is too long (#{text_length} / 140 characters)"
102
+ publish(Event::Notification.new(:error, "Text is too long (#{text_length} / 140 characters)"))
100
103
  ensure
101
104
  clear
102
105
  end
@@ -0,0 +1,25 @@
1
+ require 'launchy'
2
+ require 'singleton'
3
+ require 'twterm/event/open_uri'
4
+ require 'twterm/publisher'
5
+ require 'twterm/subscriber'
6
+
7
+ module Twterm
8
+ class URIOpener
9
+ include Publisher
10
+ include Singleton
11
+ include Subscriber
12
+
13
+ def initialize
14
+ subscribe(Event::OpenURI) { |e| open e.uri }
15
+ end
16
+
17
+ private
18
+
19
+ def open(uri)
20
+ Launchy.open(uri)
21
+ rescue Launchy::CommandNotFoundError
22
+ publish(Event::Notification.new(:error, 'Browser not found'))
23
+ end
24
+ end
25
+ end
data/lib/twterm/user.rb CHANGED
@@ -61,6 +61,8 @@ module Twterm
61
61
  end
62
62
 
63
63
  def update!(user)
64
+ return self if recently_updated?
65
+
64
66
  @name = user.name
65
67
  @screen_name = user.screen_name
66
68
  @description = user.description || ''
@@ -87,6 +89,8 @@ module Twterm
87
89
  Friendship.following_not_requested(client_id, user.id)
88
90
  end
89
91
 
92
+ @updated_at = Time.now
93
+
90
94
  self
91
95
  end
92
96
 
@@ -116,7 +120,7 @@ module Twterm
116
120
  cond = -> (user) { user.touched_at > Time.now - MAX_CACHED_TIME }
117
121
  users = all.select(&cond)
118
122
  user_ids = users.map(&:id)
119
- @@instances = user_ids.zip(users).to_h
123
+ @@instances = Hash[user_ids.zip(users)]
120
124
  end
121
125
 
122
126
  def self.ids
@@ -127,5 +131,11 @@ module Twterm
127
131
  instance = find(user.id)
128
132
  instance.nil? ? super : instance.update!(user)
129
133
  end
134
+
135
+ private
136
+
137
+ def recently_updated?
138
+ !@updated_at.nil? && @updated_at + 60 > Time.now
139
+ end
130
140
  end
131
141
  end
@@ -0,0 +1,13 @@
1
+ module Twterm
2
+ module Utils
3
+ module_function
4
+
5
+ def check_type(expected_type, argument)
6
+ return if argument.is_a?(expected_type)
7
+
8
+ raise TypeError, 'TypeError: wrong argument type %s (expected %s)' % [
9
+ argument.class, expected_type
10
+ ]
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module Twterm
2
- VERSION = '1.1.3'
2
+ VERSION = '1.2.0'
3
3
  end
data/lib/twterm.rb CHANGED
@@ -32,9 +32,6 @@ require 'twterm/history/savable'
32
32
  require 'twterm/history/hashtag'
33
33
  require 'twterm/history/screen_name'
34
34
  require 'twterm/list'
35
- require 'twterm/notification/base'
36
- require 'twterm/notification/message'
37
- require 'twterm/notification/error'
38
35
  require 'twterm/notifier'
39
36
  require 'twterm/promise'
40
37
  require 'twterm/screen'
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ require 'twterm/event/screen/resize'
3
+
4
+ RSpec.describe Twterm::Event::Screen::Resize do
5
+ describe '#fields' do
6
+ it 'has fields of Integer * Integer' do
7
+ expect { described_class.new(5, 10) }.not_to raise_error
8
+ expect { described_class.new('hello', 'world') }.to raise_error
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Twterm::EventDispatcher do
4
+ let(:event_dispatcher) { described_class.instance }
5
+
6
+ describe '#dispatch' do
7
+ subject { event_dispatcher.dispatch(event) }
8
+
9
+ let(:event) { Twterm::Event::Base.new }
10
+
11
+ it { is_expected.to eq event_dispatcher }
12
+ end
13
+
14
+ describe '.instance' do
15
+ subject { described_class.instance }
16
+
17
+ it { is_expected.to be_kind_of described_class }
18
+ end
19
+ end
data/twterm.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files -z`.split("\x0").reject { |i| i == 'Gemfile.lock' }
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.require_paths = ['lib']
19
- spec.required_ruby_version = '>= 2.1.0'
19
+ spec.required_ruby_version = '>= 2.0.0'
20
20
 
21
21
  spec.add_dependency 'curses', '>= 1.0.1'
22
22
  spec.add_dependency 'launchy', '>= 2.4.3'
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.1.3
4
+ version: 1.2.0
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-12-16 00:00:00.000000000 Z
11
+ date: 2016-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -158,6 +158,21 @@ files:
158
158
  - lib/twterm/color_manager.rb
159
159
  - lib/twterm/completion_mamanger.rb
160
160
  - lib/twterm/config.rb
161
+ - lib/twterm/direct_message.rb
162
+ - lib/twterm/direct_message_composer.rb
163
+ - lib/twterm/direct_message_manager.rb
164
+ - lib/twterm/event/base.rb
165
+ - lib/twterm/event/direct_message/fetched.rb
166
+ - lib/twterm/event/favorite.rb
167
+ - lib/twterm/event/follow.rb
168
+ - lib/twterm/event/notification.rb
169
+ - lib/twterm/event/open_uri.rb
170
+ - lib/twterm/event/screen/resize.rb
171
+ - lib/twterm/event/status/base.rb
172
+ - lib/twterm/event/status/delete.rb
173
+ - lib/twterm/event/status/mention.rb
174
+ - lib/twterm/event/status/timeline.rb
175
+ - lib/twterm/event_dispatcher.rb
161
176
  - lib/twterm/extensions/curses/window.rb
162
177
  - lib/twterm/extensions/enumerator/lazy.rb
163
178
  - lib/twterm/extensions/integer.rb
@@ -170,15 +185,18 @@ files:
170
185
  - lib/twterm/history/savable.rb
171
186
  - lib/twterm/history/screen_name.rb
172
187
  - lib/twterm/list.rb
173
- - lib/twterm/notification/base.rb
174
- - lib/twterm/notification/error.rb
175
- - lib/twterm/notification/message.rb
176
188
  - lib/twterm/notifier.rb
177
189
  - lib/twterm/promise.rb
190
+ - lib/twterm/publisher.rb
191
+ - lib/twterm/rest_client.rb
178
192
  - lib/twterm/scheduler.rb
179
193
  - lib/twterm/screen.rb
180
194
  - lib/twterm/status.rb
195
+ - lib/twterm/streaming_client.rb
196
+ - lib/twterm/subscriber.rb
181
197
  - lib/twterm/tab/base.rb
198
+ - lib/twterm/tab/direct_message/conversation.rb
199
+ - lib/twterm/tab/direct_message/conversation_list.rb
182
200
  - lib/twterm/tab/dumpable.rb
183
201
  - lib/twterm/tab/exceptions.rb
184
202
  - lib/twterm/tab/favorites.rb
@@ -202,11 +220,15 @@ files:
202
220
  - lib/twterm/tab/users/friends.rb
203
221
  - lib/twterm/tab_manager.rb
204
222
  - lib/twterm/tweetbox.rb
223
+ - lib/twterm/uri_opener.rb
205
224
  - lib/twterm/user.rb
225
+ - lib/twterm/utils.rb
206
226
  - lib/twterm/version.rb
207
227
  - spec/resources/config
208
228
  - spec/spec_helper.rb
209
229
  - spec/twterm/config_spec.rb
230
+ - spec/twterm/event/screen/resize_spec.rb
231
+ - spec/twterm/event_dispatcher_spec.rb
210
232
  - spec/twterm/friendship_spec.rb
211
233
  - twterm.gemspec
212
234
  homepage: http://twterm.ryota-ka.me/
@@ -221,7 +243,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
221
243
  requirements:
222
244
  - - ">="
223
245
  - !ruby/object:Gem::Version
224
- version: 2.1.0
246
+ version: 2.0.0
225
247
  required_rubygems_version: !ruby/object:Gem::Requirement
226
248
  requirements:
227
249
  - - ">="
@@ -229,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
229
251
  version: '0'
230
252
  requirements: []
231
253
  rubyforge_project:
232
- rubygems_version: 2.4.7
254
+ rubygems_version: 2.5.1
233
255
  signing_key:
234
256
  specification_version: 4
235
257
  summary: A full-featured CLI Twitter client
@@ -1,24 +0,0 @@
1
- module Twterm
2
- module Notification
3
- module Base
4
- attr_reader :time, :fg_color, :bg_color
5
-
6
- def initialize(message)
7
- @message = CGI.unescapeHTML(message)
8
- @time = Time.now
9
- end
10
-
11
- def show_with_width(width)
12
- @message.gsub("\n", ' ')
13
- end
14
-
15
- def fg_color
16
- fail NotImplementedError, 'fg_color method must be implemented'
17
- end
18
-
19
- def bg_color
20
- fail NotImplementedError, 'bg_color method must be implemented'
21
- end
22
- end
23
- end
24
- end
@@ -1,19 +0,0 @@
1
- module Twterm
2
- module Notification
3
- class Error
4
- include Base
5
-
6
- def initialize(message)
7
- super
8
- end
9
-
10
- def fg_color
11
- :white
12
- end
13
-
14
- def bg_color
15
- :red
16
- end
17
- end
18
- end
19
- end
@@ -1,19 +0,0 @@
1
- module Twterm
2
- module Notification
3
- class Message
4
- include Base
5
-
6
- def initialize(message)
7
- super
8
- end
9
-
10
- def fg_color
11
- :white
12
- end
13
-
14
- def bg_color
15
- :blue
16
- end
17
- end
18
- end
19
- end