pry-send_tweet.rb 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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