twterm 2.5.0 → 2.9.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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +62 -0
  3. data/.gitignore +1 -0
  4. data/Makefile +18 -0
  5. data/README.md +30 -4
  6. data/bin/twterm +1 -3
  7. data/default.nix +21 -0
  8. data/gemset.nix +5130 -0
  9. data/lib/twterm/app.rb +0 -18
  10. data/lib/twterm/client.rb +1 -6
  11. data/lib/twterm/color_manager.rb +8 -9
  12. data/lib/twterm/image.rb +26 -0
  13. data/lib/twterm/image/underlined.rb +31 -0
  14. data/lib/twterm/image_builder/user_name_image_builder.rb +1 -0
  15. data/lib/twterm/key_mapper.rb +6 -8
  16. data/lib/twterm/key_mapper/abstract_key_mapper.rb +2 -2
  17. data/lib/twterm/list.rb +36 -1
  18. data/lib/twterm/message_window.rb +4 -5
  19. data/lib/twterm/persistable_configuration_proxy.rb +6 -6
  20. data/lib/twterm/preferences.rb +8 -1
  21. data/lib/twterm/rest_client.rb +0 -33
  22. data/lib/twterm/screen.rb +54 -14
  23. data/lib/twterm/search_query_window.rb +4 -5
  24. data/lib/twterm/status.rb +10 -0
  25. data/lib/twterm/tab/abstract_tab.rb +33 -8
  26. data/lib/twterm/tab/new/index.rb +0 -10
  27. data/lib/twterm/tab/new/list.rb +3 -3
  28. data/lib/twterm/tab/new/search.rb +2 -2
  29. data/lib/twterm/tab/new/user.rb +2 -2
  30. data/lib/twterm/tab/preferences/control.rb +77 -0
  31. data/lib/twterm/tab/preferences/index.rb +6 -0
  32. data/lib/twterm/tab/status_tab.rb +10 -0
  33. data/lib/twterm/tab/statuses/abstract_statuses_tab.rb +4 -4
  34. data/lib/twterm/tab/statuses/home.rb +0 -3
  35. data/lib/twterm/tab/statuses/mentions.rb +1 -0
  36. data/lib/twterm/tab/user_tab.rb +0 -9
  37. data/lib/twterm/tab_manager.rb +77 -5
  38. data/lib/twterm/tweetbox.rb +2 -3
  39. data/lib/twterm/user.rb +1 -0
  40. data/lib/twterm/version.rb +1 -1
  41. data/nix/Gemfile +3 -0
  42. data/nix/Gemfile.lock +70 -0
  43. data/nix/gemset.nix +283 -0
  44. data/shell.nix +40 -0
  45. data/twterm.gemspec +13 -13
  46. metadata +42 -44
  47. data/.travis.yml +0 -12
  48. data/lib/twterm/direct_message.rb +0 -60
  49. data/lib/twterm/direct_message_composer.rb +0 -80
  50. data/lib/twterm/direct_message_manager.rb +0 -51
  51. data/lib/twterm/event/direct_message/fetched.rb +0 -10
  52. data/lib/twterm/event/notification/direct_message.rb +0 -30
  53. data/lib/twterm/event/status/timeline.rb +0 -10
  54. data/lib/twterm/repository/direct_message_repository.rb +0 -14
  55. data/lib/twterm/streaming_client.rb +0 -146
  56. data/lib/twterm/tab/direct_message/conversation.rb +0 -104
  57. data/lib/twterm/tab/direct_message/conversation_list.rb +0 -100
@@ -1,4 +1,5 @@
1
1
  require 'twterm/image'
2
+ require 'twterm/tab/preferences/control'
2
3
  require 'twterm/tab/preferences/notification_backend'
3
4
  require 'twterm/tab/preferences/photo_viewer_backend'
4
5
  require 'twterm/preferences'
@@ -26,6 +27,8 @@ module Twterm
26
27
  cursor = Image.cursor(1, curr)
27
28
  desc =
28
29
  case item
30
+ when :control
31
+ 'Control preferences'
29
32
  when :notification_backend
30
33
  'Notification backend preferences'
31
34
  when :photo_viewer_backend
@@ -40,6 +43,7 @@ module Twterm
40
43
 
