ayadn 0.6.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 +15 -0
- data/CHANGELOG.md +232 -0
- data/CONTRIBUTORS.md +5 -0
- data/LICENSE.md +14 -0
- data/README.md +489 -0
- data/bin/ayadn +358 -0
- data/config.yml +35 -0
- data/lib/ayadn/adn_files.rb +84 -0
- data/lib/ayadn/api.rb +302 -0
- data/lib/ayadn/authorize.rb +29 -0
- data/lib/ayadn/client-http.rb +226 -0
- data/lib/ayadn/colors.rb +62 -0
- data/lib/ayadn/debug.rb +36 -0
- data/lib/ayadn/endpoints.rb +154 -0
- data/lib/ayadn/extend.rb +23 -0
- data/lib/ayadn/files.rb +184 -0
- data/lib/ayadn/get-api.rb +43 -0
- data/lib/ayadn/help.rb +149 -0
- data/lib/ayadn/list.rb +89 -0
- data/lib/ayadn/main.rb +536 -0
- data/lib/ayadn/pinboard.rb +37 -0
- data/lib/ayadn/post.rb +212 -0
- data/lib/ayadn/requires.rb +12 -0
- data/lib/ayadn/skip.rb +27 -0
- data/lib/ayadn/status.rb +166 -0
- data/lib/ayadn/tools.rb +204 -0
- data/lib/ayadn/user-stream.rb +91 -0
- data/lib/ayadn/view-channels.rb +119 -0
- data/lib/ayadn/view-interactions.rb +57 -0
- data/lib/ayadn/view-object.rb +193 -0
- data/lib/ayadn/view.rb +270 -0
- data/lib/ayadn.rb +24 -0
- data/lib/experiments.rb +109 -0
- metadata +110 -0
data/lib/ayadn/post.rb
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
class AyaDN
|
4
|
+
def ayadn_compose_post
|
5
|
+
puts $status.writePost + "\n"
|
6
|
+
char_count = $tools.ayadn_configuration[:post_max_length]
|
7
|
+
begin
|
8
|
+
input_text = STDIN.gets.chomp
|
9
|
+
rescue Exception
|
10
|
+
abort($status.errorPostNotSent)
|
11
|
+
end
|
12
|
+
real_text_length = $tools.getMarkdownText(input_text.dup).length
|
13
|
+
remaining_text_length = char_count - real_text_length
|
14
|
+
if remaining_text_length >= 0
|
15
|
+
ayadnSendPost(input_text, nil)
|
16
|
+
else
|
17
|
+
abort($status.errorPostTooLong(real_text_length, remaining_text_length.abs))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
def ayadnSendPost(text, reply_to = nil)
|
21
|
+
abort($status.emptyPost) if (text == nil)
|
22
|
+
puts $status.sendPost
|
23
|
+
blob = JSON.parse(@api.httpSend(text, reply_to))
|
24
|
+
@hash = blob['data']
|
25
|
+
my_post_id = @hash['id']
|
26
|
+
puts @view.new(nil).buildSimplePostInfo(@hash)
|
27
|
+
puts $status.postSent
|
28
|
+
if $tools.config['files']['auto_save_sent_posts']
|
29
|
+
fileURL = $tools.ayadn_configuration[:posts_path] + "/#{my_post_id}.post"
|
30
|
+
f = File.new(fileURL, "w")
|
31
|
+
f.puts(@hash)
|
32
|
+
f.close
|
33
|
+
end
|
34
|
+
if (reply_to == nil || reply_to.empty?)
|
35
|
+
@hash = @api.getSimpleUnified
|
36
|
+
stream, last_page_id = completeStream
|
37
|
+
stream.sub!(/#{my_post_id}/, my_post_id.to_s.green.reverse_color)
|
38
|
+
displayStream(stream)
|
39
|
+
else
|
40
|
+
@hash = @api.getPostReplies(reply_to)
|
41
|
+
stream, last_page_id = completeStream
|
42
|
+
stream.sub!(/#{reply_to}/, reply_to.to_s.red.reverse_color)
|
43
|
+
stream.sub!(/#{my_post_id}/, my_post_id.to_s.green.reverse_color)
|
44
|
+
displayStream(stream)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
def ayadn_quote(post_id)
|
48
|
+
@progress_indicator = false
|
49
|
+
post_to_quote = @api.getSinglePost(post_id)
|
50
|
+
meta, data = post_to_quote['meta'], post_to_quote['data']
|
51
|
+
puts "\n"
|
52
|
+
if data['text'] != nil
|
53
|
+
text_to_quote = $tools.withoutSquareBraces(data['text']).chomp(" ")
|
54
|
+
else
|
55
|
+
abort("\n\nError: no text to quote.\n\n".red)
|
56
|
+
end
|
57
|
+
@new_string = text_to_quote
|
58
|
+
if data['entities']['links'] != nil
|
59
|
+
data['entities']['links'].each do |obj|
|
60
|
+
@new_string = text_to_quote.gsub("#{obj['text']}", "[#{obj['text']}](#{obj['url']})").chomp(" ")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
new_text = " >> @#{data['user']['username']}: " + (@new_string ||= text_to_quote)
|
64
|
+
remaining = $tools.ayadn_configuration[:post_max_length] - $tools.getMarkdownText(new_text.dup).length - 1
|
65
|
+
puts "AyaDN will automatically quote the original post like this after your comment. Markdown and embedded links will be preserved. (CTRL-C to cancel):\n".green
|
66
|
+
puts '"' + $tools.getMarkdownText(new_text.dup) + '"' + "\n"
|
67
|
+
abort("\nCANCELED: original text is too long, can't quote it.\n\n".red) if remaining <= 1
|
68
|
+
puts "\n#{remaining}".magenta + " characters remaining. Write your comment: \n\n".brown
|
69
|
+
begin
|
70
|
+
input_text = STDIN.gets.chomp
|
71
|
+
rescue Exception
|
72
|
+
abort($status.errorPostNotSent)
|
73
|
+
end
|
74
|
+
new_text = input_text + new_text
|
75
|
+
remaining = $tools.ayadn_configuration[:post_max_length] - $tools.getMarkdownText(new_text.dup).length
|
76
|
+
abort("\n" + $status.errorPostTooLong(new_text.length, new_text.length - $tools.ayadn_configuration[:post_max_length])) if remaining <= 0
|
77
|
+
ayadnSendPost(new_text)
|
78
|
+
end
|
79
|
+
def ayadn_reply(postID)
|
80
|
+
@progress_indicator = false
|
81
|
+
puts $status.replyingToPost(postID)
|
82
|
+
post_mentions_array, replying_to_this_username, is_repost = @api.getPostMentions(postID)
|
83
|
+
if is_repost != nil
|
84
|
+
puts $status.errorIsRepost(postID)
|
85
|
+
postID = is_repost['id']
|
86
|
+
puts $status.redirectingToOriginal(postID)
|
87
|
+
post_mentions_array, replying_to_this_username, is_repost = @api.getPostMentions(postID)
|
88
|
+
end
|
89
|
+
if $tools.config['identity']['prefix'] == "me"
|
90
|
+
me_saved = $files.users_read("me")
|
91
|
+
me_saved ? (my_username = me_saved) : (my_username = @api.getUserName("me"))
|
92
|
+
else
|
93
|
+
my_username = $tools.config['identity']['prefix']
|
94
|
+
end
|
95
|
+
#my_handle = "@" + my_username
|
96
|
+
replying_to_handle = "@" + replying_to_this_username
|
97
|
+
new_content = Array.new
|
98
|
+
# if I'm not answering myself, add the @username of the "replyee"
|
99
|
+
new_content.push(replying_to_handle) if replying_to_this_username != my_username
|
100
|
+
post_mentions_array.each do |item|
|
101
|
+
new_content.push("@" + item) if item != my_username
|
102
|
+
end
|
103
|
+
if new_content.length > 1
|
104
|
+
all_mentions = new_content.dup
|
105
|
+
leading_mention = all_mentions.first
|
106
|
+
all_mentions.shift
|
107
|
+
puts "\nThe leading mention (".green + leading_mention.red + ") has been put at the beginning of your post.\nThe rest of the mentions (".green + all_mentions.join(", ").red + ") will be added automatically at the end.".green
|
108
|
+
end
|
109
|
+
ayadn_compose_reply(postID, new_content)
|
110
|
+
end
|
111
|
+
def ayadn_compose_reply(reply_to, mentions_list = "")
|
112
|
+
puts $status.writePost
|
113
|
+
all_mentions = mentions_list.dup
|
114
|
+
char_count = $tools.ayadn_configuration[:post_max_length]
|
115
|
+
leading_mention = all_mentions.first
|
116
|
+
mentions_list.shift
|
117
|
+
mentions_list = mentions_list.join(" ")
|
118
|
+
if leading_mention != nil
|
119
|
+
text = leading_mention + " "
|
120
|
+
char_count -= 1
|
121
|
+
else
|
122
|
+
text = ""
|
123
|
+
end
|
124
|
+
print "\n#{text}"
|
125
|
+
begin
|
126
|
+
input_text = STDIN.gets.chomp
|
127
|
+
rescue Exception
|
128
|
+
abort($status.errorPostNotSent)
|
129
|
+
end
|
130
|
+
if leading_mention != nil
|
131
|
+
post_text = text + input_text + " " + mentions_list
|
132
|
+
real_text_length = $tools.getMarkdownText(post_text.dup).length
|
133
|
+
else
|
134
|
+
post_text = input_text
|
135
|
+
real_text_length = $tools.getMarkdownText(post_text.dup).length
|
136
|
+
end
|
137
|
+
remaining_text_length = char_count - real_text_length
|
138
|
+
if remaining_text_length >= 0
|
139
|
+
ayadnSendPost(post_text, reply_to)
|
140
|
+
else
|
141
|
+
abort($status.errorPostTooLong(real_text_length, real_text_length - $tools.ayadn_configuration[:post_max_length]))
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
def ayadnComposeMessage(target)
|
147
|
+
puts $status.writeMessage
|
148
|
+
begin
|
149
|
+
input_text = STDIN.gets.chomp
|
150
|
+
rescue Exception
|
151
|
+
abort($status.errorMessageNotSent)
|
152
|
+
end
|
153
|
+
real_length = $tools.getMarkdownText(input_text.dup).length
|
154
|
+
if real_length < $tools.ayadn_configuration[:message_max_length]
|
155
|
+
ayadnSendMessage(target, input_text)
|
156
|
+
else
|
157
|
+
abort($status.errorMessageTooLong(real_length, real_length - $tools.ayadn_configuration[:message_max_length]))
|
158
|
+
end
|
159
|
+
end
|
160
|
+
def ayadnSendMessage(target, text)
|
161
|
+
abort($status.emptyPost) if (text.empty? || text == nil)
|
162
|
+
puts $status.sendMessage
|
163
|
+
if target.is_integer?
|
164
|
+
target = $files.load_channel_id(target)
|
165
|
+
end
|
166
|
+
blob = JSON.parse(@api.httpSendMessage(target, text))
|
167
|
+
@hash = blob['data']
|
168
|
+
private_message_channel_ID = @hash['channel_id']
|
169
|
+
#private_message_thread_ID = @hash['thread_id']
|
170
|
+
$files.makedir($tools.ayadn_configuration[:messages_path])
|
171
|
+
puts "Channel ID: ".cyan + private_message_channel_ID.brown + " Message ID: ".cyan + @hash['id'].brown + "\n\n"
|
172
|
+
puts $status.postSent
|
173
|
+
$files.save_channel_id(private_message_channel_ID, target)
|
174
|
+
# save message
|
175
|
+
if $tools.config['files']['auto_save_sent_messages']
|
176
|
+
fileURL = $tools.ayadn_configuration[:messages_path] + "/#{target}-#{@hash['id']}.post"
|
177
|
+
f = File.new(fileURL, "w")
|
178
|
+
f.puts(@hash)
|
179
|
+
f.close
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def ayadnComposeMessageToChannel(target)
|
184
|
+
puts $status.writeMessage
|
185
|
+
begin
|
186
|
+
input_text = STDIN.gets.chomp
|
187
|
+
rescue Exception
|
188
|
+
abort($status.errorMessageNotSent)
|
189
|
+
end
|
190
|
+
real_length = $tools.getMarkdownText(input_text.dup).length
|
191
|
+
if real_length < $tools.ayadn_configuration[:message_max_length]
|
192
|
+
ayadnSendMessageToChannel(target, input_text)
|
193
|
+
else
|
194
|
+
abort($status.errorMessageTooLong(real_length, real_length - $tools.ayadn_configuration[:message_max_length]))
|
195
|
+
end
|
196
|
+
end
|
197
|
+
def ayadnSendMessageToChannel(target, text)
|
198
|
+
abort($status.emptyPost) if (text.empty? || text == nil)
|
199
|
+
puts $status.sendMessage
|
200
|
+
if !target.is_integer?
|
201
|
+
target = $files.load_channel_id(target)
|
202
|
+
end
|
203
|
+
blob = JSON.parse(@api.httpSendMessageToChannel(target, text))
|
204
|
+
@hash = blob['data']
|
205
|
+
private_channel_ID = @hash['channel_id']
|
206
|
+
#private_thread_ID = @hash['thread_id']
|
207
|
+
$files.makedir($tools.ayadn_configuration[:messages_path])
|
208
|
+
puts "Channel ID: ".cyan + private_channel_ID.brown + " Message ID: ".cyan + @hash['id'].brown + "\n\n"
|
209
|
+
puts $status.postSent
|
210
|
+
$files.save_channel_id(private_channel_ID, target)
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
%w{rubygems pstore date open-uri net/http json io/console fileutils yaml pinboard base64}.each do |r|
|
5
|
+
require "#{r}"
|
6
|
+
end
|
7
|
+
|
8
|
+
winPlatforms = ['mswin', 'mingw', 'mingw_18', 'mingw_19', 'mingw_20', 'mingw32']
|
9
|
+
case Gem::Platform.local.os
|
10
|
+
when *winPlatforms
|
11
|
+
require 'win32console'
|
12
|
+
end
|
data/lib/ayadn/skip.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
class AyaDN
|
4
|
+
def ayadn_skip_add(kind, target) #kind: sources,hashtags,mentions
|
5
|
+
puts "Current skipped #{kind}: ".green + $tools.config['skipped']["#{kind}"].join(", ").red + "\n\n"
|
6
|
+
puts "Adding ".green + target.red + " to the skipped #{kind}.".green + "\n\n"
|
7
|
+
$tools.config['skipped']["#{kind}"].each do |in_config|
|
8
|
+
if in_config == target
|
9
|
+
puts target.red + " is already skipped.\n\n".green
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
end
|
13
|
+
$tools.config['skipped']["#{kind}"].push(target)
|
14
|
+
puts "New skipped #{kind}: ".green + $tools.config['skipped']["#{kind}"].join(", ").red + "\n\n"
|
15
|
+
$tools.saveConfig
|
16
|
+
end
|
17
|
+
def ayadn_skip_remove(kind, target)
|
18
|
+
puts "Removing ".green + target.red + " from the skipped #{kind}.".green + "\n\n"
|
19
|
+
$tools.config['skipped']["#{kind}"].each do |in_config|
|
20
|
+
if in_config == target
|
21
|
+
$tools.config['skipped']["#{kind}"].delete(in_config)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
puts "New skipped #{kind}: ".green + $tools.config['skipped']["#{kind}"].join(", ").red + "\n\n"
|
25
|
+
$tools.saveConfig
|
26
|
+
end
|
27
|
+
end
|
data/lib/ayadn/status.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
class AyaDN
|
4
|
+
class ClientStatus
|
5
|
+
def canceled
|
6
|
+
"\nCanceled.\n\n".red
|
7
|
+
end
|
8
|
+
def showList(list, name)
|
9
|
+
if list == "muted"
|
10
|
+
"Your list of muted users:\n".green
|
11
|
+
elsif list == "followings"
|
12
|
+
"List of users ".green + "#{name} ".brown + "is following:\n".green
|
13
|
+
elsif list == "followers"
|
14
|
+
"List of ".green + "#{name}".brown + "'s followers:\n".green
|
15
|
+
end
|
16
|
+
end
|
17
|
+
def getInteractions
|
18
|
+
"\nLoading the ".green + "interactions ".brown + "informations.\n".green
|
19
|
+
end
|
20
|
+
def launchAuthorization(os)
|
21
|
+
if os == "osx"
|
22
|
+
"\nAyaDN opened a browser to authorize via App.net very easily. Just login with your App.net account, then copy the code it will give you, paste it here then press [ENTER].".pink + " Paste authorization code: \n\n".brown
|
23
|
+
else
|
24
|
+
s = "\nPlease open a browser and paste this URL: \n\n".brown
|
25
|
+
s += "https://account.app.net/oauth/authenticate?client_id=hFsCGArAjgJkYBHTHbZnUvzTmL4vaLHL&response_type=token&redirect_uri=http://aya.io/ayadn/auth.html&scope=basic stream write_post follow public_messages messages&include_marker=1"
|
26
|
+
s += "\n\nOn this page, login with your App.net account, then copy the code it will give you, paste it here then press [ENTER].".pink + " Paste authorization code: \n\n".brown
|
27
|
+
end
|
28
|
+
end
|
29
|
+
def authorized
|
30
|
+
"\nThank you for authorizing AyaDN. You won't need to do this anymore.\n\n".green
|
31
|
+
end
|
32
|
+
def noNewPosts
|
33
|
+
"\nNo new posts since your last visit.\n\n".red
|
34
|
+
end
|
35
|
+
def errorEmptyList
|
36
|
+
"\nThe list is empty.\n\n".red
|
37
|
+
end
|
38
|
+
def errorSyntax
|
39
|
+
"\nSyntax error.\n\n".red
|
40
|
+
end
|
41
|
+
def errorNotAuthorized
|
42
|
+
"\nYou haven't authorized AyaDN yet.\n\n".red
|
43
|
+
end
|
44
|
+
def errorNobodyReposted
|
45
|
+
"\nThis post hasn't been reposted by anyone.\n\n".red
|
46
|
+
end
|
47
|
+
def errorNobodyStarred
|
48
|
+
"\nThis post hasn't been starred by anyone.\n\n".red
|
49
|
+
end
|
50
|
+
def errorNoID
|
51
|
+
"\nError -> you must give a post ID to reply to.\n\n".red
|
52
|
+
end
|
53
|
+
def emptyPost
|
54
|
+
"\nError -> there was no text to post.\n\n".red
|
55
|
+
end
|
56
|
+
def errorInfos(arg)
|
57
|
+
"\nError -> ".red + "#{arg}".brown + " isn't a @username or a Post ID\n\n".red
|
58
|
+
end
|
59
|
+
def errorUserID(arg)
|
60
|
+
"\nError -> ".red + "#{arg}".brown + " is not a @username\n\n".red
|
61
|
+
end
|
62
|
+
def errorPostID(arg)
|
63
|
+
"\nError -> ".red + "#{arg}".brown + " is not a Post ID\n\n".red
|
64
|
+
end
|
65
|
+
def errorMessageNotSent
|
66
|
+
"\n\nCanceled. Your message hasn't been sent.\n\n".red
|
67
|
+
end
|
68
|
+
def errorMessageTooLong(realLength, to_remove)
|
69
|
+
"\nError: your message is ".red + "#{realLength} ".brown + "characters long, please remove ".red + "#{to_remove} ".brown + "characters.\n\n".red
|
70
|
+
end
|
71
|
+
def errorPostTooLong(realLength, to_remove)
|
72
|
+
"\nError: your post is ".red + "#{realLength} ".brown + " characters long, please remove ".red + "#{to_remove} ".brown + "characters.\n\n".red
|
73
|
+
end
|
74
|
+
def errorPostNotSent
|
75
|
+
"\n\nCanceled. Your post hasn't been sent.\n\n".red
|
76
|
+
end
|
77
|
+
def errorIsRepost(postID)
|
78
|
+
"\n#{postID} ".brown + " is a repost.\n".red
|
79
|
+
end
|
80
|
+
def errorAlreadyDeleted
|
81
|
+
"\nPost already deleted.\n\n".red
|
82
|
+
end
|
83
|
+
def redirectingToOriginal(postID)
|
84
|
+
"Redirecting to the original post: ".cyan + "#{postID}\n".brown
|
85
|
+
end
|
86
|
+
def fetchingList(list)
|
87
|
+
"\nFetching the \'#{list}\' list. Please wait\n".green
|
88
|
+
end
|
89
|
+
def getUnified
|
90
|
+
"\nLoading the ".green + "unified ".brown + "Stream".green
|
91
|
+
end
|
92
|
+
def getExplore(explore)
|
93
|
+
"\nLoading the ".green + "#{explore}".brown + " Stream".green
|
94
|
+
end
|
95
|
+
def getGlobal
|
96
|
+
"\nLoading the ".green + "global ".brown + "Stream".green
|
97
|
+
end
|
98
|
+
def whoReposted(arg)
|
99
|
+
s = "\nLoading informations on post ".green + "#{arg}".brown + "\n "
|
100
|
+
s += "\nReposted by: \n".cyan
|
101
|
+
end
|
102
|
+
def whoStarred(arg)
|
103
|
+
s = "\nLoading informations on post ".green + "#{arg}".brown + "\n"
|
104
|
+
s += "\nStarred by: \n".cyan
|
105
|
+
end
|
106
|
+
def infosUser(arg)
|
107
|
+
"\nLoading informations on ".green + "#{arg}".brown + "\n"
|
108
|
+
end
|
109
|
+
def infosPost(arg)
|
110
|
+
"\nLoading informations on post ".green + "#{arg}".brown + "\n"
|
111
|
+
end
|
112
|
+
def postsUser(arg)
|
113
|
+
"\nLoading posts of ".green + "#{arg}".brown + "\n"
|
114
|
+
end
|
115
|
+
def mentionsUser(arg)
|
116
|
+
"\nLoading posts mentionning ".green + "#{arg}".brown + "\n"
|
117
|
+
end
|
118
|
+
def starsUser(arg)
|
119
|
+
"\nLoading ".green + "#{arg}".reddish + "'s favorite posts\n".green
|
120
|
+
end
|
121
|
+
def starsPost(arg)
|
122
|
+
"\nLoading users who starred post ".green + "#{arg}".reddish + "\n"
|
123
|
+
end
|
124
|
+
def getHashtags(arg)
|
125
|
+
"\nLoading posts containing ".green + "##{arg}".pink + "\n".green
|
126
|
+
end
|
127
|
+
def sendPost
|
128
|
+
"\nSending post\n".green
|
129
|
+
end
|
130
|
+
def sendMessage
|
131
|
+
"\nSending private Message\n".green
|
132
|
+
end
|
133
|
+
def postSent
|
134
|
+
"Successfully posted\n".green
|
135
|
+
end
|
136
|
+
def postDeleted
|
137
|
+
"\nPost successfully deleted\n".green
|
138
|
+
end
|
139
|
+
def replyingToPost(postID)
|
140
|
+
"\nReplying to post ".cyan + "#{postID}\n".brown
|
141
|
+
end
|
142
|
+
def deletePost(postID)
|
143
|
+
"\nDeleting post ".green + "#{postID}".brown + "\n"
|
144
|
+
end
|
145
|
+
def getPostReplies(arg)
|
146
|
+
"\nLoading the conversation around post ".green + "#{arg}".brown + "\n"
|
147
|
+
end
|
148
|
+
def writePost
|
149
|
+
s = "\n#{$tools.ayadn_configuration[:post_max_length]} characters max, validate with [Enter] or cancel with [CTRL+C].\n".green
|
150
|
+
s += "\nType your text: ".cyan
|
151
|
+
end
|
152
|
+
def writeMessage
|
153
|
+
s = "\n#{$tools.ayadn_configuration[:message_max_length]} characters max, validate with [Enter] or cancel with [CTRL+C].\n".green
|
154
|
+
s += "\nType your text: ".cyan + "\n\n"
|
155
|
+
end
|
156
|
+
def writeReply(arg)
|
157
|
+
"\nLoading informations of post " + "#{arg}".brown + "\n"
|
158
|
+
end
|
159
|
+
def savingFile(name, path, file)
|
160
|
+
"\nSaving ".green + "#{name} ".brown + "in ".green + "#{path}#{file}".magenta
|
161
|
+
end
|
162
|
+
def stopped
|
163
|
+
"\n\nStopped.\n\n".red
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
data/lib/ayadn/tools.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
require 'yaml'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'pinboard'
|
6
|
+
|
7
|
+
class AyaDN
|
8
|
+
class Tools
|
9
|
+
def initialize
|
10
|
+
@default_ayadn_data_path = Dir.home + "/ayadn/data"
|
11
|
+
@installed_config_path = "#{@default_ayadn_data_path}/config.yml"
|
12
|
+
@configFileContents = loadConfig
|
13
|
+
identityPrefix = @configFileContents['identity']['prefix']
|
14
|
+
ayadn_data_path = Dir.home + @configFileContents['files']['ayadnfiles']
|
15
|
+
@ayadn_configuration = {
|
16
|
+
data_path: ayadn_data_path,
|
17
|
+
posts_path: ayadn_data_path + "/#{identityPrefix}/posts",
|
18
|
+
lists_path: ayadn_data_path + "/#{identityPrefix}/lists",
|
19
|
+
files_path: ayadn_data_path + "/#{identityPrefix}/files",
|
20
|
+
db_path: ayadn_data_path + "/#{identityPrefix}/db",
|
21
|
+
last_page_id_path: ayadn_data_path + "/#{identityPrefix}/.pagination",
|
22
|
+
messages_path: ayadn_data_path + "/#{identityPrefix}/messages",
|
23
|
+
authorization_path: ayadn_data_path + "/#{identityPrefix}/.auth",
|
24
|
+
api_config_path: ayadn_data_path + "/#{identityPrefix}/.api",
|
25
|
+
progress_indicator: false,
|
26
|
+
platform: RbConfig::CONFIG['host_os']
|
27
|
+
}
|
28
|
+
end
|
29
|
+
def loadConfig
|
30
|
+
if File.exists?(@installed_config_path)
|
31
|
+
YAML::load_file(@installed_config_path)
|
32
|
+
elsif File.exists?('./config.yml')
|
33
|
+
YAML::load_file('./config.yml')
|
34
|
+
else
|
35
|
+
{
|
36
|
+
"counts" => {
|
37
|
+
"global" => 100,
|
38
|
+
"unified" => 100,
|
39
|
+
"checkins" => 100,
|
40
|
+
"explore" => 100,
|
41
|
+
"mentions" => 100,
|
42
|
+
"starred" => 100,
|
43
|
+
"posts" => 100,
|
44
|
+
"search" => 200
|
45
|
+
},
|
46
|
+
"timeline" => {
|
47
|
+
"downside" => true,
|
48
|
+
"directed" => true,
|
49
|
+
"streamback" => 30,
|
50
|
+
"countdown_1" => 5,
|
51
|
+
"countdown_2" => 15,
|
52
|
+
"show_client" => false,
|
53
|
+
"show_symbols" => true,
|
54
|
+
"show_reposters" => false
|
55
|
+
},
|
56
|
+
"files" => {
|
57
|
+
"ayadnfiles" => "/ayadn/data",
|
58
|
+
"auto_save_sent_messages" => false,
|
59
|
+
"auto_save_sent_posts" => false
|
60
|
+
},
|
61
|
+
"identity" => { "prefix" => "me" },
|
62
|
+
"skipped" => {
|
63
|
+
"sources" => [],
|
64
|
+
"hashtags" => [],
|
65
|
+
"mentions" => []
|
66
|
+
},
|
67
|
+
"pinboard" => {
|
68
|
+
"username" => "",
|
69
|
+
"password" => ""
|
70
|
+
}
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
def saveConfig
|
75
|
+
if File.exists?(@installed_config_path)
|
76
|
+
File.open(@installed_config_path, 'w') {|f| f.write config.to_yaml }
|
77
|
+
puts "\nDone!\n\n".green
|
78
|
+
else
|
79
|
+
File.open('./config.yml', 'w') {|f| f.write config.to_yaml }
|
80
|
+
puts "\nDone!\n\n".green
|
81
|
+
end
|
82
|
+
end
|
83
|
+
def installConfig
|
84
|
+
if File.exists?(@installed_config_path)
|
85
|
+
puts "\nInstalled config file already exists. Replace with the new one? (N/y) ".red
|
86
|
+
if STDIN.getch == ("y" || "Y")
|
87
|
+
copyConfigFromMaster
|
88
|
+
else
|
89
|
+
abort("\nCanceled.\n\n".red)
|
90
|
+
end
|
91
|
+
else
|
92
|
+
copyConfigFromMaster
|
93
|
+
end
|
94
|
+
end
|
95
|
+
def copyConfigFromMaster
|
96
|
+
FileUtils.cp('./config.yml', @installed_config_path)
|
97
|
+
puts "\nDone.\n\n".green
|
98
|
+
end
|
99
|
+
def config
|
100
|
+
@configFileContents
|
101
|
+
end
|
102
|
+
def ayadn_configuration
|
103
|
+
@ayadn_configuration
|
104
|
+
end
|
105
|
+
def winplatforms
|
106
|
+
/mswin|mingw|mingw32|cygwin/
|
107
|
+
end
|
108
|
+
def colorize(contentText)
|
109
|
+
content = Array.new
|
110
|
+
for word in contentText.split(" ") do
|
111
|
+
if word =~ /#\w+/
|
112
|
+
content.push(word.gsub(/#([A-Za-z0-9_]{1,255})(?![\w+])/, '#\1'.pink))
|
113
|
+
#content.push(removeEndCharIfSpecial(word, "pink"))
|
114
|
+
elsif word =~ /@\w+/
|
115
|
+
content.push(word.gsub(/@([A-Za-z0-9_]{1,20})(?![\w+])/, '@\1'.red))
|
116
|
+
#content.push(removeEndCharIfSpecial(word, "red"))
|
117
|
+
#elsif word =~ /^http/ or word =~ /^photos.app.net/ or word =~ /^files.app.net/ or word =~ /^chimp.li/ or word =~ /^bli.ms/
|
118
|
+
#content.push(word.magenta)
|
119
|
+
else
|
120
|
+
content.push(word)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
content.join(" ")
|
124
|
+
end
|
125
|
+
def removeEndCharIfSpecial(word, color)
|
126
|
+
word_array = word.chars.to_a
|
127
|
+
last_char = word_array.last
|
128
|
+
if last_char =~ /[.,:;?!-'`&"()\/]/
|
129
|
+
word_array.pop
|
130
|
+
if color == "red"
|
131
|
+
word_colored = word_array.join("").red
|
132
|
+
elsif color == "pink"
|
133
|
+
word_colored = word_array.join("").pink
|
134
|
+
end
|
135
|
+
word_colored.chars.to_a.push(last_char).join("")
|
136
|
+
else
|
137
|
+
if color == "red"
|
138
|
+
word.red
|
139
|
+
elsif color == "pink"
|
140
|
+
word.pink
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def getMarkdownText(str)
|
146
|
+
str.gsub %r{
|
147
|
+
\[ # Literal opening bracket
|
148
|
+
( # Capture what we find in here
|
149
|
+
[^\]]+ # One or more characters other than close bracket
|
150
|
+
) # Stop capturing
|
151
|
+
\] # Literal closing bracket
|
152
|
+
\( # Literal opening parenthesis
|
153
|
+
( # Capture what we find in here
|
154
|
+
[^)]+ # One or more characters other than close parenthesis
|
155
|
+
) # Stop capturing
|
156
|
+
\) # Literal closing parenthesis
|
157
|
+
}x, '\1'
|
158
|
+
end
|
159
|
+
def withoutSquareBraces(str)
|
160
|
+
str.gsub %r{
|
161
|
+
\[ # Literal opening bracket
|
162
|
+
( # Capture what we find in here
|
163
|
+
[^\]]+ # One or more characters other than close bracket
|
164
|
+
) # Stop capturing
|
165
|
+
\] # Literal closing bracket
|
166
|
+
}x, ''
|
167
|
+
end
|
168
|
+
def countdown(value)
|
169
|
+
value.downto(1) do |i|
|
170
|
+
print "\r#{sprintf("%02d", i)} sec... QUIT WITH [CTRL+C]".cyan
|
171
|
+
sleep 1
|
172
|
+
end
|
173
|
+
end
|
174
|
+
def startBrowser(url)
|
175
|
+
Process.detach(Process.spawn("sleep 1; open '#{url}'"))
|
176
|
+
end
|
177
|
+
def meta(meta)
|
178
|
+
case meta['code']
|
179
|
+
when 200
|
180
|
+
puts "\nDone!\n".green
|
181
|
+
when 301,302
|
182
|
+
puts "\nRedirected.\n\n".red
|
183
|
+
puts "#{meta.inspect}\n".red
|
184
|
+
when 404
|
185
|
+
puts "Does not exist (or has been deleted).\n\n".red
|
186
|
+
exit
|
187
|
+
else
|
188
|
+
abort("\nERROR: #{meta.to_s}\n".red)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
def checkHTTPResp(resp)
|
192
|
+
case resp.code
|
193
|
+
when !200
|
194
|
+
abort("\nERROR: does not exist (or has been deleted) => #{resp.code} #{resp.body}\n".red)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
def saveToPinboard(post_id, pin_username, pin_password, link, tags, post_text, user_name)
|
198
|
+
tags += ",ADN"
|
199
|
+
post_text += " http://alpha.app.net/#{user_name}/post/#{post_id}"
|
200
|
+
pinboard = Pinboard::Client.new(:username => pin_username, :password => pin_password)
|
201
|
+
pinboard.add(:url => link, :tags => tags, :extended => post_text, :description => link)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|