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.
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