41
44
  def items
42
45
  [
46
+ :control,
43
47
  :notification_backend,
44
48
  :photo_viewer_backend,
45
49
  ]
@@ -67,6 +71,8 @@ module Twterm
67
71
  def open
68
72
  tab =
69
73
  case scroller.current_item
74
+ when :control
75
+ Tab::Preferences::Control.new(app, client)
70
76
  when :notification_backend
71
77
  Tab::Preferences::NotificationBackend.new(app, client)
72
78
  when :photo_viewer_backend
@@ -67,6 +67,7 @@ module Twterm
67
67
 
68
68
  def items
69
69
  [
70
+ :show_conversation,
70
71
  :reply,
71
72
  :favorite,
72
73
  :retweet,
@@ -135,6 +136,8 @@ module Twterm
135
136
  Image.string('Quote this tweet')
136
137
  when :destroy
137
138
  Image.string('Delete this tweet')
139
+ when :show_conversation
140
+ Image.string("Show conversation")
138
141
  when :show_user
139
142
  Image.string("Show user (@#{user.screen_name})")
140
143
  when :open_in_browser
@@ -172,6 +175,8 @@ module Twterm
172
175
  quote!
173
176
  when :destroy
174
177
  destroy!
178
+ when :show_conversation
179
+ show_conversation!
175
180
  when :show_user
176
181
  show_user!
177
182
  when :open_in_browser
@@ -209,6 +214,11 @@ module Twterm
209
214
  .then { render }
210
215
  end
211
216
 
217
+ def show_conversation!
218
+ tab = Tab::Statuses::Conversation.new(app, client, status_id)
219
+ app.tab_manager.add_and_show(tab)
220
+ end
221
+
212
222
  def show_user!
213
223
  user_id = status.user_id
214
224
  user_tab = Tab::UserTab.new(app, client, user_id)
@@ -27,7 +27,7 @@ module Twterm
27
27
  return if @status_ids.include?(status.id)
28
28
 
29
29
  @status_ids.push(status.id)
30
- status.split(window.maxx - 4)
30
+ status.split(window.maxx - 2)
31
31
  scroller.item_appended!
32
32
  render
33
33
  end
@@ -46,7 +46,7 @@ module Twterm
46
46
 
47
47
  def drawable_item_count
48
48
  statuses.drop(scroller.offset).lazy
49
- .map { |s| s.split(window.maxx - 4).count + 2 }
49
+ .map { |s| s.split(window.maxx - 2).count + 2 }
50
50
  .scan(0, :+)
51
51
  .each_cons(2)
52
52
  .select { |_, l| l < window.maxy }
@@ -113,7 +113,7 @@ module Twterm
113
113
  return if @status_ids.include?(status.id)
114
114
 
115
115
  @status_ids.unshift(status.id)
116
- status.split(window.maxx - 4)
116
+ status.split(window.maxx - 2)
117
117
  scroller.item_prepended!
118
118
  render
119
119
  end
@@ -235,7 +235,7 @@ module Twterm
235
235
  ].compact.intersperse(Image.whitespace).reduce(Image.empty, :-)
236
236
 
237
237
  body = original
238
- .split(window.maxx - 4)
238
+ .split(window.maxx - 2)
239
239
  .map(&Image.method(:string))
240
240
  .reduce(Image.empty, :|)
241
241
 
@@ -1,5 +1,4 @@
1
1
  require 'twterm/subscriber'
2
- require 'twterm/event/status/timeline'
3
2
  require 'twterm/tab/statuses/abstract_statuses_tab'
4
3
  require 'twterm/utils'
5
4
 
@@ -21,8 +20,6 @@ module Twterm
21
20
  def initialize(app, client)
22
21
  super(app, client)
23
22
 
24
- subscribe(Event::Status::Timeline) { |e| prepend(e.status) }
25
-
26
23
  reload.then do
27
24
  initially_loaded!
28
25
  scroller.move_to_top
@@ -1,4 +1,5 @@
1
1
  require 'twterm/tab/statuses/abstract_statuses_tab'
2
+ require 'twterm/event/status/mention'
2
3
 
3
4
  module Twterm
4
5
  module Tab
@@ -53,7 +53,6 @@ module Twterm
53
53
  :profile_image,
