pry-send_tweet.rb 0.8.0 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ce2553fea351dc038a90454aab0c8fea7ba8a68116f20732d1f4ac06287e241
4
- data.tar.gz: 8d7a7a9a77a2ed1c392d508ac64cbfa7daaafa7975c0667fa72b8257fdd595f3
3
+ metadata.gz: 00774a2bc4c154a5756a86bc02ebff9fab766e3eaf233768a30ed1d16fd38461
4
+ data.tar.gz: 6291210c7ebffd391b09fba722215e9be5458c35a484ec25d73020d33f02167d
5
5
  SHA512:
6
- metadata.gz: a8ce626ae62a433641ae6939e61ae8e8ff597d88e881c0e722786ca3d180c44c7bf4712e2e8f265f62952189b6f13afbb68d7aba2c62c9ba00a358d31746c4ec
7
- data.tar.gz: 000dca566ec219b81d8ce3470e38b3d6f3a46688032c8831bb1f409dac235d339884b4e9686258cadc5046206d7de661b71f5eddadae9223df9da26eead6270c
6
+ metadata.gz: d19ee6a9687148a87ad5d0d4d2933e80dd30b5df9fd4e33d0be6e0acf3df0b46fce0a3ff67b4d75a65c9afb271a1cd24011d9b599060ee7d295bcf5826027da5
7
+ data.tar.gz: 410db8e42963c8369abc505255fdbf5f294f81f5d16c1f04a60650cbe0ffd29bac29822f8c70042e6769952cce3f5e6e65fb8c5b1d2b0169566526d3775648f2
@@ -1,6 +1,31 @@
1
1
  # CHANGELOG
2
2
 
3
- ## v0.8.0
3
+ ## v0.9.0
4
+
5
+ * Render `Twitter::Tweet` and `Twitter::User` objects using `TTY::Box` - with the
6
+ knowledge that it has bugs and limitations that will need to be fixed in the
7
+ future.
8
+
9
+ * Improve `send-tweet --reply-to` by writing the tweet owners screen name
10
+ and all other user mentions in their tweet to the temp file created
11
+ to compose a reply.
12
+
13
+ * Add `on-twitter --show-following` to show the newest tweeters you have started d
14
+ to follow.
15
+
16
+ * Add `on-twitter --show-followers` to show the newest tweeters to have followed
17
+ you.
18
+
19
+ * Add the option to configure pry-send_tweet through a YAML file.
20
+
21
+ * Add `dockerize.sh` to gem package.
22
+
23
+ * Add README documentation for following related actions.
24
+
25
+ * Add README documentation for all `on-twitter` actions related to a users
26
+ profile.
27
+
28
+ ## v0.8.0ddd
4
29
 
5
30
  * Add sticky local variable `_twitter_` to the active Binding.
6
31
 
data/Dockerfile CHANGED
@@ -1,12 +1,14 @@
1
1
  FROM ruby:2.6.0-stretch
2
2
 
3
- # Create working directory
4
- RUN mkdir -p /app/
5
- WORKDIR /app/
3
+ # Add regular user
4
+ RUN groupadd -g 999 appuser
5
+ RUN useradd -d /home/appuser -r -u 999 -g appuser appuser
6
+ RUN mkdir -p /home/appuser
7
+ WORKDIR /home/appuser/
6
8
 
7
- # Bundler
8
- ADD Gemfile pry-send_tweet.gemspec /app/
9
- ADD lib /app/lib
9
+ # Bundle
10
+ ADD Gemfile pry-send_tweet.gemspec /home/appuser/
11
+ ADD lib /home/appuser/lib/
10
12
  RUN gem install bundler
11
13
  # FIXME: During 'bundle install', i got: Could not find gem 'buftok (~> 0.2.0)'
12
14
  # Installing twitter as a gem first fixes that.
@@ -23,12 +25,17 @@ RUN locale-gen
23
25
  RUN echo 'Europe/Zurich' > /etc/timezone
24
26
  RUN rm /etc/localtime
25
27
  RUN dpkg-reconfigure -f noninteractive tzdata
26
-
27
28
  ENV LANG en_US.UTF-8
28
29
  ENV LANGUAGE en_US:en
29
30
  ENV LC_ALL en_US.UTF-8
31
+
32
+ # Configure editor
30
33
  ENV EDITOR emacs
31
34
 
