tit 2.0.4 → 2.1.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.
- data/ChangeLog.markdown +6 -0
- data/VERSION.yml +2 -2
- data/bin/tit +15 -15
- data/lib/tit.rb +56 -25
- data/tit.gemspec +1 -1
- metadata +1 -1
data/ChangeLog.markdown
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# tit 2.1.0 2011-09-10
|
2
|
+
|
3
|
+
* got direct messaging working -- requires reauthorization
|
4
|
+
* notifies user of need to reauthorize the app for dm permissions
|
5
|
+
* can now handle missing tweet, whereas it was just throwing a Ruby error before
|
6
|
+
|
1
7
|
# tit 2.0.4 2011-09-09
|
2
8
|
|
3
9
|
* fixes issue with replacing t.co urls, where the ridiculous set of chars at the end remained
|
data/VERSION.yml
CHANGED
data/bin/tit
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'tit'
|
4
|
-
|
5
4
|
require 'optparse'
|
6
5
|
|
7
6
|
def main
|
@@ -35,33 +34,34 @@ def main
|
|
35
34
|
options[:action] = :mentions
|
36
35
|
unchanged = false
|
37
36
|
end
|
38
|
-
opts.on("-u", "--user
|
37
|
+
opts.on("-u", "--user USERNAME",
|
39
38
|
"Show a particular user's timeline") do |user|
|
40
39
|
unchanged = false
|
41
40
|
options[:action] = :user_timeline
|
42
41
|
options[:payload] ||= {}
|
43
42
|
options[:payload]["user"] = user
|
44
43
|
end
|
45
|
-
opts.on("-
|
46
|
-
unchanged = false
|
47
|
-
options[:action] = :update
|
48
|
-
options[:payload] ||= {}
|
49
|
-
options[:payload]["status"] = status
|
50
|
-
end
|
51
|
-
opts.on("-d", "--dm [USERNAME] [MESSAGE]", "Read direct messages. Send a direct message if USERNAME and MESSAGE are set") do |user, message|
|
52
|
-
"Tit does not presently have access to Twitter's Direct Messaging functionality. This will be rectified soon.".wrapped(@cols-2).each do |l|
|
53
|
-
puts " #{l}"
|
54
|
-
end
|
44
|
+
opts.on("-d", "--dm [USERNAME]", "Read direct messages. Send a direct message if USERNAME is set and -t or --tweet accompanies it") do |user|
|
55
45
|
unchanged = false
|
56
|
-
if not user.nil?
|
46
|
+
if not user.nil?
|
57
47
|
options[:action] = :new_direct_message
|
58
48
|
options[:payload] ||= {}
|
59
49
|
options[:payload]["screen_name"] = user
|
60
|
-
options[:payload]["text"] = message
|
61
50
|
else
|
51
|
+
puts "Displaying dms."
|
62
52
|
options[:action] = :direct_messages
|
63
53
|
end
|
64
54
|
end
|
55
|
+
opts.on("-t", "--tweet [STATUS]", "Update status (required when using -G)") do |status|
|
56
|
+
unchanged = false
|
57
|
+
if not options[:action].nil? and options[:action].eql?(:new_direct_message)
|
58
|
+
options[:payload]["text"] = status
|
59
|
+
else
|
60
|
+
options[:action] = :update
|
61
|
+
options[:payload] ||= {}
|
62
|
+
options[:payload]["status"] = status
|
63
|
+
end
|
64
|
+
end
|
65
65
|
opts.on("--pin PIN", ("Set auth pin if this is your first time playing " +
|
66
66
|
"with this tit")) do |pin|
|
67
67
|
unchanged = false
|
@@ -156,7 +156,7 @@ def main
|
|
156
156
|
not options[:notify].nil?)
|
157
157
|
end
|
158
158
|
if options[:action] == :update
|
159
|
-
tit.abort("need status message") unless options[:payload].include? "status"
|
159
|
+
tit.abort("need status message") unless options[:payload].include? "status" and not options[:payload]["status"].nil?
|
160
160
|
tit.abort("can't repeatedly update status") unless options[:wait].nil?
|
161
161
|
tit.abort("can't notify when updating status") unless options[:notify].nil?
|
162
162
|
end
|
data/lib/tit.rb
CHANGED
@@ -26,7 +26,7 @@ class String
|
|
26
26
|
replace(replace_with_expanded_url(expanded))
|
27
27
|
end
|
28
28
|
def replace_with_expanded_url(expanded)
|
29
|
-
replace_uris(/http:\/\/t.co\/[a-zA-Z0-9]{
|
29
|
+
replace_uris(/http:\/\/t.co\/[a-zA-Z0-9]{1,8}$/i, expanded)
|
30
30
|
end
|
31
31
|
def replace_uris(old, newt)
|
32
32
|
split(URI_REGEX).collect do |s|
|
@@ -91,7 +91,7 @@ end
|
|
91
91
|
Why are you reading the documentation, you cunt?
|
92
92
|
=end
|
93
93
|
class Tit
|
94
|
-
VERSION = [2,
|
94
|
+
VERSION = [2, 1, 0]
|
95
95
|
|
96
96
|
RCFILE = File.join(ENV["HOME"], ".titrc")
|
97
97
|
RTFILE = File.join(ENV["HOME"], ".titrt")
|
@@ -136,7 +136,7 @@ class Tit
|
|
136
136
|
YAML.dump(request_token.params, rt)
|
137
137
|
end
|
138
138
|
File.open(RCFILE, "w") do |rc|
|
139
|
-
YAML.dump({count
|
139
|
+
YAML.dump({:count => 10}, rc)
|
140
140
|
end
|
141
141
|
tuts "Please visit '#{request_token.authorize_url}'."
|
142
142
|
tuts "When you finish, provide your pin with `tit --pin PIN'"
|
@@ -171,6 +171,7 @@ class Tit
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def get_tits(action, payload)
|
174
|
+
# Build the API Endpoint
|
174
175
|
api_endpoint = URLS[action]
|
175
176
|
if(action == :user_timeline and not payload.nil?)
|
176
177
|
api_endpoint.concat("?screen_name=".concat(payload['user'])).concat("&count=#{@prefs[:count]}")
|
@@ -178,30 +179,53 @@ class Tit
|
|
178
179
|
api_endpoint.concat("?count=#{@prefs[:count]}")
|
179
180
|
end
|
180
181
|
api_endpoint.concat("&include_entities=true")
|
182
|
+
|
181
183
|
coder = HTMLEntities.new
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
184
|
+
|
185
|
+
# Parse XML
|
186
|
+
xmlbody = @access_token.get(api_endpoint).body
|
187
|
+
# Errors
|
188
|
+
Nokogiri.XML(xmlbody).xpath("//errors").map do |xml|
|
189
|
+
if xml.at_xpath("./error").content == "This application is not allowed to access or delete your direct messages"
|
190
|
+
abort("Your OAuth key is not authorized for direct messaging.\nDelete #{TITAT} and run tit without arguments to reauthorize.")
|
191
|
+
end
|
192
|
+
end
|
193
|
+
# no errors - get tits
|
194
|
+
if action != :direct_messages
|
195
|
+
Nokogiri.XML(xmlbody).xpath("//status").map do |xml|
|
196
|
+
{
|
197
|
+
:username => xml.at_xpath("./user/name").content,
|
198
|
+
:userid => xml.at_xpath("./user/screen_name").content,
|
199
|
+
:text => xml.xpath("./text").map do |n|
|
200
|
+
txt = coder.decode(n.content)
|
201
|
+
if not xml.xpath("./entities/urls").nil?
|
202
|
+
xml.xpath("./entities/urls/url").map do |url|
|
203
|
+
txt.replace_with_expanded_url!(url.xpath("./expanded_url").map { |expurl| expurl.content })
|
204
|
+
end
|
205
|
+
end
|
206
|
+
txt
|
207
|
+
end,
|
208
|
+
:timestamp => Time.parse(xml.at_xpath("./created_at").content),
|
209
|
+
:id => xml.at_xpath("./id").content.to_i,
|
210
|
+
:geo => xml.at_xpath("./geo").instance_eval do
|
211
|
+
unless children.empty?
|
212
|
+
n, e = children[1].content.split.map { |s| s.to_f }
|
213
|
+
"#{n.abs}#{n >= 0 ? 'N' : 'S'} #{e.abs}#{e >= 0 ? 'E' : 'W'}"
|
192
214
|
end
|
193
215
|
end
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
216
|
+
}
|
217
|
+
end
|
218
|
+
else
|
219
|
+
# get the dms
|
220
|
+
Nokogiri.XML(xmlbody).xpath("//direct_message").map do |xml|
|
221
|
+
{
|
222
|
+
:username => xml.at_xpath("./sender/name").content,
|
223
|
+
:userid => xml.at_xpath("./sender_screen_name").content,
|
224
|
+
:text => xml.xpath("./text").map {|n| coder.decode(n.content)},
|
225
|
+
:timestamp => Time.parse(xml.at_xpath("./created_at").content),
|
226
|
+
:id => xml.at_xpath("./id").content.to_i,
|
227
|
+
}
|
228
|
+
end
|
205
229
|
end
|
206
230
|
end
|
207
231
|
|
@@ -231,7 +255,14 @@ class Tit
|
|
231
255
|
exit(-1)
|
232
256
|
end
|
233
257
|
|
234
|
-
@access_token.post(URLS[:new_direct_message], payload)
|
258
|
+
response = @access_token.post(URLS[:new_direct_message], payload)
|
259
|
+
|
260
|
+
# Check the response for errors
|
261
|
+
Nokogiri.XML(response).xpath("//hash").map do |xml|
|
262
|
+
if not xml.at_xpath("./error").content.eql?("")
|
263
|
+
abort("you cannot send a dm to someone who doesn't follow you")
|
264
|
+
end
|
265
|
+
end
|
235
266
|
end
|
236
267
|
|
237
268
|
def show_tit(status)
|
data/tit.gemspec
CHANGED