54
54
  (:profile_background_image unless user.profile_background_image.nil?),
55
55
  :manage_lists,
56
- (:compose_direct_message unless myself?),
57
56
  (:open_website unless user.website.nil?),
58
57
  (:toggle_follow unless myself?),
59
58
  (:toggle_mute unless myself?),
@@ -96,10 +95,6 @@ module Twterm
96
95
  app.friendship_repository.blocking?(client.user_id, user_id)
97
96
  end
98
97
 
99
- def compose_direct_message
100
- app.direct_message_composer.compose(user)
101
- end
102
-
103
98
  def follow
104
99
  client.follow(user_id).then do |users|
105
100
  render
@@ -176,8 +171,6 @@ module Twterm
176
171
 
177
172
  def perform_selected_action
178
173
  case scroller.current_item
179
- when :compose_direct_message
180
- compose_direct_message
181
174
  when :manage_lists
182
175
  open_list_management_tab
183
176
  when :open_in_browser
@@ -294,8 +287,6 @@ module Twterm
294
287
  curr = scroller.current_index?(i)
295
288
  Image.cursor(1, curr) - Image.whitespace -
296
289
  case item
297
- when :compose_direct_message
298
- Image.string('Compose direct message')
299
290
  when :toggle_block
300
291
  if blocking?
301
292
  Image.string('Unblock this user')
@@ -6,7 +6,6 @@ require 'twterm/view'
6
6
 
7
7
  module Twterm
8
8
  class TabManager
9
- include Curses
10
9
  include Publisher
11
10
  include Subscriber
12
11
  include Utils
@@ -69,6 +68,20 @@ module Twterm
69
68
  end
70
69
  end
71
70
 
71
+ # Returns if the given coordinate is enclosed by the window
72
+ #
73
+ # @param x [Integer]
74
+ # @param y [Integer]
75
+ # @return [Boolean]
76
+ def enclose?(x, y)
77
+ left = @window.begx
78
+ top = @window.begy
79
+ right = left + @window.maxx
80
+ bottom = top + @window.maxy
81
+
82
+ left <= x && x < right && top <= y && y < bottom
83
+ end
84
+
72
85
  def initialize(app, client)
73
86
  @app, @client = app, client
74
87
 
@@ -76,11 +89,50 @@ module Twterm
76
89
  @index = 0
77
90
  @history = []
78
91
 
79
- @window = stdscr.subwin(3, stdscr.maxx, 0, 0)
92
+ @window = Curses.stdscr.subwin(1, Curses.stdscr.maxx, 0, 0)
80
93
 
81
94
  subscribe(Event::Screen::Resize, :resize)
82
95
  end
83
96
 
97
+ # Open the clicked tab
98
+ #
99
+ # @param x [Integer]
100
+ # @param _y [Integer]
101
+ #
102
+ # @return [nil]
103
+ def handle_left_click(x, _y)
104
+ n = find_tab_index_on_x(x)
105
+ return if n.nil?
106
+
107
+ show_nth_tab(n)
108
+
109
+ nil
110
+ end
111
+
112
+ # Open next tab
113
+ #
114
+ # @param _x [Integer]
115
+ # @param _y [Integer]
116
+ #
117
+ # @return [nil]
118
+ def handle_scroll_down(_x, _y)
119
+ show_next
120
+
121
+ nil
122
+ end
123
+
124
+ # Open previous tab
125
+ #
126
+ # @param _x [Integer]
127
+ # @param _y [Integer]
128
+ #
129
+ # @return [nil]
130
+ def handle_scroll_up(_x, _y)
131
+ show_previous
132
+
133
+ nil
134
+ end
135
+
84
136
  def open_my_profile
85
137
  current_user_id = client.user_id
86
138
  tab = Tab::UserTab.new(app, client, current_user_id)
@@ -120,10 +172,10 @@ module Twterm
120
172
 
121
173
  image = @tabs
122
174
  .map { |t| [t, Image.string(t.title)] }
123
- .map { |t, r| t.equal?(current_tab) ? !r : r }
175
+ .map { |t, r| t.equal?(current_tab) ? !r._ : r }
124
176
  .reduce(pipe) { |acc, x| acc - wss - x - wss - pipe }