32
- # Define entry point
33
- ADD . /app
34
- ENTRYPOINT /bin/bash -c 'bundle exec pry'
35
+ # Add files to container
36
+ ADD . /home/appuser/
37
+
38
+ # Finally, drop root permissions to regular user
39
+ RUN chown appuser /home/appuser
40
+ RUN chown -R appuser /home/appuser/*
41
+ USER appuser
data/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
  * [Reading Tweets](#reading-tweets)
9
9
  * [Deleting Tweets](#deleting-tweets)
10
10
  * [Liking Tweets](#liking-tweets)
11
+ * [Following / unfollowing](#following-unfollowing)
11
12
  * [Searching Twitter](#searching-twitter)
12
13
  * [Retweets](#retweets)
13
14
  * [Profile Actions](#profile-actions)
@@ -25,15 +26,20 @@ A Twitter client for the Pry REPL.
25
26
 
26
27
  ## <a id='api-access'>API Access</a>
27
28
 
28
- Using the Twitter API requires a developer account.
29
+ Using the Twitter API requires a developer account.
29
30
  Follow the instructions at [https://developer.twitter.com](https://developer.twitter.com)
30
31
  if you haven't already setup access to the Twitter API.
31
32
 
32
33
  ## <a id='configuration'>Configuration (required)</a>
33
34
 
34
- The placeholder keys and tokens in the below example can be replaced
35
+ The placeholder keys and tokens in the below example can be replaced
35
36
  by those from your developer account.
36
37
 
38
+ pry-send_tweet.rb can be configured from a `.pryrc` file using Ruby, or
39
+ through a YAML file located at `$HOME/.pry-send_tweet.yml`
40
+
41
+ __1. Ruby__
42
+
37
43
  ```ruby
38
44
  # .pryrc
39
45
  Pry.configure do |config|
@@ -53,6 +59,22 @@ Pry.configure do |config|
53
59
  end
54
60
  ```
55
61
 
62
+ __2. YAML__
63
+
64
+ `$HOME/.pry-send_tweet.yml`:
65
+
66
+ ```yaml
67
+ ---
68
+ # Required
69
+ consumer_key: '<consumer key>'
70
+ consumer_secret: '<consumer secret>'
71
+ access_token: '<access token>'
72
+ access_token_secret: '<access token secret>'
73
+ # Optional
74
+ user_agent: 'Your User-Agent string'
75
+ line_width: 120
76
+ ```
77
+
56
78
  ## <a id='usage'>Usage</a>
57
79
 
58
80
  There are four commands added to Pry by this plugin, those commands are:
@@ -151,21 +173,35 @@ feature.
151
173
 
152
174
  * Delete one or more tweets with a comma separated list:
153
175
 
154
- [1] pry(main)> on-twitter --delete-tweet https://twitter.com/username/status/1
176
+ [1] pry(main)> on-twitter --delete-tweet https://twitter.com/username/status/1,https://twitter.com/username/status/2
155
177
 
156
178
  * Delete one or more retweets with a comma separated list:
157
179
 
158
- [1] pry(main)> on-twitter --delete-retweet https://twitter.com/username/status/1
180
+ [1] pry(main)> on-twitter --delete-retweet https://twitter.com/username/status/1,https://twitter.com/username/status/2
159
181
 
160
182
  ### <a id='liking-tweets'>Liking tweets</a>
161
183
 
162
184
  * Like one or more tweets with a comma separated list:
163
185
 
164
- [1] pry(main)> on-twitter --like https://twitter.com/user/status/1
186
+ [1] pry(main)> on-twitter --like https://twitter.com/user/status/1,https://twitter.com/user/status/2
165
187
 
166
188
  * Unlike one or more tweets with a comma separated list:
167
189
 
168
- [1] pry(main)> on-twitter --unlike https://twitter.com/user/status/1
190
+ [1] pry(main)> on-twitter --unlike https://twitter.com/user/status/1,https://twitter.com/user/status/2
191
+
192
+ ### <a id='following-unfollowing'> Following / unfollowing </a>
193
+
194
+ * Follow one or more tweeters with a comma separated list:
195
+
196
+ [1] pry(main)> on-twitter --follow user1,user2,user3
197
+
198
+ * Unfollow one or more tweeters with a comma separated list:
199
+
200
+ [1] pry(main)> on-twitter --unfollow user1,user2,user3,user4
201
+
202
+ * Show the tweeters who are following you:
203
+
204
+ [1] pry(main)> on-twitter --show-followers
169
205
 
170
206
  ### <a id='searching-twitter'>Searching Twitter</a>
171
207
 
@@ -179,23 +215,32 @@ The `twitter-search` command can be used to search Twitter.
179
215
 
180
216
  * Retweet one or more tweets with a comma separated list:
181
217
 
182
- [1] pry(main)> on-twitter --retweet https://twitter.com/user/status/1
218
+ [1] pry(main)> on-twitter --retweet https://twitter.com/user/status/1,https://twitter.com/user/status/2
183
219
 
184
220
  ### <a id='profile-actions'>Profile actions</a>
185
221
 
186
- * Update your profiles image:
222
+ * Update profile bio:
223
+
224
+ # Your editor opens (`_pry_.editor`), write your bio then hit save & close.
225
+ # Your bio will be updated after closing your editor.
226
+ [1] pry(main)> on-twitter --set-profile-bio
227
+
228
+ * Update the name associated with your profile:
229
+
230
+ [1] pry(main)> on-twitter --set-profile-name=Robert
231
+
232
+ * Update the URL associated with your profile:
233
+
234
+ [1] pry(main)> on-twitter --set-profile-url=https://github.com/you
235
+
236
+ * Update profile image:
187
237
 
188
238
  [1] pry(main)> on-twitter --set-profile-image /path/to/image.jpg
189
239
 
190
- * Update your profiles banner image:
240
+ * Update profile banner image:
191
241
 
192
242
  [1] pry(main)> on-twitter --set-profile-banner-image /path/to/image.jpg
193
243
 
194
- * Update your profiles bio:
195
-
196
- # Your editor opens (`_pry_.editor`), write your bio then hit save & close.
197
- # Your bio will be updated after closing your editor.
198
- [1] pry(main)> on-twitter --set-profile-bio
199
244
 
200
245
  ### <a id='twitter-suggestions'>Twitter Suggestions</a>
201
246
 
@@ -217,7 +262,7 @@ The `twitter-search` command can be used to search Twitter.
217
262
 
218
263
  * Unmute one or more users with a comma separated list:
219
264
 
220
- [1] pry(main)> on-twitter --unmute-user=user1,user2,user3
265
+ [1] pry(main)> on-twitter --unmute-user=user1,user2,user3,user4
221
266
 
222
267
 
223
268
  ### <a id='special-variable-_twitter_'>Sticky local variable: `_twitter_`</a>
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+ docker build -t send_tweets .
3
+ docker run -v $PWD/tweets/:/app/tweets -i -t send_tweets bundle exec pry
@@ -19,22 +19,39 @@ class Pry
19
19
  require 'pry' if not defined?(Pry::ClassCommand)
20
20
  require 'twitter'
21
21
  require 'cgi'
22
- require 'shellwords'
23
22
  require 'timeout'
23
+ require 'yaml'
24
24
  require 'time-lord'
25
+ require 'tty/box'
25
26
  require_relative 'pry/send_tweet/renderers/tweet_renderer'
27
+ require_relative 'pry/send_tweet/renderers/user_renderer'
28
+ require_relative 'pry/send_tweet/commands/paging/paging_support'
26
29
  require_relative 'pry/send_tweet/commands/base_command'
27
30
  require_relative 'pry/send_tweet/commands/send_tweet'
28
31
  require_relative 'pry/send_tweet/commands/read_tweets'
29
32
  require_relative 'pry/send_tweet/commands/twitter_search'
30
33
  require_relative 'pry/send_tweet/commands/twitter_action'
34
+
35
+ # @api private
36
+ def self.merge_yaml_file!(config, path)
37
+ if File.readable?(path)
38
+ warn "[warning] Reading pry-send_tweet configuration from '#{path}'."
39
+ t = Pry::Config.from_hash config.merge!(YAML.load_file(path))
40
+ config.twitter = t
41
+ end
42
+ rescue => e
43
+ warn "[warning] Error parsing '#{path}' .. (#{e.class})."
44
+ end
31
45
  end
32
46
  end
33
47
 
34
48
  Pry.configure do |config|
49
+ twitter = nil
35
50
  b = lambda do |*ary|
36
51
  pry = ary[-1]
37
- twitter = Twitter::REST::Client.new {|config|
52
+ twitter ||= Twitter::REST::Client.new {|config|
53
+ Pry::SendTweet.merge_yaml_file! pry.config,
54
+ File.join(ENV['HOME'], '.pry-send_tweet.yml')
38
55
  config.consumer_key = pry.config.twitter.consumer_key
39
56
  config.consumer_secret = pry.config.twitter.consumer_secret
40
57
  config.access_token = pry.config.twitter.access_token
@@ -1,5 +1,7 @@
1
1
  class Pry::SendTweet::BaseCommand < Pry::ClassCommand
2
2
  include Pry::SendTweet::TweetRenderer
3
+ include Pry::SendTweet::UserRenderer
4
+ include Pry::SendTweet::PagingSupport
3
5
 
4
6
  def self.inherited(kls)
5
7
  kls.group 'Twitter'
@@ -16,11 +18,7 @@ class Pry::SendTweet::BaseCommand < Pry::ClassCommand
16
18
 
17
19
  private
18
20
 
19
- def page(txt)
20
- _pry_.pager.page txt.to_s
21
- end
22
-
23
- def find_usernames_in(*ary)
21
+ def search_str_for_users(*ary)
24
22
  ary.map do |str|
25
23
  if str.start_with?('https://twitter.com')
26
24
  File.basename URI.parse(URI.escape(str)).path
@@ -34,28 +32,32 @@ class Pry::SendTweet::BaseCommand < Pry::ClassCommand
34
32
 
35
33
  # With thanks to ActionView for this method
36
34
  def word_wrap(text, options = {})
37
- line_width = _pry_.config.twitter.line_width || Pry::SendTweet::DEFAULT_LINE_WIDTH
38
35
  text.split("\n").collect! do |line|
39
36
  line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
40
37
  end * "\n"
41
38
  end
42
39
 
43
40
  def numbered_list(title, ary)
44
- underline = "-" * title.size
45
- title = "#{bold(underline)}\n#{title.chomp}\n#{bold(underline)}\n\n"
41
+ title = "\n#{bold(title.chomp)}\n\n"
46
42
  title + ary.map.with_index { |item, index| yield(item, index+1) }.join("\n")
47
43
  end
48
44
 
49
- def twitter_error(e)
50
- msg = Exception === e ? e.message : e
51
- "#{bold(bright_red('Twitter Error:'))} #{msg}"
52
- end
53
-
54
45
  def time_format
55
46
  "%-d %b %Y, %-I:%M:%S %p"
56
47
  end
57
48
 
49
+ def line_width
50
+ _pry_.config.twitter.line_width || Pry::SendTweet::DEFAULT_LINE_WIDTH
51
+ end
52
+
58
53
  def twitter
59
54
  @twitter ||= _pry_.binding_stack[-1].eval('_twitter_')
60
55
  end
56
+
57
+ # @api private
58
+ # TTY::Box doesn't handle unicode well, we remove non-ASCII characters as a
59
+ # temporary work around.
60
+ def __tty_box_sanitize(str)
61
+ CGI.unescapeHTML str.chars.reject {|c| c.ord > 255}.join
62
+ end
61
63
  end
@@ -0,0 +1,16 @@
1
+ module Pry::SendTweet::PagingSupport
2
+ def page(str)
3
+ _pry_.pager.page(str.to_s)
4
+ end
5
+
6
+ def page_ok(str)
7
+ prefix = bright_green "OK: "
8
+ page "#{prefix}#{str}"
9
+ end
10
+
11
+ def page_error(str)
12
+ str = str.respond_to?(:message) ? str.message : str
13
+ prefix = bright_red "Error: "
14
+ page "#{prefix}#{str}"
15
+ end
16
+ end
@@ -35,7 +35,7 @@ class Pry::SendTweet::ReadTweets < Pry::SendTweet::BaseCommand
35
35
 
36
36
  def show_replies(user:)
37
37
  render_tweets lambda {
38
- username = find_usernames_in(user).first
38
+ username = search_str_for_users(user).first
39
39
  twitter.user_timeline(username, timeline_options).select {|tweet|
40
40
  tweet.reply? &&
41
41
  tweet.in_reply_to_screen_name? &&
@@ -47,7 +47,7 @@ class Pry::SendTweet::ReadTweets < Pry::SendTweet::BaseCommand
47
47
 
48
48
  def show_likes(user:)
49
49
  if user
50
- user = find_usernames_in(user).first
50
+ user = search_str_for_users(user).first
51
51
  render_tweets lambda { twitter.favorites(user, count: opts['count'] || Pry::SendTweet::DEFAULT_READ_SIZE)},
52
52
  title: "Tweets liked by #{bright_white('@'+user)}"
53
53
  else
@@ -62,7 +62,7 @@ class Pry::SendTweet::ReadTweets < Pry::SendTweet::BaseCommand
62
62
  title: '@'+user
63
63
  else
64
64
  render_tweets lambda { twitter.home_timeline(timeline_options) },
65
- title: "Twitter.com"
65
+ title: "Twitter"
66
66
  end
67
67
  end
68
68
 
@@ -68,12 +68,9 @@ class Pry::SendTweet::SendTweet < Pry::SendTweet::BaseCommand
68
68
  end
69
69
 
70
70
  def prepend_username_to_reply!(tweet_url, file)
71
- username = tweet_username_from(tweet_url)
72
- file.write "@#{username} "
73
- end
74
-
75
- def tweet_username_from(tweet_url)
76
- File.basename File.dirname(File.dirname(tweet_url))
71
+ tweet = twitter.status(tweet_url)
72
+ mentions = tweet.user_mentions.map{|u| "@#{u.screen_name}"}.join(' ')
73
+ file.write "@#{tweet.user.screen_name} #{mentions}"
77
74
  end
78
75
 
79
76
  def replying_to_other_tweet?
@@ -28,10 +28,13 @@ class Pry::SendTweet::TwitterAction < Pry::SendTweet::BaseCommand
28
28
  o.on 'like-tweet=', 'Like one or more tweets', as: Array
29
29
  o.on 'unlike-tweet=', 'Unlike one or more tweets', as: Array
30
30
  #
31
- # Follow / unfollow a user
31
+ # Following / unfollowing
32
32
  #
33
33
  o.on 'follow=', 'Follow one or more users', as: Array
34
34
  o.on 'unfollow=', 'Unfollow one or more users', as: Array
35
+ o.on 'show-followers=', 'Show the newest tweeters to have followed you or ' \
36
+ 'another user', argument: :optional
37
+ o.on 'show-following', 'Show the newest tweeters you currently follow'
35
38
  #
36
39
  # Delete tweets and reweets
37
40
  #
@@ -44,11 +47,11 @@ class Pry::SendTweet::TwitterAction < Pry::SendTweet::BaseCommand
44
47
  #
45
48
  # Profile management
46
49
  #
47
- o.on 'set-profile-bio', 'Set your profiles bio'
48
- o.on 'set-profile-url=', 'Set the URL associated with your profile'
49
- o.on 'set-profile-banner-image=', 'Set your profiles banner image'
50
50
  o.on 'set-profile-name=', 'Set the name associated with your profile'
51
- o.on 'set-profile-image=', 'Set your profile image'
51
+ o.on 'set-profile-bio', 'Set your profiles bio'
52
+ o.on 'set-profile-url=', 'Set the URL associated with your profile'
53
+ o.on 'set-profile-banner-image=', 'Set the banner image used by your profile'
54
+ o.on 'set-profile-image=', 'Set your profile photo'
52
55
  #
53
56
  # Suggestions
54
57
  #
@@ -83,6 +86,8 @@ class Pry::SendTweet::TwitterAction < Pry::SendTweet::BaseCommand
83
86
  when opts.present?('suggested-users') then suggested_users(opts['suggested-users'])
84
87
  when opts.present?('mute-user') then mute_user(opts['mute-user'])
85
88
  when opts.present?('unmute-user') then unmute_user(opts['unmute-user'])
89
+ when opts.present?('show-followers') then show_followers
90
+ when opts.present?('show-following') then show_following
86
91
  end
87
92
  end
88
93
 
@@ -90,18 +95,17 @@ class Pry::SendTweet::TwitterAction < Pry::SendTweet::BaseCommand
90
95
 
91
96
  def retweet_tweet(tweets)
92
97
  retweets = twitter.retweet(tweets)
93
- error_msg = word_wrap("No retweets created. Are you sure you gave a valid reference to " \
94
- "one or more tweets, and that you haven't already retweeted the supplied " \
95
- "tweet(s) ..?")
96
- retweets.size > 0 ? render_tweets(retweets, title: bright_green("Retweeted tweets"), timeout: false) :
97
- page(twitter_error(error_msg))
98
+ if retweets.size > 0
99
+ render_tweets retweets, title: bright_green("Retweeted tweets"), timeout: false
100
+ else
101
+ page_error word_wrap("Nothing retweeted. Are you sure you gave a valid reference to " \
102
+ "one or more tweets, and that you haven't already retweeted the given " \
103
+ "tweet(s) ..?")
104
+ end
98
105
  rescue Twitter::Error => e
99
- page twitter_error(e)
100
- end
101
-
102
- def display_followed_or_unfollowed(user, index)
103
- sn = "@#{user.screen_name}"
104
- "#{sn} #{bold(bright_blue('|'))} #{user.url}"
106
+ page_error word_wrap("Nothing retweeted. Are you sure you gave a valid reference to " \
107
+ "one or more tweets, and that you haven't already retweeted the given " \
108
+ "tweet(s) ..?")
105
109
  end
106
110
 
107
111
  Pry.commands.add_command(self)
@@ -1,16 +1,19 @@
1
1
  module Pry::SendTweet::TwitterAction::DeleteTweetActions
2
2
  def delete_retweet(retweets)
3
3
  tweets = twitter.unretweet(retweets)
4
- tweets.size > 0 ? render_tweets(tweets, title: bold("Deleted retweets"), timeout: false) :
5
- page(twitter_error("No retweets deleted. Are you sure you gave a valid reference to the retweet?"))
4
+ if tweets.size == 0
5
+ page_error "Are you sure you gave a valid reference to one or more retweets?"
6
+ else
7
+ render_tweets tweets, title: bold("Deleted retweets"), timeout: false
8
+ end
6
9
  rescue Twitter::Error => e
7
- page twitter_error(e)
10
+ page_error(e)
8
11
  end
9
12
 
10
13
  def delete_tweet(tweets)
11
14
  tweets = twitter.destroy_status(tweets)
12
15
  render_tweets tweets, title: bold("Deleted tweets"), timeout: false
13
16
  rescue Twitter::Error => e
14
- page twitter_error(e)
17
+ page_error(e)
15
18
  end
16
19
  end
@@ -1,27 +1,58 @@
1
1
  module Pry::SendTweet::TwitterAction::FollowActions
2
2
  def follow_user(users)
3
- users = find_usernames_in(*users)
3
+ users = search_str_for_users(*users)
4
4
  follows = twitter.follow(users)
5
- follows.empty? ? page("Are you sure you are not already following #{join_usernames(users)} ?") :
6
- page(numbered_list(bold("Followed:"), follows) {|user, index|
7
- display_followed_or_unfollowed(user, index)
8
- })
5
+ if follows.empty?
6
+ page_error "Are you already following #{join_usernames(users)} ..?"
7
+ else
8
+ page numbered_list(bold("Followed"), follows) {|followed, index|
9
+ render_user(followed)
10
+ }
11
+ end
9
12
  rescue Twitter::Error => e
10
- page twitter_error(e)
13
+ page_error(e)
11
14
  end
12
15
 
13
16
  def unfollow_user(users)
14
- users = find_usernames_in(*users)
17
+ users = search_str_for_users(*users)
15
18
  unfollows = twitter.unfollow(users)
16
- unfollows.empty? ? page("Are you sure you are following #{join_usernames(users)} ?") :
17
- page(numbered_list(bold("Unfollowed:"), unfollows) {|user, index|
18
- display_followed_or_unfollowed(user, index)
19
- })
19
+ if unfollows.empty?
20
+ page_error "Did you already unfollow #{join_usernames(users)} ..?"
21
+ else
22
+ page numbered_list(bold("Unfollowed"), unfollows) {|unfollowed, index|
23
+ render_user(unfollowed)
24
+ }
25
+ end
20
26
  rescue Twitter::Error => e
21
- page twitter_error(e)
27
+ page_error(e)
28
+ end
29
+
30
+ def show_followers
31
+ followers = twitter.followers(follow_request_options)
32
+ page numbered_list("Followers", followers) {|follower, index|
33
+ render_user(follower)
34
+ }
35
+ rescue Twitter::Error => e
36
+ page_error(e)
37
+ end
38
+
39
+ def show_following
40
+ followings = twitter.following(follow_request_options)
41
+ page numbered_list("Following", followings) {|following, index|
42
+ render_user(following)
43
+ }
44
+ rescue Twitter::Error => e
45
+ page_error(e)
22
46
  end
23
47
 
24
48
  private
49
+
50
+ # @api private
51
+ def follow_request_options
52
+ {skip_status: true, include_user_entities: true}
53
+ end
54
+
55
+ # @api private
25
56
  def join_usernames(users)
26
57
  users.map do |username|
27
58
  bold("@#{username}")
@@ -1,17 +1,23 @@
1
1
  module Pry::SendTweet::TwitterAction::LikeActions
2
2
  def like_tweet(tweets)
3
3
  liked = twitter.favorite(tweets)
4
- liked.size > 0 ? render_tweets(liked, title: bold("Liked tweets"), timeout: false) :
5
- page(twitter_error("Tweet(s) not liked. Maybe you liked those tweet(s) already?"))
4
+ if liked.size > 0
5
+ render_tweets liked, title: bold("Liked tweets"), timeout: false
6
+ else
7
+ page_error "No tweets liked, are you sure you didn't already like those tweet(s) ..?"
8
+ end
6
9
  rescue Timeout::Error => e
7
- page twitter_error(e)
10
+ page_error(e)
8
11
  end
9
12
 
10
13
  def unlike_tweet(tweets)
11
14
  unliked = twitter.unfavorite(tweets)
12
- unliked.size > 0 ? render_tweets(unliked, title: bold("Unliked tweets"), timeout: false) :
13
- page(twitter_error("Tweet(s) not unliked. Maybe you haven't liked those tweet(s)?"))
15
+ if unliked.size > 0
16
+ render_tweets unliked, title: bold("Unliked tweets"), timeout: false
17
+ else
18
+ page_error "No tweets unliked, are you sure you had liked those tweet(s) ..?"
19
+ end
14
20
  rescue Twitter::Error => e
15
- page twitter_error(e)
21
+ page_error(e)
16
22
  end
17
23
  end
@@ -1,20 +1,23 @@
1
1
  module Pry::SendTweet::TwitterAction::MuteActions
2
2
  def mute_user(strings)
3
- muted = twitter.mute(*find_usernames_in(*strings))
4
- muted.empty? ? page("No users muted. Maybe you muted them already?") :
5
- page(numbered_list("Muted users", muted) {|user, index|
6
- display_followed_or_unfollowed(user, index)
7
- })
3
+ muted = twitter.mute(*search_str_for_users(*strings))
4
+ if muted.size > 0
5
+ page numbered_list("Muted users", muted) {|user, index|
6
+ render_user(user)
7
+ }
8
+ else
9
+ page_error "No one was muted, did you mute those user(s) already ..?"
10
+ end
8
11
  rescue Twitter::Error => e
9
- page twitter_error(e)
12
+ page_error(e)
10
13
  end
11
14
 
12
15
  def unmute_user(strings)
13
- unmuted = twitter.unmute(*find_usernames_in(*strings))
16
+ unmuted = twitter.unmute(*search_str_for_users(*strings))
14
17
  page numbered_list("Unmuted users", unmuted) {|user, index|
15
- display_followed_or_unfollowed(user, index)
18
+ render_user(user)
16
19
  }
17
20
  rescue Twitter::Error => e
18
- page twitter_error(e)
21
+ page_error(e)
19
22
  end
20
23
  end
@@ -11,7 +11,7 @@ module Pry::SendTweet::TwitterAction::ProfileActions
11
11
  twitter.update_profile_image(path)
12
12
  page "Profile image updated"
13
13
  rescue Twitter::Error => e
14
- page twitter_error(e)
14
+ page_error(e)
15
15
  end
16
16
 
17
17
  def set_profile_banner_image(path)
@@ -19,14 +19,14 @@ module Pry::SendTweet::TwitterAction::ProfileActions
19
19
  twitter.update_profile_banner(base64)
20
20
  page "Profile banner updated"
21
21
  rescue Twitter::Error => e
22
- page twitter_error(e)
22
+ page_error(e)
23
23
  end
24
24
 
25
25
  def set_profile_name(name)
26
26
  twitter.update_profile name: name
27
27
  page "Profile name updated"
28
28
  rescue Twitter::Error => e
29
- page twitter_error(e)
29
+ page_error(e)
30
30
  end
31
31
 
32
32
  def set_profile_bio
@@ -37,6 +37,6 @@ module Pry::SendTweet::TwitterAction::ProfileActions
37
37
  page "Profile bio updated"
38
38
  end
39
39
  rescue Twitter::Error => e
40
- page twitter_error(e)
40
+ page_error(e)
41
41
  end
42
42
  end
@@ -10,7 +10,7 @@ module Pry::SendTweet::TwitterAction::SuggestedActions
10
10
  topic = URI.escape(topic)
11
11
  users = twitter.suggestions(topic, lang: suggested_lang).users
12
12
  page numbered_list("Suggested users: ", users) {|user, index|
13
- display_followed_or_unfollowed(user, index)
13
+ render_user(user)
14
14
  }
15
15
  end
16
16
 
@@ -1,19 +1,14 @@
1
1
  module Pry::SendTweet::TweetRenderer
2
2
  include Timeout
3
3
 
4
- def render_tweets(fetch_tweets, title:, timeout: _pry_.config.twitter.refresh_interval)
5
- timeout = _pry_.config.twitter.refresh_interval
6
- interval = if timeout == false
7
- nil
8
- else
9
- timeout || (60*5)
10
- end
4
+ def render_tweets(tweet_fetcher, title:, timeout: _pry_.config.twitter.refresh_interval)
5
+ interval = __choose_render_interval(timeout)
11
6
  pid = nil
12
7
  timeout(interval) do
13
8
  pid = Kernel.fork do
14
9
  _pry_.pager.open do |pager|
15
10
  __trap_signal(pager)
16
- tweets = Proc === fetch_tweets ? fetch_tweets.call : fetch_tweets
11
+ tweets = __fetch_tweets(tweet_fetcher)
17
12
  tweets.empty? ? pager.write("No tweets to show.") :
18
13
  pager.write(__render_tweets(title, tweets))
19
14
 
@@ -30,36 +25,58 @@ module Pry::SendTweet::TweetRenderer
30
25
  retry
31
26
  end
32
27
 
33
- def render_tweet(tweet)
34
- line_width = _pry_.config.twitter.line_width || Pry::SendTweet::DEFAULT_LINE_WIDTH
35
- text = tweet.attrs[:full_text] ? tweet.attrs[:full_text] : tweet.full_text
36
- <<-TWEET.each_line.map{|s| s.chomp.strip}.join("\n")
37
- #{render_tweet_title(tweet)}
38
- #{tweet.url}
39
- #{bold("-") * line_width}
40
- #{word_wrap(CGI.unescapeHTML(text))}
41
- TWEET
28
+ private
29
+ # @api private
30
+ def __render_tweets(title, tweets)
31
+ title = bright_blue(bold((" " * 40) + title) + "\n\n")
32
+ title + tweets.map.with_index {|tweet, i| __render_tweet(tweet)}.join("\n")
42
33
  end
43
34
 
44
- def render_tweet_title(tweet)
45
- u = tweet.user
46
- created_at = tweet.created_at.getlocal
47
- <<-TWEET_TITLE.each_line.map{|s| s.chomp.strip}.join
48
- #{bold("@#{u.screen_name}")}
49
- #{bright_blue(" | ")}
50
- #{created_at.ago.in_words}
51
- #{bright_blue(" | ")}
52
- #{created_at.strftime(time_format)}
53
- TWEET_TITLE
35
+ # @api private
36
+ def __render_tweet(tweet)
37
+ contents = __get_tweet_contents(tweet)
38
+ TTY::Box.frame(height: 7,
39
+ width: line_width,
40
+ title: {top_left: __render_tweet_title(tweet)}) do
41
+ "#{tweet.url}\n--\n#{contents}\n"
42
+ end.to_s
54
43
  end
55
44
 
56
- private
57
45
  # @api private
58
- def __render_tweets(title, tweets)
59
- title = bright_blue(bold((" " * 40) + title) + "\n\n")
60
- title + tweets.map.with_index {|tweet, i|
61
- "#{red bold('#')}#{red bold(i+1)}\n#{render_tweet(tweet)}"
62
- }.join("\n\n")
46
+ def __render_tweet_title(tweet)
47
+ user, created_at = tweet.user, tweet.created_at.getlocal
48
+ title = [
49
+ bold("@#{user.screen_name}"),
50
+ created_at.ago.in_words,
51
+ created_at.strftime(time_format)
52
+ ].join bright_blue(" | ")
53
+ " #{title} "
54
+ end
55
+
56
+ # @api private
57
+ def __get_tweet_contents(tweet)
58
+ text = tweet.attrs[:full_text] ? tweet.attrs[:full_text] :
59
+ tweet.full_text
60
+ text = __tty_box_sanitize(CGI.unescapeHTML(text)).strip
61
+ text.size == 0 || text == '.' ? "\n[ Outside ASCII charset ]\n" : text
62
+ end
63
+
64
+ # @api private
65
+ def __fetch_tweets(tweet_fetcher)
66
+ if tweet_fetcher.respond_to?(:call)
67
+ tweet_fetcher.call
68
+ else
69
+ # Already fetched
70
+ tweet_fetcher
71
+ end
72
+ end
73
+
74
+ def __choose_render_interval(timeout)
75
+ if timeout == false
76
+ nil
77
+ else
78
+ timeout || (60*5)
79
+ end
63
80
  end
64
81
 
65
82
  # @api private
@@ -0,0 +1,15 @@
1
+ module Pry::SendTweet::UserRenderer
2
+ def render_user(user)
3
+ body = <<-USER
4
+ #{bold("Tweets")} #{user.tweets_count}
5
+ #{bold("Followers")} #{user.followers_count}
6
+ #{bold("Following")} #{user.friends_count}
7
+ #{__tty_box_sanitize(user.description)}
8
+ USER
9
+ TTY::Box.frame(
10
+ height: 8,
11
+ width: 80,
12
+ title: {top_left: "@#{user.screen_name} ( https://twitter.com/#{user.screen_name} )"}
13
+ ) { body }.to_s
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  class Pry
2
2
  module SendTweet
3
- VERSION = '0.8.0'
3
+ VERSION = '0.9.0'
4
4
  end
5
5
  end
@@ -9,8 +9,9 @@ Gem::Specification.new do |spec|
9
9
  spec.homepage = "https://github.com/r-obert/pry-send_tweet.rb"
10
10
  spec.licenses = ["MIT"]
11
11
  spec.require_paths = ["lib"]
12
- spec.files = Dir["Dockerfile", "Gemfile", "*.{txt,gemspec,md}", "lib/**/*.rb"]
12
+ spec.files = Dir["Dockerfile", "Gemfile", "*.{txt,gemspec,md,sh}", "lib/**/*.rb"]
13
13
  spec.add_runtime_dependency "pry", "~> 0.12"
