twterm 1.1.3 → 1.2.0

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.
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