125
177
 
126
- View.new(@window, image).at(1, 1)
178
+ View.new(@window, image)
127
179
  end
128
180
 
129
181
  def respond_to_key(key)
@@ -195,8 +247,28 @@ module Twterm
195
247
 
196
248
  attr_reader :app, :client
197
249
 
250
+ # @param x [Integer]
251
+ #
252
+ # @return [Integer, nil]
253
+ def find_tab_index_on_x(x)
254
+ pos = 0
255
+
256
+ @tabs.each.with_index do |tab, index|
257
+ title = tab.title
258
+ len = title.length
259
+ left = pos + 1
260
+ right = left + len + 4 # each tab has 2 whitespaces on the both side
261
+
262
+ return index if left <= x && x < right
263
+
264
+ pos = right
265
+ end
266
+
267
+ nil
268
+ end
269
+
198
270
  def resize(_event)
199
- @window.resize(3, stdscr.maxx)
271
+ @window.resize(1, Curses.stdscr.maxx)
200
272
  @window.move(0, 0)
201
273
  end
202
274
  end
@@ -16,7 +16,6 @@ module Twterm
16
16
  end
17
17
 
18
18
  include Readline
19
- include Curses
20
19
  include Publisher
21
20
 
22
21
  def initialize(app, client)
@@ -104,7 +103,7 @@ module Twterm
104
103
  end
105
104
 
106
105
  def ask_and_post(leading_text, prompt, postprocessor, options = {})
107
- close_screen
106
+ Curses.close_screen
108
107
  puts "\e[H\e[2J#{leading_text}\n\n"
109
108
  ask(prompt, postprocessor) { |text| client.post(postprocessor.call(text), options) }
110
109
  end
@@ -120,7 +119,7 @@ module Twterm
120
119
  end
121
120
 
122
121
  def reset
123
- reset_prog_mode
122
+ Curses.reset_prog_mode
124
123
  sleep 0.1
125
124
  publish(Event::Screen::Refresh.new)
126
125
  end
data/lib/twterm/user.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  module Twterm
2
+ # A Twitter user
2
3
  class User
3
4
  attr_reader :description, :favorites_count, :followers_count,
4
5
  :friends_count, :id, :location, :name, :protected, :profile_image,
@@ -1,3 +1,3 @@
1
1
  module Twterm
2
- VERSION = '2.5.0'
2
+ VERSION = '2.9.0'
3
3
  end
