twterm 1.3.0 → 2.0.0.beta1

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 (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -18
  3. data/bin/twterm +1 -1
  4. data/lib/twterm/app.rb +120 -30
  5. data/lib/twterm/client.rb +10 -13
  6. data/lib/twterm/completion_mamanger.rb +11 -6
  7. data/lib/twterm/direct_message.rb +6 -28
  8. data/lib/twterm/direct_message_composer.rb +10 -5
  9. data/lib/twterm/direct_message_manager.rb +5 -6
  10. data/lib/twterm/event/notification/abstract_notification.rb +27 -0
  11. data/lib/twterm/event/notification/error.rb +13 -0
  12. data/lib/twterm/event/notification/info.rb +13 -0
  13. data/lib/twterm/event/notification/success.rb +13 -0
  14. data/lib/twterm/event/notification/warning.rb +13 -0
  15. data/lib/twterm/event_dispatcher.rb +1 -1
  16. data/lib/twterm/extensions/array.rb +5 -0
  17. data/lib/twterm/extensions/enumerator/lazy.rb +3 -0
  18. data/lib/twterm/extensions/string.rb +0 -4
  19. data/lib/twterm/friendship.rb +1 -85
  20. data/lib/twterm/image/between.rb +31 -0
  21. data/lib/twterm/image/blank_line.rb +21 -0
  22. data/lib/twterm/image/bold.rb +31 -0
  23. data/lib/twterm/image/brackets.rb +21 -0
  24. data/lib/twterm/image/color.rb +45 -0
  25. data/lib/twterm/image/empty.rb +21 -0
  26. data/lib/twterm/image/horizontal_sequential_image.rb +48 -0
  27. data/lib/twterm/image/parens.rb +21 -0
  28. data/lib/twterm/image/string_image.rb +38 -0
  29. data/lib/twterm/image/vertical_sequential_image.rb +43 -0
  30. data/lib/twterm/image.rb +107 -0
  31. data/lib/twterm/key_mapper/abstract_key_mapper.rb +51 -0
  32. data/lib/twterm/key_mapper/app_key_mapper.rb +13 -0
  33. data/lib/twterm/key_mapper/cursor_key_mapper.rb +13 -0
  34. data/lib/twterm/key_mapper/general_key_mapper.rb +18 -0
  35. data/lib/twterm/key_mapper/no_such_command.rb +20 -0
  36. data/lib/twterm/key_mapper/no_such_key.rb +16 -0
  37. data/lib/twterm/key_mapper/status_key_mapper.rb +18 -0
  38. data/lib/twterm/key_mapper/tab_key_mapper.rb +31 -0
  39. data/lib/twterm/key_mapper.rb +127 -0
  40. data/lib/twterm/list.rb +0 -31
  41. data/lib/twterm/notifier.rb +7 -7
  42. data/lib/twterm/repository/abstract_entity_repository.rb +41 -0
  43. data/lib/twterm/repository/abstract_expirable_entity_repository.rb +35 -0
  44. data/lib/twterm/repository/abstract_repository.rb +64 -0
  45. data/lib/twterm/repository/direct_message_repository.rb +14 -0
  46. data/lib/twterm/repository/friendship_repository.rb +108 -0
  47. data/lib/twterm/repository/hashtag_repository.rb +39 -0
  48. data/lib/twterm/repository/list_repository.rb +14 -0
  49. data/lib/twterm/repository/status_repository.rb +36 -0
  50. data/lib/twterm/repository/user_repository.rb +22 -0
  51. data/lib/twterm/rest_client.rb +107 -63
  52. data/lib/twterm/screen.rb +21 -15
  53. data/lib/twterm/search_query_window.rb +139 -0
  54. data/lib/twterm/status.rb +14 -108
  55. data/lib/twterm/streaming_client.rb +13 -12
  56. data/lib/twterm/tab/base.rb +48 -8
  57. data/lib/twterm/tab/direct_message/conversation.rb +53 -52
  58. data/lib/twterm/tab/direct_message/conversation_list.rb +46 -45
  59. data/lib/twterm/tab/dumpable.rb +3 -3
  60. data/lib/twterm/tab/key_assignments_cheatsheet.rb +58 -57
  61. data/lib/twterm/tab/loadable.rb +20 -0
  62. data/lib/twterm/tab/new/list.rb +32 -43
  63. data/lib/twterm/tab/new/search.rb +31 -44
  64. data/lib/twterm/tab/new/start.rb +44 -55
  65. data/lib/twterm/tab/new/user.rb +15 -12
  66. data/lib/twterm/tab/rate_limit_status.rb +84 -0
  67. data/lib/twterm/tab/scrollable.rb +39 -19
  68. data/lib/twterm/tab/searchable.rb +133 -0
  69. data/lib/twterm/tab/statuses/base.rb +139 -129
  70. data/lib/twterm/tab/statuses/conversation.rb +26 -15
  71. data/lib/twterm/tab/statuses/favorites.rb +10 -8
  72. data/lib/twterm/tab/statuses/home.rb +10 -9
  73. data/lib/twterm/tab/statuses/list_timeline.rb +12 -8
  74. data/lib/twterm/tab/statuses/mentions.rb +17 -11
  75. data/lib/twterm/tab/statuses/search.rb +8 -5
  76. data/lib/twterm/tab/statuses/user_timeline.rb +11 -8
  77. data/lib/twterm/tab/user_list_management.rb +109 -0
  78. data/lib/twterm/tab/user_tab.rb +125 -126
  79. data/lib/twterm/tab/users/base.rb +39 -41
  80. data/lib/twterm/tab/users/followers.rb +9 -6
  81. data/lib/twterm/tab/users/friends.rb +9 -6
  82. data/lib/twterm/tab_manager.rb +64 -40
  83. data/lib/twterm/tweetbox.rb +18 -13
  84. data/lib/twterm/uri_opener.rb +2 -1
  85. data/lib/twterm/user.rb +2 -110
  86. data/lib/twterm/version.rb +1 -1
  87. data/lib/twterm/view.rb +30 -0
  88. data/lib/twterm.rb +3 -9
  89. data/spec/fixtures/status.json +107 -0
  90. data/spec/fixtures/user.json +102 -0
  91. data/spec/spec_helper.rb +7 -0
  92. data/spec/supports/shared_examples/abstract_key_mapper.rb +17 -0
  93. data/spec/twterm/extension/enumerator/lazy_spec.rb +11 -0
  94. data/spec/twterm/friendship_spec.rb +0 -102
  95. data/spec/twterm/image/blank_line_spec.rb +11 -0
  96. data/spec/twterm/image/brackets_spec.rb +12 -0
  97. data/spec/twterm/image/color_spec.rb +22 -0
  98. data/spec/twterm/image/empry_spec.rb +11 -0
  99. data/spec/twterm/image/horizontal_sequential_image_spec.rb +15 -0
  100. data/spec/twterm/image/parens_spec.rb +12 -0
  101. data/spec/twterm/image/string_image_spec.rb +12 -0
  102. data/spec/twterm/image/vertical_sequential_image_spec.rb +14 -0
  103. data/spec/twterm/image_spec.rb +65 -0
  104. data/spec/twterm/key_mapper/abstract_key_mapper_spec.rb +21 -0
  105. data/spec/twterm/key_mapper/app_key_mapper_spec.rb +7 -0
  106. data/spec/twterm/key_mapper/status_key_mapper_spec.rb +7 -0
  107. data/spec/twterm/key_mapper/tab_key_mapper_spec.rb +7 -0
  108. data/spec/twterm/repository/friendship_repository_spec.rb +108 -0
  109. data/spec/twterm/status_spec.rb +58 -0
  110. data/spec/twterm/user_spec.rb +94 -0
  111. data/twterm.gemspec +13 -10
  112. metadata +129 -35
  113. data/lib/twterm/event/notification.rb +0 -33
  114. data/lib/twterm/extensions/integer.rb +0 -5
  115. data/lib/twterm/filter_query_window.rb +0 -91
  116. data/lib/twterm/filterable_list.rb +0 -41
  117. data/lib/twterm/history/base.rb +0 -21
  118. data/lib/twterm/history/hashtag.rb +0 -13
  119. data/lib/twterm/history/savable.rb +0 -37
  120. data/lib/twterm/history/screen_name.rb +0 -11
  121. data/lib/twterm/promise.rb +0 -143
@@ -13,18 +13,21 @@ module Twterm
13
13
  end
14
14
 
15
15
  def fetch
16
- Client.current.friends(user_id) do |users|
16
+ client.friends(user_id) do |users|
17
17
  @user_ids.concat(users.map(&:id)).uniq!
18
- refresh
18
+ render
19
19
  end
20
20
  end
21
21
 
22
- def initialize(user_id)
23
- super()
22
+ def initialize(app, client, user_id)
23
+ super(app, client)
24
24
 
25
25
  @user_id = user_id
26
26
 
27
- fetch { move_to_top }
27
+ fetch.then do
28
+ initially_loaded!
29
+ move_to_top
30
+ end
28
31
  end
29
32
 
30
33
  def title
@@ -34,7 +37,7 @@ module Twterm
34
37
  private
35
38
 
36
39
  def user
37
- User.find(user_id)
40
+ app.user_repository.find(user_id)
38
41
  end
39
42
  end
40
43
  end
@@ -2,10 +2,10 @@ require 'twterm/event/screen/resize'
2
2
  require 'twterm/publisher'
3
3
  require 'twterm/subscriber'
4
4
  require 'twterm/utils'
5
+ require 'twterm/view'
5
6
 
6
7
  module Twterm
7
8
  class TabManager
8
- include Singleton
9
9
  include Curses
10
10
  include Publisher
11
11
  include Subscriber
@@ -31,7 +31,7 @@ module Twterm
31
31
  def add_and_show(tab)
32
32
  result = add(tab)
33
33
  @index = @tabs.count - 1 if result
34
- current_tab.refresh
34
+ current_tab.render
35
35
  refresh_window
36
36
  result
37
37
  end
@@ -42,10 +42,10 @@ module Twterm
42
42
  @history.delete_if { |n| n == @index }
43
43
  @history = @history.map { |i| i > @index ? i - 1 : i }
44
44
  @index = @history.first
45
- current_tab.refresh
45
+ current_tab.render
46
46
  refresh_window
47
47
  rescue Tab::NotClosableError
48
- publish(Event::Notification.new(:error, 'this tab cannot be closed'))
48
+ publish(Event::Notification::Warning.new('this tab cannot be closed'))
49
49
  end
50
50
 
51
51
  def current_tab
@@ -69,7 +69,9 @@ module Twterm
69
69
  end
70
70
  end
71
71
 
72
- def initialize
72
+ def initialize(app, client)
73
+ @app, @client = app, client
74
+
73
75
  @tabs = []
74
76
  @index = 0
75
77
  @history = []
@@ -80,71 +82,83 @@ module Twterm
80
82
  end
81
83
 
82
84
  def open_my_profile
83
- current_user_id = Client.current.user_id
84
- tab = Tab::UserTab.new(current_user_id)
85
+ current_user_id = client.user_id
86
+ tab = Tab::UserTab.new(app, client, current_user_id)
85
87
  add_and_show(tab)
86
88
  end
87
89
 
88
90
  def open_new
89
- tab = Tab::New::Start.new
91
+ tab = Tab::New::Start.new(app, client)
90
92
  add_and_show(tab)
91
93
  end
92
94
 
93
95
  def recover_tabs
94
96
  unless File.exist? DUMPED_TABS_FILE
95
- tab = Tab::KeyAssignmentsCheatsheet.new
97
+ tab = Tab::KeyAssignmentsCheatsheet.new(app, client)
96
98
  add(tab)
97
99
  return
98
100
  end
99
101
 
100
102
  data = YAML.load(File.read(DUMPED_TABS_FILE))
101
103
  data.each do |klass, title, arg|
102
- tab = klass.recover(title, arg)
104
+ tab = klass.recover(app, client, title, arg)
103
105
  add(tab)
104
106
  end
105
107
  rescue
106
- publish(Event::Notification.new(:error, 'Failed to recover tabs'))
108
+ publish(Event::Notification::Error.new('Failed to recover tabs'))
107
109
  end
108
110
 
109
111
  def refresh_window
110
112
  @window.clear
111
- current_tab_id = current_tab.object_id
113
+ view.render
114
+ @window.refresh
115
+ end
112
116
 
113
- @window.setpos(1, 1)
114
- @window.addstr('| ')
115
- @tabs.each do |tab|
116
- if tab.object_id == current_tab_id
117
- @window.bold do
118
- @window.addstr(tab.title)
119
- end
120
- else
121
- @window.addstr(tab.title)
122
- end
123
- @window.addstr(' | ')
124
- end
117
+ def view
118
+ wss = Image.string(' ')
119
+ pipe = Image.string('|')
125
120
 
126
- @window.refresh
121
+ image = @tabs
122
+ .map { |t| [t, Image.string(t.title)] }
123
+ .map { |t, r| t.equal?(current_tab) ? !r : r }
124
+ .reduce(pipe) { |acc, x| acc - wss - x - wss - pipe }
125
+
126
+ View.new(@window, image).at(1, 1)
127
127
  end
128
128
 
129
129
  def respond_to_key(key)
130
+ k = KeyMapper.instance
131
+
130
132
  case key
131
- when ?1..?9
132
- @index = key.to_i - 1 if @tabs.count >= key.to_i
133
- current_tab.refresh
134
- refresh_window
135
- when ?0
136
- @index = @tabs.count - 1
137
- current_tab.refresh
138
- refresh_window
139
- when ?h, 2, Key::LEFT
133
+ when k[:tab, :'1st']
134
+ show_nth_tab(0)
135
+ when k[:tab, :'2nd']
136
+ show_nth_tab(1)
137
+ when k[:tab, :'3rd']
138
+ show_nth_tab(2)
139
+ when k[:tab, :'4th']
140
+ show_nth_tab(3)
141
+ when k[:tab, :'5th']
142
+ show_nth_tab(4)
143
+ when k[:tab, :'6th']
144
+ show_nth_tab(5)
145
+ when k[:tab, :'7th']
146
+ show_nth_tab(6)
147
+ when k[:tab, :'8th']
148
+ show_nth_tab(7)
149
+ when k[:tab, :'9th']
150
+ show_nth_tab(8)
151
+ when k[:tab, :last]
152
+ show_nth_tab(@tabs.count - 1)
153
+ when k[:general, :left], Curses::Key::LEFT
140
154
  show_previous
141
- when ?l, 6, Key::RIGHT
155
+ when k[:general, :right], Curses::Key::RIGHT
142
156
  show_next
143
- when ?P
157
+ when k[:app, :me]
144
158
  open_my_profile
145
- when ?N
159
+ when k[:tab, :new]
146
160
  open_new
147
- when ?w
161
+ when k[:tab, :close]
148
162
  close
149
163
  else
150
164
  return false
@@ -154,13 +168,21 @@ module Twterm
154
168
 
155
169
  def show_next
156
170
  @index = (@index + 1) % @tabs.count
157
- current_tab.refresh
171
+ current_tab.render
172
+ refresh_window
173
+ end
174
+
175
+ def show_nth_tab(n)
176
+ return unless n < @tabs.count
177
+
178
+ @index = n
179
+ current_tab.render
158
180
  refresh_window
159
181
  end
160
182
 
161
183
  def show_previous
162
184
  @index = (@index - 1) % @tabs.count
163
- current_tab.refresh
185
+ current_tab.render
164
186
  refresh_window
165
187
  end
166
188
 
@@ -171,6 +193,8 @@ module Twterm
171
193
 
172
194
  private
173
195
 
196
+ attr_reader :app, :client
197
+
174
198
  def resize(event)
175
199
  @window.resize(3, stdscr.maxx)
176
200
  @window.move(0, 0)
@@ -1,4 +1,5 @@
1
1
  require 'twterm/publisher'
2
+ require 'twterm/event/notification/error'
2
3
 
3
4
  module Twterm
4
5
  class Tweetbox
@@ -6,24 +7,28 @@ module Twterm
6
7
  class InvalidCharactersError < StandardError; end
7
8
  class TextTooLongError < StandardError; end
8
9
 
9
- include Singleton
10
10
  include Readline
11
11
  include Curses
12
12
  include Publisher
13
13
 
14
+ def initialize(app, client)
15
+ @app, @client = app, client
16
+ end
17
+
14
18
  def compose(in_reply_to = nil)
15
19
  @text = ''
16
20
 
17
- if in_reply_to.is_a? Status
18
- @in_reply_to = in_reply_to
21
+ @in_reply_to, screen_name =
22
+ if in_reply_to.is_a?(Status)
23
+ [in_reply_to, app.user_repository.find(in_reply_to.user_id).screen_name]
19
24
  else
20
- @in_reply_to = nil
25
+ [nil, nil]
21
26
  end
22
27
 
23
28
  resetter = proc do
24
29
  reset_prog_mode
25
30
  sleep 0.1
26
- Screen.instance.refresh
31
+ app.screen.refresh
27
32
  end
28
33
 
29
34
  thread = Thread.new do
@@ -32,14 +37,14 @@ module Twterm
32
37
  if in_reply_to.nil?
33
38
  puts "\nCompose new tweet:"
34
39
  else
35
- puts "\nReply to @#{in_reply_to.user.screen_name}'s tweet: \"#{in_reply_to.text}\""
40
+ puts "\nReply to @#{screen_name}'s tweet: \"#{in_reply_to.text}\""
36
41
  end
37
42
 
38
- CompletionManager.instance.set_default_mode!
43
+ app.completion_manager.set_default_mode!
39
44
 
40
45
  loop do
41
46
  loop do
42
- msg = in_reply_to.nil? || !text.empty? ? '> ' : "> @#{in_reply_to.user.screen_name} "
47
+ msg = in_reply_to.nil? || !text.empty? ? '> ' : "> @#{screen_name} "
43
48
  line = (readline(msg, true) || '').strip
44
49
  break if line.empty?
45
50
 
@@ -72,7 +77,7 @@ module Twterm
72
77
  post
73
78
  end
74
79
 
75
- App.instance.register_interruption_handler do
80
+ app.register_interruption_handler do
76
81
  thread.kill
77
82
  clear
78
83
  puts "\nCanceled"
@@ -84,7 +89,7 @@ module Twterm
84
89
 
85
90
  private
86
91
 
87
- attr_reader :in_reply_to
92
+ attr_reader :app, :client, :in_reply_to
88
93
 
89
94
  def clear
90
95
  @text = ''
@@ -93,13 +98,13 @@ module Twterm
93
98
 
94
99
  def post
95
100
  validate_text!
96
- Client.current.post(text, in_reply_to)
101
+ client.post(text, in_reply_to)
97
102
  rescue EmptyTextError
98
103
  # do nothing
99
104
  rescue InvalidCharactersError
100
- publish(Event::Notification.new(:error, 'Text contains invalid characters'))
105
+ publish(Event::Notification::Error.new('Text contains invalid characters'))
101
106
  rescue TextTooLongError
102
- publish(Event::Notification.new(:error, "Text is too long (#{text_length} / 140 characters)"))
107
+ publish(Event::Notification::Error.new("Text is too long (#{text_length} / 140 characters)"))
103
108
  ensure
104
109
  clear
105
110
  end
@@ -3,6 +3,7 @@ require 'singleton'
3
3
  require 'twterm/event/open_uri'
4
4
  require 'twterm/publisher'
5
5
  require 'twterm/subscriber'
6
+ require 'twterm/event/notification/warning'
6
7
 
7
8
  module Twterm
8
9
  class URIOpener
@@ -19,7 +20,7 @@ module Twterm
19
20
  def open(uri)
20
21
  Launchy.open(uri)
21
22
  rescue Launchy::CommandNotFoundError
22
- publish(Event::Notification.new(:error, 'Browser not found'))
23
+ publish(Event::Notification::Warning.new('Browser not found'))
23
24
  end
24
25
  end
25
26
  end
data/lib/twterm/user.rb CHANGED
@@ -2,70 +2,22 @@ module Twterm
2
2
  class User
3
3
  attr_reader :color, :description, :favorites_count, :followers_count,
4
4
  :friends_count, :id, :location, :name, :protected,
5
- :screen_name, :statuses_count, :touched_at, :verified, :website
5
+ :screen_name, :statuses_count, :verified, :website
6
6
  alias_method :protected?, :protected
7
7
  alias_method :verified?, :verified
8
8
 
9
- MAX_CACHED_TIME = 3600
10
9
  COLORS = [:red, :blue, :green, :cyan, :yellow, :magenta]
11
10
 
12
- @@instances = {}
13
-
14
- def blocked_by?(user_id)
15
- Friendship.blocking?(user_id, id)
16
- end
17
-
18
- def blocking?(user_id)
19
- Friendship.blocking?(id, user_id)
20
- end
21
-
22
- def followed_by?(user_id)
23
- Friendship.following?(user_id, id)
24
- end
25
-
26
- def following?(user_id)
27
- Friendship.following?(id, user_id)
28
- end
29
-
30
- def following_requested?(user_id)
31
- Friendship.following_requested?(id, user_id)
32
- end
33
-
34
- def following_requested_by?(user_id)
35
- Friendship.following_requested?(user_id, id)
36
- end
37
-
38
11
  def initialize(user)
39
12
  @id = user.id
40
13
  update!(user)
41
14
  @color = COLORS[@id % 6]
42
- touch!
43
-
44
- @@instances[@id] = self
45
- end
46
-
47
- def matches?(query)
48
- [name, screen_name, description, website].any? { |x| x.to_s.downcase.include? query.downcase }
49
- end
50
-
51
- def muted_by?(user_id)
52
- Friendship.muting?(user_id, id)
53
- end
54
-
55
- def muting?(user_id)
56
- Friendship.muting?(id, user_id)
57
- end
58
-
59
- def touch!
60
- @touched_at = Time.now
61
15
  end
62
16
 
63
17
  def update!(user)
64
- return self if recently_updated?
65
-
66
18
  @name = user.name
67
19
  @screen_name = user.screen_name
68
- @description = user.description || ''
20
+ @description = user.description.is_a?(Twitter::NullObject) ? '' : user.description
69
21
  @location = user.location.is_a?(Twitter::NullObject) ? '' : user.location
70
22
  @website = user.website
71
23
  @protected = user.protected?
@@ -75,67 +27,7 @@ module Twterm
75
27
  @followers_count = user.followers_count
76
28
  @verified = user.verified?
77
29
 
78
- client_id = Client.current.user_id
79
-
80
- if user.following?
81
- Friendship.follow(client_id, user.id)
82
- else
83
- Friendship.unfollow(client_id, user.id)
84
- end
85
-
86
- if user.follow_request_sent?
87
- Friendship.following_requested(client_id, user.id)
88
- else
89
- Friendship.following_not_requested(client_id, user.id)
90
- end
91
-
92
- @updated_at = Time.now
93
-
94
30
  self
95
31
  end
96
-
97
- def self.all
98
- @@instances.values
99
- end
100
-
101
- def self.find(id)
102
- @@instances[id]
103
- end
104
-
105
- def self.find_or_fetch(id)
106
- Promise.new do |resolve, reject|
107
- instance = find(id)
108
- (resolve.(instance) && next) if instance
109
-
110
- Client.current.show_user(id).then do |user|
111
- resolve.(user)
112
- end
113
- end
114
- end
115
-
116
- def self.cleanup
117
- referenced_users = Status.all.map(&:user)
118
- referenced_users.each(&:touch!)
119
-
120
- cond = -> (user) { user.touched_at > Time.now - MAX_CACHED_TIME }
121
- users = all.select(&cond)
122
- user_ids = users.map(&:id)
123
- @@instances = Hash[user_ids.zip(users)]
124
- end
125
-
126
- def self.ids
127
- @@instances.keys
128
- end
129
-
130
- def self.new(user)
131
- instance = find(user.id)
132
- instance.nil? ? super : instance.update!(user)
133
- end
134
-
135
- private
136
-
137
- def recently_updated?
138
- !@updated_at.nil? && @updated_at + 60 > Time.now
139
- end
140
32
  end
141
33
  end
@@ -1,3 +1,3 @@
1
1
  module Twterm
2
- VERSION = '1.3.0'
2
+ VERSION = '2.0.0.beta1'
3
3
  end
@@ -0,0 +1,30 @@
1
+ module Twterm
2
+ class View
3
+ def initialize(window, image)
4
+ @window, @image = window, image
5
+ end
6
+
7
+ def at(line, column)
8
+ @line, @column = line, column
9
+
10
+ self
11
+ end
12
+
13
+ def render
14
+ @image.at(line, column).render(@window)
15
+ @window.refresh
16
+
17
+ self
18
+ end
19
+
20
+ private
21
+
22
+ def column
23
+ @column || 0
24
+ end
25
+
26
+ def line
27
+ @line || 0
28
+ end
29
+ end
30
+ end
data/lib/twterm.rb CHANGED
@@ -19,20 +19,14 @@ require 'twterm/client'
19
19
  require 'twterm/color_manager'
20
20
  require 'twterm/completion_mamanger'
21
21
  require 'twterm/config'
22
+ require 'twterm/extensions/array'
22
23
  require 'twterm/extensions/curses/window'
23
24
  require 'twterm/extensions/enumerator/lazy'
24
- require 'twterm/extensions/integer'
25
25
  require 'twterm/extensions/string'
26
- require 'twterm/filter_query_window'
27
- require 'twterm/filterable_list'
26
+ require 'twterm/search_query_window'
28
27
  require 'twterm/friendship'
29
- require 'twterm/history/base'
30
- require 'twterm/history/savable'
31
- require 'twterm/history/hashtag'
32
- require 'twterm/history/screen_name'
33
28
  require 'twterm/list'
34
29
  require 'twterm/notifier'
35
- require 'twterm/promise'
36
30
  require 'twterm/screen'
37
31
  require 'twterm/scheduler'
38
32
  require 'twterm/status'
@@ -64,6 +58,6 @@ require 'twterm/version'
64
58
 
65
59
  module Twterm
66
60
  class Conf
67
- REQUIRE_VERSION = '1.3.0'
61
+ REQUIRE_VERSION = '1.1.1'
68
62
  end
69
63
  end
@@ -0,0 +1,107 @@
1
+ {
2
+ "coordinates": null,
3
+ "favorited": false,
4
+ "truncated": false,
5
+ "created_at": "Wed Jun 06 20:07:10 +0000 2012",
6
+ "id_str": "210462857140252672",
7
+ "entities": {
8
+ "urls": [
9
+ {
10
+ "expanded_url": "/terms/display-guidelines",
11
+ "url": "https://t.co/Ed4omjYs",
12
+ "indices": [
13
+ 76,
14
+ 97
15
+ ],
16
+ "display_url": "dev.twitter.com/terms/display-\u2026"
17
+ }
18
+ ],
19
+ "hashtags": [
20
+ {
21
+ "text": "Twitterbird",
22
+ "indices": [
23
+ 19,
24
+ 31
25
+ ]
26
+ }
27
+ ],
28
+ "user_mentions": [
29
+
30
+ ]
31
+ },
32
+ "in_reply_to_user_id_str": null,
33
+ "contributors": [
34
+ 14927800
35
+ ],
36
+ "text": "Along with our new #Twitterbird, we've also updated our Display Guidelines: https://t.co/Ed4omjYs ^JC",
37
+ "retweet_count": 66,
38
+ "in_reply_to_status_id_str": null,
39
+ "id": 210462857140252672,
40
+ "geo": null,
41
+ "retweeted": true,
42
+ "possibly_sensitive": false,
43
+ "in_reply_to_user_id": null,
44
+ "place": null,
45
+ "user": {
46
+ "profile_sidebar_fill_color": "DDEEF6",
47
+ "profile_sidebar_border_color": "C0DEED",
48
+ "profile_background_tile": false,
49
+ "name": "Twitter API",
50
+ "profile_image_url": "http://a0.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_normal.png",
51
+ "created_at": "Wed May 23 06:01:13 +0000 2007",
52
+ "location": "San Francisco, CA",
53
+ "follow_request_sent": false,
54
+ "profile_link_color": "0084B4",
55
+ "is_translator": false,
56
+ "id_str": "6253282",
57
+ "entities": {
58
+ "url": {
59
+ "urls": [
60
+ {
61
+ "expanded_url": null,
62
+ "url": "",
63
+ "indices": [
64
+ 0,
65
+ 22
66
+ ]
67
+ }
68
+ ]
69
+ },
70
+ "description": {
71
+ "urls": [
72
+
73
+ ]
74
+ }
75
+ },
76
+ "default_profile": true,
77
+ "contributors_enabled": true,
78
+ "favourites_count": 24,
79
+ "url": "",
80
+ "profile_image_url_https": "https://si0.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_normal.png",
81
+ "utc_offset": -28800,
82
+ "id": 6253282,
83
+ "profile_use_background_image": true,
84
+ "listed_count": 10774,
85
+ "profile_text_color": "333333",
86
+ "lang": "en",
87
+ "followers_count": 1212963,
88
+ "protected": false,
89
+ "notifications": null,
90
+ "profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme1/bg.png",
91
+ "profile_background_color": "C0DEED",
92
+ "verified": true,
93
+ "geo_enabled": true,
94
+ "time_zone": "Pacific Time (US & Canada)",
95
+ "description": "The Real Twitter API. I tweet about API changes, service issues and happily answer questions about Twitter and our API. Don't get an answer? It's on my website.",
96
+ "default_profile_image": false,
97
+ "profile_background_image_url": "http://a0.twimg.com/images/themes/theme1/bg.png",
98
+ "statuses_count": 3333,
99
+ "friends_count": 31,
100
+ "following": true,
101
+ "show_all_inline_media": false,
102
+ "screen_name": "twitterapi"
103
+ },
104
+ "in_reply_to_screen_name": null,
105
+ "source": "web",
106
+ "in_reply_to_status_id": null
107
+ }