tit 2.0.4 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/ChangeLog.markdown +6 -0
  2. data/VERSION.yml +2 -2
  3. data/bin/tit +15 -15
  4. data/lib/tit.rb +56 -25
  5. data/tit.gemspec +1 -1
  6. 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
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 2
3
- :minor: 0
4
- :patch: 4
3
+ :minor: 1
4
+ :patch: 0
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 [USERNAME]",
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("-t", "--tweet [STATUS]", "Update status (required when using -G)") do |status|
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? and not message.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]{0,7}$/i, expanded)
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, 0, 4]
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: 10}, rc)
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
- #puts @access_token.get(api_endpoint).body
183
- Nokogiri.XML(@access_token.get(api_endpoint).body).xpath("//status").map do |xml|
184
- {
185
- :username => xml.at_xpath("./user/name").content,
186
- :userid => xml.at_xpath("./user/screen_name").content,
187
- :text => xml.xpath("./text").map do |n|
188
- txt = coder.decode(n.content)
189
- if not xml.xpath("./entities/urls").nil?
190
- xml.xpath("./entities/urls/url").map do |url|
191
- txt.replace_with_expanded_url! (url.xpath("./expanded_url").map { |expurl| expurl.content })
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
- txt
195
- end,
196
- :timestamp => Time.parse(xml.at_xpath("./created_at").content),
197
- :id => xml.at_xpath("./id").content.to_i,
198
- :geo => xml.at_xpath("./geo").instance_eval do
199
- unless children.empty?
200
- n, e = children[1].content.split.map { |s| s.to_f }
201
- "#{n.abs}#{n >= 0 ? 'N' : 'S'} #{e.abs}#{e >= 0 ? 'E' : 'W'}"
202
- end
203
- end
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
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{tit}
8
- s.version = "2.0.4"
8
+ s.version = "2.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Leif Walsh", "Parker Moore"]
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: tit
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 2.0.4
5
+ version: 2.1.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Leif Walsh