pry-send_tweet.rb 0.6.0 → 0.7.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 +4 -4
- data/CHANGELOG.md +43 -0
- data/Dockerfile +6 -4
- data/Gemfile +3 -1
- data/README.md +139 -52
- data/lib/pry-send_tweet.rb +31 -11
- data/lib/pry/send_tweet/{base_command.rb → commands/base_command.rb} +15 -6
- data/lib/pry/send_tweet/commands/read_tweets.rb +83 -0
- data/lib/pry/send_tweet/commands/send_tweet.rb +141 -0
- data/lib/pry/send_tweet/commands/twitter_action.rb +109 -0
- data/lib/pry/send_tweet/commands/twitter_action/delete_tweet_actions.rb +16 -0
- data/lib/pry/send_tweet/commands/twitter_action/follow_actions.rb +30 -0
- data/lib/pry/send_tweet/commands/twitter_action/like_actions.rb +17 -0
- data/lib/pry/send_tweet/commands/twitter_action/mute_actions.rb +20 -0
- data/lib/pry/send_tweet/commands/twitter_action/profile_actions.rb +42 -0
- data/lib/pry/send_tweet/commands/twitter_action/suggested_actions.rb +20 -0
- data/lib/pry/send_tweet/commands/twitter_search.rb +35 -0
- data/lib/pry/send_tweet/renderers/tweet_renderer.rb +78 -0
- data/lib/pry/send_tweet/version.rb +1 -1
- data/pry-send_tweet.gemspec +2 -1
- metadata +31 -10
- data/lib/pry/send_tweet/mixins/tweet_renderer.rb +0 -58
- data/lib/pry/send_tweet/read_tweets_command.rb +0 -78
- data/lib/pry/send_tweet/send_tweet_command.rb +0 -96
- data/lib/pry/send_tweet/twitter_action_command.rb +0 -184
@@ -0,0 +1,83 @@
|
|
1
|
+
class Pry::SendTweet::ReadTweets < Pry::SendTweet::BaseCommand
|
2
|
+
match 'read-tweets'
|
3
|
+
description 'A command for reading tweets.'
|
4
|
+
banner <<-BANNER
|
5
|
+
read-tweets [OPTIONS]
|
6
|
+
|
7
|
+
#{description}
|
8
|
+
BANNER
|
9
|
+
|
10
|
+
def options(o)
|
11
|
+
o.on 't=', 'tweeter=',
|
12
|
+
'A username whose timeline you want to read.'
|
13
|
+
o.on 'c=', 'count=',
|
14
|
+
"The number of tweets to read. The maximum is 200, and the default is " \
|
15
|
+
"#{Pry::SendTweet::DEFAULT_READ_SIZE}."
|
16
|
+
o.on 'l=', 'likes=',
|
17
|
+
'Read tweets you or another user have liked.',
|
18
|
+
argument: :optional
|
19
|
+
o.on 'r=', 'replies=', 'A username whose replies you want to read'
|
20
|
+
o.on 'm', 'mentions', 'Read tweets that @mention you.'
|
21
|
+
o.on 'w', 'with-retweets', 'Include retweets.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def process
|
25
|
+
super
|
26
|
+
case
|
27
|
+
when opts.present?('replies') then show_replies(user: opts['replies'])
|
28
|
+
when opts.present?('likes') then show_likes(user: opts['likes'])
|
29
|
+
when opts.present?('mentions') then show_mentions
|
30
|
+
else show_tweets_from_timeline(user: opts['tweeter'])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def show_replies(user:)
|
37
|
+
render_tweets lambda {
|
38
|
+
username = find_usernames_in(user).first
|
39
|
+
twitter.user_timeline(username, timeline_options).select {|tweet|
|
40
|
+
tweet.reply? &&
|
41
|
+
tweet.in_reply_to_screen_name? &&
|
42
|
+
tweet.in_reply_to_screen_name.downcase != username.downcase
|
43
|
+
}
|
44
|
+
},
|
45
|
+
title: format("Replies sent by %{user}", user: bold("@#{user}"))
|
46
|
+
end
|
47
|
+
|
48
|
+
def show_likes(user:)
|
49
|
+
if user
|
50
|
+
user = find_usernames_in(user).first
|
51
|
+
render_tweets lambda { twitter.favorites(user, count: opts['count'] || Pry::SendTweet::DEFAULT_READ_SIZE)},
|
52
|
+
title: "Tweets liked by #{bright_white('@'+user)}"
|
53
|
+
else
|
54
|
+
render_tweets lambda { twitter.favorites(count: opts['count'] || Pry::SendTweet::DEFAULT_READ_SIZE) },
|
55
|
+
title: "Liked tweets"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def show_tweets_from_timeline(user:)
|
60
|
+
if user
|
61
|
+
render_tweets lambda { twitter.user_timeline(user, timeline_options) },
|
62
|
+
title: '@'+user
|
63
|
+
else
|
64
|
+
render_tweets lambda { twitter.home_timeline(timeline_options) },
|
65
|
+
title: "Twitter.com"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def show_mentions
|
70
|
+
render_tweets lambda { twitter.mentions(timeline_options) },
|
71
|
+
title: "Tweets that #{bright_white('@mention')} #{bright_blue('you')}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def timeline_options
|
75
|
+
{
|
76
|
+
tweet_mode: 'extended',
|
77
|
+
include_rts: opts.present?('with-retweets'),
|
78
|
+
count: opts.present?('count') ? opts['count'] : Pry::SendTweet::DEFAULT_READ_SIZE
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
Pry.commands.add_command self
|
83
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
class Pry::SendTweet::SendTweet < Pry::SendTweet::BaseCommand
|
2
|
+
MAX_TWEET_SIZE = 280
|
3
|
+
|
4
|
+
match 'send-tweet'
|
5
|
+
description 'Send a tweet'
|
6
|
+
command_options argument_required: false
|
7
|
+
banner <<-BANNER
|
8
|
+
send-tweet [options]
|
9
|
+
|
10
|
+
Send a tweet.
|
11
|
+
BANNER
|
12
|
+
|
13
|
+
def options(o)
|
14
|
+
o.on 'f=', 'file=',
|
15
|
+
'One or more paths to image(s) to attach to a tweet',
|
16
|
+
as: Array
|
17
|
+
o.on 'r=', 'reply-to=',
|
18
|
+
'An absolute url to a tweet you want to reply to.'
|
19
|
+
o.on 's=', 'self-destruct=',
|
20
|
+
'The number of seconds (represented as a number or a timestamp in the ' \
|
21
|
+
'format of HH:MM:SS) to wait before automatically deleting the tweet ' \
|
22
|
+
'asynchronously'
|
23
|
+
o.on 'd=', 'delay=',
|
24
|
+
'The number of seconds (represented as a number or a timestamp in the ' \
|
25
|
+
'format of HH:MM:SS) to wait before creating the tweet asynchronously'
|
26
|
+
o.on 'n', 'no-newline',
|
27
|
+
"Remove newlines (\\n) from a tweet before sending it"
|
28
|
+
end
|
29
|
+
|
30
|
+
def process(args)
|
31
|
+
super
|
32
|
+
tweet_contents = compose_tweet_with_editor
|
33
|
+
create_tweet = opts.present?(:file) ? lambda { send_tweet_with_media(tweet_contents) } :
|
34
|
+
lambda { send_textual_tweet(tweet_contents) }
|
35
|
+
if opts.present?('delay')
|
36
|
+
time_obj, sleep_seconds = parse_duration_str(opts['delay'])
|
37
|
+
Thread.new {
|
38
|
+
sleep sleep_seconds
|
39
|
+
create_tweet.call
|
40
|
+
}
|
41
|
+
publish_time = (time_obj ? time_obj : Time.now + sleep_seconds)
|
42
|
+
.getlocal
|
43
|
+
.strftime(time_format)
|
44
|
+
page bold("Tweet will be published at approximately #{publish_time}.")
|
45
|
+
else
|
46
|
+
tweet = create_tweet.call
|
47
|
+
page tweet.url
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def no_newline?
|
54
|
+
opts.present?('no-newline')
|
55
|
+
end
|
56
|
+
|
57
|
+
def send_tweet_with_media(tweet_contents)
|
58
|
+
medias = opts['file'].map{|p| File.new p, 'r'}
|
59
|
+
tweet = twitter.update_with_media(tweet_contents, medias, tweet_options)
|
60
|
+
tweet.tap {|t| self_destruct! t.id, opts['self-destruct'] }
|
61
|
+
ensure
|
62
|
+
medias.each(&:close)
|
63
|
+
end
|
64
|
+
|
65
|
+
def send_textual_tweet(tweet_contents)
|
66
|
+
tweet = twitter.update(tweet_contents, tweet_options)
|
67
|
+
tweet.tap {|t| self_destruct! t.id, opts['self-destruct'] }
|
68
|
+
end
|
69
|
+
|
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))
|
77
|
+
end
|
78
|
+
|
79
|
+
def replying_to_other_tweet?
|
80
|
+
opts.present?('reply-to')
|
81
|
+
end
|
82
|
+
|
83
|
+
def tweet_options
|
84
|
+
options = {}
|
85
|
+
options.merge!({
|
86
|
+
in_reply_to_status_id: Integer(File.basename(opts['reply-to']))
|
87
|
+
}) if replying_to_other_tweet?
|
88
|
+
options
|
89
|
+
end
|
90
|
+
|
91
|
+
def compose_tweet_with_editor
|
92
|
+
tweet = Tempfile.open('pry-send_tweet--compose-tweet') do |file|
|
93
|
+
if replying_to_other_tweet?
|
94
|
+
# During experimentation I noticed that without prefixing who we are
|
95
|
+
# replying to, the tweet we send will not be considered a reply even
|
96
|
+
# with reply_to_status_id being set.
|
97
|
+
prepend_username_to_reply!(opts['reply-to'], file)
|
98
|
+
end
|
99
|
+
file.rewind
|
100
|
+
Pry::Editor.new(_pry_).invoke_editor(file.path, 0)
|
101
|
+
lines = file.read.each_line
|
102
|
+
no_newline? ? lines.map(&:chomp).join(' ') : lines.to_a.join
|
103
|
+
end
|
104
|
+
validate_tweet!(tweet)
|
105
|
+
tweet
|
106
|
+
end
|
107
|
+
|
108
|
+
def validate_tweet!(tweet)
|
109
|
+
if tweet.strip.empty?
|
110
|
+
raise Pry::CommandError, "Can't post an empty tweet."
|
111
|
+
elsif tweet.size > MAX_TWEET_SIZE
|
112
|
+
raise Pry::CommandError, "The tweet: \n" +
|
113
|
+
word_wrap(tweet) +
|
114
|
+
"\nis too big to publish, try to use less characters."
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def self_destruct!(tweet_id, duration)
|
119
|
+
return if !duration
|
120
|
+
_, sleep_seconds = parse_duration_str(duration)
|
121
|
+
page bold("Tweet due to self destruct in #{sleep_seconds} seconds")
|
122
|
+
Thread.new do
|
123
|
+
sleep sleep_seconds
|
124
|
+
twitter.destroy_status(tweet_id)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def parse_duration_str(str)
|
129
|
+
if str =~ /\A\d+\z/
|
130
|
+
sleep_seconds = Integer(str)
|
131
|
+
elsif str =~ /\A\d{2}:\d{2}\z/ || str =~ /\A\d{2}:\d{2}:\d{2}\z/
|
132
|
+
time_obj = Time.parse(str)
|
133
|
+
sleep_seconds = Integer(time_obj - Time.now)
|
134
|
+
else
|
135
|
+
raise Pry::CommandError, "The argument --delay='#{str}' is not " \
|
136
|
+
"something I understand."
|
137
|
+
end
|
138
|
+
[time_obj, sleep_seconds]
|
139
|
+
end
|
140
|
+
Pry.commands.add_command self
|
141
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
|
2
|
+
class Pry::SendTweet::TwitterAction < Pry::SendTweet::BaseCommand
|
3
|
+
require_relative 'twitter_action/profile_actions'
|
4
|
+
require_relative 'twitter_action/suggested_actions'
|
5
|
+
require_relative 'twitter_action/like_actions'
|
6
|
+
require_relative 'twitter_action/follow_actions'
|
7
|
+
require_relative 'twitter_action/mute_actions'
|
8
|
+
require_relative 'twitter_action/delete_tweet_actions'
|
9
|
+
include ProfileActions
|
10
|
+
include SuggestedActions
|
11
|
+
include LikeActions
|
12
|
+
include FollowActions
|
13
|
+
include MuteActions
|
14
|
+
include DeleteTweetActions
|
15
|
+
|
16
|
+
match 'twitter-action'
|
17
|
+
description 'Like, unlike, follow, unfollow and more'
|
18
|
+
banner <<-B
|
19
|
+
twitter-action OPTIONS
|
20
|
+
|
21
|
+
Like, unlike, follow, unfollow and more.
|
22
|
+
B
|
23
|
+
|
24
|
+
def options(o)
|
25
|
+
#
|
26
|
+
# Like / unlike tweets
|
27
|
+
#
|
28
|
+
o.on 'like-tweet=', 'Like one or more tweets', as: Array
|
29
|
+
o.on 'unlike-tweet=', 'Unlike one or more tweets', as: Array
|
30
|
+
#
|
31
|
+
# Follow / unfollow a user
|
32
|
+
#
|
33
|
+
o.on 'follow=', 'Follow one or more users', as: Array
|
34
|
+
o.on 'unfollow=', 'Unfollow one or more users', as: Array
|
35
|
+
#
|
36
|
+
# Delete tweets and reweets
|
37
|
+
#
|
38
|
+
o.on 'delete-retweet=', 'Delete one or more retweets', as: Array
|
39
|
+
o.on 'delete-tweet=', 'Delete one or more tweets', as: Array
|
40
|
+
#
|
41
|
+
# Retweet a tweet
|
42
|
+
#
|
43
|
+
o.on 'retweet=', 'Retweet one or more tweets', as: Array
|
44
|
+
#
|
45
|
+
# Profile management
|
46
|
+
#
|
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
|
+
o.on 'set-profile-name=', 'Set the name associated with your profile'
|
51
|
+
o.on 'set-profile-image=', 'Set your profile image'
|
52
|
+
#
|
53
|
+
# Suggestions
|
54
|
+
#
|
55
|
+
o.on 'suggested-topics', 'View topics suggested by Twitter'
|
56
|
+
o.on 'suggested-users=', 'A topic from which to view users Twitter ' \
|
57
|
+
'suggests following'
|
58
|
+
o.on 'suggested-lang=', 'Restrict suggestion results to a specific language, ' \
|
59
|
+
'given in ISO 639-1 format. Default is "en"'
|
60
|
+
#
|
61
|
+
# Muting
|
62
|
+
#
|
63
|
+
o.on 'mute-user=', 'One or more usersname to mute', as: Array
|
64
|
+
o.on 'unmute-user=', 'One or more usernames to unmute', as: Array
|
65
|
+
end
|
66
|
+
|
67
|
+
def process
|
68
|
+
super
|
69
|
+
case
|
70
|
+
when opts.present?('like-tweet') then like_tweet(opts['like-tweet'])
|
71
|
+
when opts.present?('unlike-tweet') then unlike_tweet(opts['unlike-tweet'])
|
72
|
+
when opts.present?('follow') then follow_user(opts['follow'])
|
73
|
+
when opts.present?('unfollow') then unfollow_user(opts['unfollow'])
|
74
|
+
when opts.present?('delete-tweet') then delete_tweet(opts['delete-tweet'])
|
75
|
+
when opts.present?('delete-retweet') then delete_retweet(opts['delete-retweet'])
|
76
|
+
when opts.present?('retweet') then retweet_tweet(opts['retweet'])
|
77
|
+
when opts.present?('set-profile-banner-image') then set_profile_banner_image(opts['set-profile-banner-image'])
|
78
|
+
when opts.present?('set-profile-name') then set_profile_name(opts['set-profile-name'])
|
79
|
+
when opts.present?('set-profile-image') then set_profile_image(opts['set-profile-image'])
|
80
|
+
when opts.present?('set-profile-url') then set_profile_url(opts['set-profile-url'])
|
81
|
+
when opts.present?('set-profile-bio') then set_profile_bio
|
82
|
+
when opts.present?('suggested-topics') then suggested_topics
|
83
|
+
when opts.present?('suggested-users') then suggested_users(opts['suggested-users'])
|
84
|
+
when opts.present?('mute-user') then mute_user(opts['mute-user'])
|
85
|
+
when opts.present?('unmute-user') then unmute_user(opts['unmute-user'])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def retweet_tweet(tweets)
|
92
|
+
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
|
+
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}"
|
105
|
+
end
|
106
|
+
|
107
|
+
Pry.commands.add_command(self)
|
108
|
+
Pry.commands.alias_command "on-twitter", "twitter-action"
|
109
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Pry::SendTweet::TwitterAction::DeleteTweetActions
|
2
|
+
def delete_retweet(retweets)
|
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?"))
|
6
|
+
rescue Twitter::Error => e
|
7
|
+
page twitter_error(e)
|
8
|
+
end
|
9
|
+
|
10
|
+
def delete_tweet(tweets)
|
11
|
+
tweets = twitter.destroy_status(tweets)
|
12
|
+
render_tweets tweets, title: bold("Deleted tweets"), timeout: false
|
13
|
+
rescue Twitter::Error => e
|
14
|
+
page twitter_error(e)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Pry::SendTweet::TwitterAction::FollowActions
|
2
|
+
def follow_user(users)
|
3
|
+
users = find_usernames_in(*users)
|
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
|
+
})
|
9
|
+
rescue Twitter::Error => e
|
10
|
+
page twitter_error(e)
|
11
|
+
end
|
12
|
+
|
13
|
+
def unfollow_user(users)
|
14
|
+
users = find_usernames_in(*users)
|
15
|
+
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
|
+
})
|
20
|
+
rescue Twitter::Error => e
|
21
|
+
page twitter_error(e)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def join_usernames(users)
|
26
|
+
users.map do |username|
|
27
|
+
bold("@#{username}")
|
28
|
+
end.join(', ')
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Pry::SendTweet::TwitterAction::LikeActions
|
2
|
+
def like_tweet(tweets)
|
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?"))
|
6
|
+
rescue Timeout::Error => e
|
7
|
+
page twitter_error(e)
|
8
|
+
end
|
9
|
+
|
10
|
+
def unlike_tweet(tweets)
|
11
|
+
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)?"))
|
14
|
+
rescue Twitter::Error => e
|
15
|
+
page twitter_error(e)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Pry::SendTweet::TwitterAction::MuteActions
|
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
|
+
})
|
8
|
+
rescue Twitter::Error => e
|
9
|
+
page twitter_error(e)
|
10
|
+
end
|
11
|
+
|
12
|
+
def unmute_user(strings)
|
13
|
+
unmuted = twitter.unmute(*find_usernames_in(*strings))
|
14
|
+
page numbered_list("Unmuted users", unmuted) {|user, index|
|
15
|
+
display_followed_or_unfollowed(user, index)
|
16
|
+
}
|
17
|
+
rescue Twitter::Error => e
|
18
|
+
page twitter_error(e)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Pry::SendTweet::TwitterAction::ProfileActions
|
2
|
+
def set_profile_url(url)
|
3
|
+
if twitter.update_profile url: url
|
4
|
+
page "Profile URL updated"
|
5
|
+
else
|
6
|
+
raise Pry::CommandError, "Something went wrong"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def set_profile_image(path)
|
11
|
+
twitter.update_profile_image(path)
|
12
|
+
page "Profile image updated"
|
13
|
+
rescue Twitter::Error => e
|
14
|
+
page twitter_error(e)
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_profile_banner_image(path)
|
18
|
+
base64 = Base64.strict_encode64 File.binread(path)
|
19
|
+
twitter.update_profile_banner(base64)
|
20
|
+
page "Profile banner updated"
|
21
|
+
rescue Twitter::Error => e
|
22
|
+
page twitter_error(e)
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_profile_name(name)
|
26
|
+
twitter.update_profile name: name
|
27
|
+
page "Profile name updated"
|
28
|
+
rescue Twitter::Error => e
|
29
|
+
page twitter_error(e)
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_profile_bio
|
33
|
+
Tempfile.open('pry-send_tweet-set-bio') do |file|
|
34
|
+
Pry::Editor.new(_pry_).invoke_editor(file.path, 0)
|
35
|
+
file.rewind
|
36
|
+
twitter.update_profile description: file.read
|
37
|
+
page "Profile bio updated"
|
38
|
+
end
|
39
|
+
rescue Twitter::Error => e
|
40
|
+
page twitter_error(e)
|
41
|
+
end
|
42
|
+
end
|