data/nix/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'twterm'
data/nix/Gemfile.lock ADDED
@@ -0,0 +1,70 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.7.0)
5
+ public_suffix (>= 2.0.2, < 5.0)
6
+ buftok (0.2.0)
7
+ citrus (3.0.2)
8
+ concurrent-ruby (1.0.5)
9
+ curses (1.3.2)
10
+ domain_name (0.5.20190701)
11
+ unf (>= 0.0.5, < 1.0.0)
12
+ equalizer (0.0.11)
13
+ http (3.3.0)
14
+ addressable (~> 2.3)
15
+ http-cookie (~> 1.0)
16
+ http-form_data (~> 2.0)
17
+ http_parser.rb (~> 0.6.0)
18
+ http-cookie (1.0.3)
19
+ domain_name (~> 0.5)
20
+ http-form_data (2.3.0)
21
+ http_parser.rb (0.6.0)
22
+ idn-ruby (0.1.0)
23
+ launchy (2.4.3)
24
+ addressable (~> 2.3)
25
+ memoizable (0.4.2)
26
+ thread_safe (~> 0.3, >= 0.3.1)
27
+ multipart-post (2.1.1)
28
+ naught (1.1.0)
29
+ oauth (0.5.4)
30
+ public_suffix (4.0.5)
31
+ simple_oauth (0.3.1)
32
+ terminal-notifier (2.0.0)
33
+ thread_safe (0.3.6)
34
+ toml-rb (0.3.15)
35
+ citrus (~> 3.0, > 3.0)
36
+ twitter (6.2.0)
37
+ addressable (~> 2.3)
38
+ buftok (~> 0.2.0)
39
+ equalizer (~> 0.0.11)
40
+ http (~> 3.0)
41
+ http-form_data (~> 2.0)
42
+ http_parser.rb (~> 0.6.0)
43
+ memoizable (~> 0.4.0)
44
+ multipart-post (~> 2.0)
45
+ naught (~> 1.0)
46
+ simple_oauth (~> 0.3.0)
47
+ twitter-text (2.1.0)
48
+ idn-ruby
49
+ unf (~> 0.1.0)
50
+ twterm (2.8.0)
51
+ concurrent-ruby (~> 1.0.5)
52
+ curses (~> 1.3.2)
53
+ launchy (~> 2.4.3)
54
+ oauth (~> 0.5.1)
55
+ terminal-notifier (~> 2.0.0)
56
+ toml-rb (~> 0.3.14)
57
+ twitter (~> 6.2.0)
58
+ twitter-text (~> 2.1.0)
59
+ unf (0.1.4)
60
+ unf_ext
61
+ unf_ext (0.0.7.7)
62
+
63
+ PLATFORMS
64
+ ruby
65
+
66
+ DEPENDENCIES
67
+ twterm
68
+
69
+ BUNDLED WITH
70
+ 2.1.4
data/nix/gemset.nix ADDED
@@ -0,0 +1,283 @@
1
+ {
2
+ addressable = {
3
+ dependencies = ["public_suffix"];
4
+ groups = ["default"];
5
+ platforms = [];
6
+ source = {
7
+ remotes = ["https://rubygems.org"];
8
+ sha256 = "1fvchp2rhp2rmigx7qglf69xvjqvzq7x0g49naliw29r2bz656sy";
9
+ type = "gem";
10
+ };
11
+ version = "2.7.0";
12
+ };
13
+ buftok = {
14
+ groups = ["default"];
15
+ platforms = [];
16
+ source = {
17
+ remotes = ["https://rubygems.org"];
18
+ sha256 = "1rzsy1vy50v55x9z0nivf23y0r9jkmq6i130xa75pq9i8qrn1mxs";
19
+ type = "gem";
20
+ };
21
+ version = "0.2.0";
22
+ };
23
+ citrus = {
24
+ groups = ["default"];
25
+ platforms = [];
26
+ source = {
27
+ remotes = ["https://rubygems.org"];
28
+ sha256 = "0l7nhk3gkm1hdchkzzhg2f70m47pc0afxfpl6mkiibc9qcpl3hjf";
29
+ type = "gem";
30
+ };
31
+ version = "3.0.2";
32
+ };
33
+ concurrent-ruby = {
34
+ groups = ["default"];
35
+ platforms = [];
36
+ source = {
37
+ remotes = ["https://rubygems.org"];
38
+ sha256 = "183lszf5gx84kcpb779v6a2y0mx9sssy8dgppng1z9a505nj1qcf";
39
+ type = "gem";
40
+ };
41
+ version = "1.0.5";
42
+ };
43
+ curses = {
44
+ groups = ["default"];
45
+ platforms = [];
46
+ source = {
47
+ remotes = ["https://rubygems.org"];
48
+ sha256 = "0hic9kq09dhh8jqjx3k1991rnqhlj3glz82w0g7ndcri52m1hgqg";
49
+ type = "gem";
50
+ };
51
+ version = "1.3.2";
52
+ };
53
+ domain_name = {
54
+ dependencies = ["unf"];
55
+ groups = ["default"];
56
+ platforms = [];
57
+ source = {
58
+ remotes = ["https://rubygems.org"];
59
+ sha256 = "0lcqjsmixjp52bnlgzh4lg9ppsk52x9hpwdjd53k8jnbah2602h0";
60
+ type = "gem";
61
+ };
62
+ version = "0.5.20190701";
63
+ };
64
+ equalizer = {
65
+ groups = ["default"];
66
+ platforms = [];
67
+ source = {
68
+ remotes = ["https://rubygems.org"];
69
+ sha256 = "1kjmx3fygx8njxfrwcmn7clfhjhb6bvv3scy2lyyi0wqyi3brra4";
70
+ type = "gem";
71
+ };
72
+ version = "0.0.11";
73
+ };
74
+ http = {
75
+ dependencies = ["addressable" "http-cookie" "http-form_data" "http_parser.rb"];
76
+ groups = ["default"];
77
+ platforms = [];
78
+ source = {
79
+ remotes = ["https://rubygems.org"];
80
+ sha256 = "1jlm5prw437wqpfxcigh88lfap3m7g8mnmj5as7qw6dzqnvrxwmc";
81
+ type = "gem";
82
+ };
83
+ version = "3.3.0";
84
+ };
85
+ http-cookie = {
86
+ dependencies = ["domain_name"];
87
+ groups = ["default"];
88
+ platforms = [];
89
+ source = {
90
+ remotes = ["https://rubygems.org"];
91
+ sha256 = "004cgs4xg5n6byjs7qld0xhsjq3n6ydfh897myr2mibvh6fjc49g";
92
+ type = "gem";
93
+ };
94
+ version = "1.0.3";
95
+ };
96
+ http-form_data = {
97
+ groups = ["default"];
98
+ platforms = [];
99
+ source = {
100
+ remotes = ["https://rubygems.org"];
101
+ sha256 = "1wx591jdhy84901pklh1n9sgh74gnvq1qyqxwchni1yrc49ynknc";
102
+ type = "gem";
103
+ };
104
+ version = "2.3.0";
105
+ };
106
+ "http_parser.rb" = {
107
+ groups = ["default"];
108
+ platforms = [];
109
+ source = {
110
+ remotes = ["https://rubygems.org"];
111
+ sha256 = "15nidriy0v5yqfjsgsra51wmknxci2n2grliz78sf9pga3n0l7gi";
112
+ type = "gem";
113
+ };
114
+ version = "0.6.0";
115
+ };
116
+ idn-ruby = {
117
+ groups = ["default"];
118
+ platforms = [];
119
+ source = {
120
+ remotes = ["https://rubygems.org"];
121
+ sha256 = "07vblcyk3g72sbq12xz7xj28snpxnh3sbcnxy8bglqbfqqhvmawr";
122
+ type = "gem";
123
+ };
124
+ version = "0.1.0";
125
+ };
126
+ launchy = {
127
+ dependencies = ["addressable"];
128
+ groups = ["default"];
129
+ platforms = [];
130
+ source = {
131
+ remotes = ["https://rubygems.org"];
132
+ sha256 = "190lfbiy1vwxhbgn4nl4dcbzxvm049jwc158r2x7kq3g5khjrxa2";
133
+ type = "gem";
134
+ };
135
+ version = "2.4.3";
136
+ };
137
+ memoizable = {
138
+ dependencies = ["thread_safe"];
139
+ groups = ["default"];
140
+ platforms = [];
141
+ source = {
142
+ remotes = ["https://rubygems.org"];
143
+ sha256 = "0v42bvghsvfpzybfazl14qhkrjvx0xlmxz0wwqc960ga1wld5x5c";
144
+ type = "gem";
145
+ };
146
+ version = "0.4.2";
147
+ };
148
+ multipart-post = {
149
+ groups = ["default"];
150
+ platforms = [];
151
+ source = {
152
+ remotes = ["https://rubygems.org"];
153
+ sha256 = "1zgw9zlwh2a6i1yvhhc4a84ry1hv824d6g2iw2chs3k5aylpmpfj";
154
+ type = "gem";
155
+ };
156
+ version = "2.1.1";
157
+ };
158
+ naught = {
159
+ groups = ["default"];
160
+ platforms = [];
161
+ source = {
162
+ remotes = ["https://rubygems.org"];
163
+ sha256 = "1wwjx35zgbc0nplp8a866iafk4zsrbhwwz4pav5gydr2wm26nksg";
164
+ type = "gem";
165
+ };
166
+ version = "1.1.0";
167
+ };
168
+ oauth = {
169
+ groups = ["default"];
170
+ platforms = [];
171
+ source = {
172
+ remotes = ["https://rubygems.org"];
173
+ sha256 = "1zszdg8q1b135z7l7crjj234k4j0m347hywp5kj6zsq7q78pw09y";
174
+ type = "gem";
175
+ };
176
+ version = "0.5.4";
177
+ };
178
+ public_suffix = {
179
+ groups = ["default"];
180
+ platforms = [];
181
+ source = {
182
+ remotes = ["https://rubygems.org"];
183
+ sha256 = "0vywld400fzi17cszwrchrzcqys4qm6sshbv73wy5mwcixmrgg7g";
184
+ type = "gem";
185
+ };
186
+ version = "4.0.5";
187
+ };
188
+ simple_oauth = {
189
+ groups = ["default"];
190
+ platforms = [];
191
+ source = {
192
+ remotes = ["https://rubygems.org"];
193
+ sha256 = "0dw9ii6m7wckml100xhjc6vxpjcry174lbi9jz5v7ibjr3i94y8l";
194
+ type = "gem";
195
+ };
196
+ version = "0.3.1";
197
+ };
198
+ terminal-notifier = {
199
+ groups = ["default"];
200
+ platforms = [];
201
+ source = {
202
+ remotes = ["https://rubygems.org"];
203
+ sha256 = "1slc0y8pjpw30hy21v8ypafi8r7z9jlj4bjbgz03b65b28i2n3bs";
204
+ type = "gem";
205
+ };
206
+ version = "2.0.0";
207
+ };
208
+ thread_safe = {
209
+ groups = ["default"];
210
+ platforms = [];
211
+ source = {
212
+ remotes = ["https://rubygems.org"];
213
+ sha256 = "0nmhcgq6cgz44srylra07bmaw99f5271l0dpsvl5f75m44l0gmwy";
214
+ type = "gem";
215
+ };
216
+ version = "0.3.6";
217
+ };
218
+ toml-rb = {
219
+ dependencies = ["citrus"];
220
+ groups = ["default"];
221
+ platforms = [];
222
+ source = {
223
+ remotes = ["https://rubygems.org"];
224
+ sha256 = "03sr3k193i1r5bh9g4zc7iq9jklapmwj0rndcvhr9q7v5xm7x4rf";
225
+ type = "gem";
226
+ };
227
+ version = "0.3.15";
228
+ };
229
+ twitter = {
230
+ dependencies = ["addressable" "buftok" "equalizer" "http" "http-form_data" "http_parser.rb" "memoizable" "multipart-post" "naught" "simple_oauth"];
231
+ groups = ["default"];
232
+ platforms = [];
233
+ source = {
234
+ remotes = ["https://rubygems.org"];
235
+ sha256 = "0fjyz3viabz3xs5d9aad18zgdbhfwm51jsnzigc8kxk77p1x58n5";
236
+ type = "gem";
237
+ };
238
+ version = "6.2.0";
239
+ };
240
+ twitter-text = {
241
+ dependencies = ["idn-ruby" "unf"];
242
+ groups = ["default"];
243
+ platforms = [];
244
+ source = {
245
+ remotes = ["https://rubygems.org"];
246
+ sha256 = "1igv713wn6wqhq4nlr81r93v7wmgjqny24jwp3ai5i4ipk2f2k6a";
247
+ type = "gem";
248
+ };
249
+ version = "2.1.0";
250
+ };
251
+ twterm = {
252
+ dependencies = ["concurrent-ruby" "curses" "launchy" "oauth" "terminal-notifier" "toml-rb" "twitter" "twitter-text"];
253
+ groups = ["default"];
254
+ platforms = [];
255
+ source = {
256
+ remotes = ["https://rubygems.org"];
257
+ sha256 = "075rq11axsz41hcrmm6ixjyy0kz3axf0mhkvq3cgryqib2isjbk9";
258
+ type = "gem";
259
+ };
260
+ version = "2.8.0";
261
+ };
262
+ unf = {
263
+ dependencies = ["unf_ext"];
264
+ groups = ["default"];
265
+ platforms = [];
266
+ source = {
267
+ remotes = ["https://rubygems.org"];
268
+ sha256 = "0bh2cf73i2ffh4fcpdn9ir4mhq8zi50ik0zqa1braahzadx536a9";
269
+ type = "gem";
270
+ };
271
+ version = "0.1.4";
272
+ };
273
+ unf_ext = {
274
+ groups = ["default"];
275
+ platforms = [];
276
+ source = {
277
+ remotes = ["https://rubygems.org"];
278
+ sha256 = "0wc47r23h063l8ysws8sy24gzh74mks81cak3lkzlrw4qkqb3sg4";
279
+ type = "gem";
280
+ };
281
+ version = "0.0.7.7";
282
+ };
283
+ }