14
14
  spec.add_runtime_dependency "twitter", "~> 6.0"
15
15
  spec.add_runtime_dependency "time-lord", "~> 1.0"
16
+ spec.add_runtime_dependency "tty-box"
16
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pry-send_tweet.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Gleeson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-09 00:00:00.000000000 Z
11
+ date: 2019-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tty-box
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: A Twitter client for the Pry REPL.
56
70
  email: trebor.g@protonmail.com
57
71
  executables: []
@@ -63,8 +77,10 @@ files:
63
77
  - Gemfile
64
78
  - LICENSE.txt
65
79
  - README.md
80
+ - dockerize.sh
66
81
  - lib/pry-send_tweet.rb
67
82
  - lib/pry/send_tweet/commands/base_command.rb
83
+ - lib/pry/send_tweet/commands/paging/paging_support.rb
68
84
  - lib/pry/send_tweet/commands/read_tweets.rb
69
85
  - lib/pry/send_tweet/commands/send_tweet.rb
70
86
  - lib/pry/send_tweet/commands/twitter_action.rb
@@ -76,6 +92,7 @@ files:
76
92
  - lib/pry/send_tweet/commands/twitter_action/suggested_actions.rb
77
93
  - lib/pry/send_tweet/commands/twitter_search.rb
78
94
  - lib/pry/send_tweet/renderers/tweet_renderer.rb
95
+ - lib/pry/send_tweet/renderers/user_renderer.rb
79
96
  - lib/pry/send_tweet/version.rb
80
97
  - pry-send_tweet.gemspec
81
98
  homepage: https://github.com/r-obert/pry-send_tweet.rb