webco-tuiter 0.0.1 → 0.0.2

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/AUTHORS CHANGED
@@ -7,8 +7,11 @@ Both projects were latter adopted by WebCo Internet (http://webcointernet.com).
7
7
 
8
8
  The authors and contributors of Tuiter are:
9
9
 
10
- * Manoel Lemos (manoel@lemos.net)
11
- * Luiz Rocha (lsdr@lsdr.net)
12
- * Luis Cipriani (lfcipriani@talleye.com)
13
- * Lucas Húngaro (lucashungaro@gmail.com)
10
+ * Manoel Lemos (manoel@lemos.net) - initial work
11
+ * Celestino Gomes (tinorj@gmail.com)
12
+ * Leandro Silva (leandrodoze@gmail.com)
13
+ * Lucas Fais (lfais@webcointernet.com)
14
+ * Lucas Húngaro (lucashungaro@gmail.com)
15
+ * Luis Cipriani (lfcipriani@talleye.com)
16
+ * Luiz Rocha (lsdr@lsdr.net)
14
17
 
data/README.rdoc ADDED
@@ -0,0 +1,44 @@
1
+ = Tuiter
2
+
3
+ Tuiter was design and developed by {Manoel Lemos}[http://manoellemos.com] to
4
+ provide access to the Twitter API. It was developed for the experimental
5
+ project called {Tuitersfera Brasil}[http://tuitersfera.com.br], an application
6
+ to monitor the Twitter usage in Brazil.
7
+
8
+ Both Tuiter and Tuitersfera were adopted, further developed and maintained by
9
+ {Webco Internet}[http://webcointernet.com].
10
+
11
+ == Instalation
12
+
13
+ Tuiter is avaliable as a gem on
14
+ {Rubyforge}[http://rubyforge.org/projects/tuiter/], so you can easily install
15
+ using rubygems:
16
+
17
+ gem install tuiter
18
+
19
+ Although it is recommended to use the gem published on Rubyforge, tuiter is also
20
+ avaliable at Github. This might be useful if you want to experiment with forks
21
+ or live on the bleeding edge.
22
+
23
+ To install the Github version, simply run on a console:
24
+
25
+ gem install webco-tuiter --source=http://gems.github.com
26
+
27
+ If you already have Github gem repository on you gem source, you can leave the
28
+ source part out.
29
+
30
+ == Basic Usage
31
+
32
+ require 'tuiter'
33
+ client = Tuiter::Client.new(:username => '<twitter_login>', :password => '<twitter_pwd>')
34
+
35
+ client.update('Hey Ho, Twitters!')
36
+
37
+ There are (or at least we want to add :-) another examples in the examples/
38
+ folder.
39
+
40
+ == Roadmap and TO-DO list
41
+
42
+ Check out the library roadmap and to-do list
43
+ {in the project wiki}[http://wiki.github.com/webco/tuiter]
44
+
data/Rakefile CHANGED
@@ -4,6 +4,10 @@ require "rake"
4
4
  require "rake/testtask"
5
5
  require "rake/rdoctask"
6
6
 
7
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].each do |req|
8
+ load req
9
+ end
10
+
7
11
  require "lib/tuiter/version"
8
12
 
9
13
  desc "Run test suite"
@@ -37,7 +41,7 @@ task "list" do
37
41
  end
38
42
 
39
43
  def spec_files
40
- %w( Rakefile AUTHORS CHANGELOG LICENSE README.markdown ) + Dir["{lib,examples,test}/**/*"]
44
+ %w( Rakefile AUTHORS CHANGELOG LICENSE README.rdoc ) + Dir["{lib,examples,test}/**/*"]
41
45
  end
42
46
 
43
47
  def spec
@@ -50,7 +54,10 @@ def spec
50
54
  s.homepage = "http://github.com/webco/tuiter"
51
55
  s.description = "Yet another Twitter API wrapper library in Ruby"
52
56
  s.has_rdoc = false
57
+ # s.extra_rdoc_files = ["LICENSE", "README.rdoc", "CHANGELOG"]
58
+ # s.rdoc_options = ["--inline-source", "--charset=utf-8"]
53
59
  s.files = spec_files
60
+ s.rubyforge_project = "tuiter"
54
61
 
55
62
  # Dependencies
56
63
  s.add_dependency "json", ">= 1.1"
@@ -61,14 +68,14 @@ desc "Creates the gemspec"
61
68
  task "gemify" do
62
69
  skip_fields = %w(new_platform original_platform specification_version loaded required_ruby_version rubygems_version platform bindir )
63
70
 
64
- result = "# WARNING : RAKE AUTO-GENERATED FILE. DO NOT MANUALLY EDIT!\n"
65
- result << "# RUN : 'rake gem:update_gemspec'\n\n"
71
+ result = "# WARNING: RAKE AUTO-GENERATED FILE. DO NOT MANUALLY EDIT!\n"
72
+ result << "# RUN: 'rake gemify'\n\n"
66
73
  result << "Gem::Specification.new do |s|\n"
67
74
 
68
75
  spec.instance_variables.each do |ivar|
69
76
  value = spec.instance_variable_get(ivar)
70
77
  name = ivar.split("@").last
71
- value = Time.now if name == "date"
78
+ value = Date.today.to_s if name == "date"
72
79
 
73
80
  next if skip_fields.include?(name) || value.nil? || value == "" || (value.respond_to?(:empty?) && value.empty?)
74
81
  if name == "dependencies"
@@ -76,6 +83,8 @@ task "gemify" do
76
83
  dep, *ver = d.to_s.split(" ")
77
84
  result << " s.add_dependency #{dep.inspect}, #{ver.join(" ").inspect.gsub(/[()]/, "").gsub(", runtime", "")}\n"
78
85
  end
86
+ elsif name == "required_rubygems_version"
87
+ result << " s.required_rubygems_version = Gem::Requirement.new(\">= 0\") if s.respond_to? :required_rubygems_version=\n"
79
88
  else
80
89
  case value
81
90
  when Array
@@ -91,7 +100,7 @@ task "gemify" do
91
100
  result << " s.#{name} = #{value}\n"
92
101
  end
93
102
  end
94
-
103
+
95
104
  result << "end"
96
105
  File.open(File.join(File.dirname(__FILE__), "#{spec.name}.gemspec"), "w"){|f| f << result}
97
106
  end
@@ -106,5 +115,18 @@ task "install" => "build" do
106
115
  sh "gem install #{spec.name}-#{spec.version}.gem && rm -r *.gem *.gemspec"
107
116
  end
108
117
 
118
+ desc "Publish the gem to Rubyforge"
119
+ task "publish" => "build" do
120
+ require 'rubyforge'
121
+ rubyforge_config_path = File.expand_path(File.join('~', '.rubyforge'))
122
+ user_config = YAML::load(File.open(rubyforge_config_path + '/user-config.yml'))
123
+ auto_config = YAML::load(File.open(rubyforge_config_path + '/auto-config.yml'))
124
+
125
+ @rubyforge = RubyForge::Client.new(user_config, auto_config)
126
+
127
+ @rubyforge.login
128
+ @rubyforge.add_release('tuiter', 'tuiter', "#{spec.version}", "#{spec.name}-#{spec.version}.gem")
129
+ end
130
+
109
131
  task :default => ["test"]
110
132
 
data/lib/tuiter/client.rb CHANGED
@@ -8,6 +8,7 @@ module Tuiter
8
8
  @logger = options[:logger] || Logger.new('tuiter.log')
9
9
  @username = options[:username]
10
10
  @password = options[:password]
11
+ @use_proxy = setup_a_proxy?
11
12
  log("initialize()")
12
13
  end
13
14
 
@@ -17,7 +18,7 @@ module Tuiter
17
18
  req = Net::HTTP::Post.new(url.path)
18
19
  req.basic_auth @username, @password
19
20
  req.set_form_data({'status'=>status, 'in_reply_to_status_id'=>in_reply_to_status_id })
20
- res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
21
+ res = new_http_for(url).start {|http| http.request(req) }
21
22
  case res
22
23
  when Net::HTTPSuccess, Net::HTTPRedirection
23
24
  log("update() success: OK")
@@ -34,7 +35,7 @@ module Tuiter
34
35
  req = Net::HTTP::Post.new(url.path)
35
36
  req.basic_auth @username, @password
36
37
  req.set_form_data({'user'=>user, 'text'=>text })
37
- res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
38
+ res = new_http_for(url).start {|http| http.request(req) }
38
39
  case res
39
40
  when Net::HTTPSuccess, Net::HTTPRedirection
40
41
  log("direct_new() success: OK")
@@ -44,14 +45,26 @@ module Tuiter
44
45
  res.error!
45
46
  end
46
47
  end
47
-
48
+
49
+ def direct_list(options = {})
50
+ url = 'http://twitter.com/direct_messages.json'
51
+ params = parse_options(options) || ""
52
+
53
+ if res = request(url+params)
54
+ data = JSON.parse(res)
55
+ return data.map { |d| DirectMessage.new(d) }
56
+ else
57
+ return nil
58
+ end
59
+ end
60
+
48
61
  def friendship_new(user, follow = nil)
49
62
  log("friendship_new() following: #{user}")
50
63
  url = URI.parse("http://twitter.com/friendships/create/#{user}.json")
51
64
  req = Net::HTTP::Post.new(url.path)
52
65
  req.basic_auth @username, @password
53
66
  req.set_form_data({'follow'=>"true"}) if follow
54
- res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
67
+ res = new_http_for(url).start {|http| http.request(req) }
55
68
  case res
56
69
  when Net::HTTPSuccess, Net::HTTPRedirection
57
70
  log("friendship_new() success: OK")
@@ -64,7 +77,7 @@ module Tuiter
64
77
 
65
78
  def verify_credentials?
66
79
  if res = request("http://twitter.com/account/verify_credentials.json")
67
- return Tuiter::UserExtended.new(JSON.parse(res))
80
+ return UserExtended.new(JSON.parse(res))
68
81
  else
69
82
  return nil
70
83
  end
@@ -107,7 +120,7 @@ module Tuiter
107
120
  end
108
121
  if res = request(query+params)
109
122
  data = JSON.parse(res)
110
- return data.map { |d| Tuiter::Status.new(d) }
123
+ return data.map { |d| Status.new(d) }
111
124
  else
112
125
  return nil
113
126
  end
@@ -115,7 +128,7 @@ module Tuiter
115
128
 
116
129
  def get_client
117
130
  if res = request("http://twitter.com/users/show/#{@username}.json")
118
- return Tuiter::UserExtended.new(JSON.parse(res))
131
+ return UserExtended.new(JSON.parse(res))
119
132
  else
120
133
  return nil
121
134
  end
@@ -123,7 +136,7 @@ module Tuiter
123
136
 
124
137
  def get_user(id)
125
138
  if res = request("http://twitter.com/users/show/#{id}.json")
126
- return Tuiter::UserExtended.new(JSON.parse(res))
139
+ return UserExtended.new(JSON.parse(res))
127
140
  else
128
141
  return nil
129
142
  end
@@ -131,7 +144,7 @@ module Tuiter
131
144
 
132
145
  def get_status(id)
133
146
  if res = request("http://twitter.com/statuses/show/#{id}.json")
134
- return Tuiter::Status.new(JSON.parse(res))
147
+ return Status.new(JSON.parse(res))
135
148
  else
136
149
  return nil
137
150
  end
@@ -139,7 +152,7 @@ module Tuiter
139
152
 
140
153
  def rate_limit
141
154
  if res = request("http://twitter.com/account/rate_limit_status.json")
142
- return Tuiter::RateLimit.new(JSON.parse(res))
155
+ return RateLimit.new(JSON.parse(res))
143
156
  else
144
157
  return nil
145
158
  end
@@ -177,7 +190,49 @@ module Tuiter
177
190
  rescue Exception => e
178
191
  log("request() error: #{e.message} in #{e.backtrace.first.to_s}")
179
192
  return nil
180
- end
193
+ end
194
+
195
+ def parse_options(options)
196
+ if options[:since]
197
+ params = "?since=#{options[:since]}"
198
+ elsif options[:since_id]
199
+ params = "?since_id=#{options[:since_id]}"
200
+ else
201
+ params = ""
202
+ end
203
+
204
+ if options[:page]
205
+ if params == ""
206
+ params = "?page=#{options[:page]}"
207
+ else
208
+ params = params + "&" + "page=#{options[:page]}"
209
+ end
210
+ end
211
+
212
+ return params
213
+ end
214
+
215
+ def setup_a_proxy?
216
+ http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY'] || nil
217
+
218
+ if http_proxy
219
+ proxy = URI.parse(http_proxy)
220
+
221
+ @proxy_host = proxy.host
222
+ @proxy_port = proxy.port
223
+ @proxy_user, @proxy_pass = proxy.userinfo.split(/:/) if proxy.userinfo
224
+ end
225
+
226
+ http_proxy != nil
227
+ end
228
+
229
+ def new_http_for(url)
230
+ if @use_proxy
231
+ http = Net::HTTP.new(url.host, url.port, @proxy_host, @proxy_port, @proxy_user, @proxy_pass)
232
+ else
233
+ http = Net::HTTP.new(url.host, url.port)
234
+ end
235
+ end
181
236
 
182
237
  def log(message)
183
238
  @logger.info "[Tuiter:#{@pid}] #{Time.now.to_s} : #{message}"
@@ -0,0 +1,44 @@
1
+ module Tuiter
2
+
3
+ class DirectMessageBasic
4
+ attr_accessor :id
5
+ attr_accessor :text
6
+ attr_accessor :created_at
7
+ attr_accessor :sender_id
8
+ attr_accessor :sender_screen_name
9
+ attr_accessor :recipient_id
10
+ attr_accessor :recipient_screen_name
11
+
12
+ def initialize(data = nil)
13
+ unless data.nil?
14
+ @id = data['id']
15
+ @text = data['text']
16
+ @created_at = (data['created_at'] ? DateTime.parse(data['created_at']) : DateTime.now)
17
+ @sender_id = data['sender_id']
18
+ @sender_screen_name = data['sender_screen_name']
19
+ @recipient_id = data['recipient_id']
20
+ @recipient_screen_name = data['recipient_screen_name']
21
+ else
22
+ @created_at = DateTime.now
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+
29
+ class DirectMessage < DirectMessageBasic
30
+ attr_accessor :sender
31
+ attr_accessor :recipient
32
+
33
+ def initialize(data = nil)
34
+ unless data.nil?
35
+ super(data)
36
+ @sender = UserBasic.new(data['sender'])
37
+ @recipient = UserBasic.new(data['recipient'])
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
@@ -13,7 +13,7 @@ module Tuiter
13
13
 
14
14
  def initialize(data = nil)
15
15
  unless data.nil?
16
- @created_at = Time.parse(data["created_at"])
16
+ @created_at = (data["created_at"] ? DateTime.parse(data["created_at"]) : DateTime.now)
17
17
  @id = data["id"]
18
18
  @text = data["text"]
19
19
  @source = data["source"]
@@ -22,6 +22,8 @@ module Tuiter
22
22
  @in_reply_to_user_id = data["in_reply_to_user_id"]
23
23
  @favorited = data["favorited"]
24
24
  @in_reply_to_screen_name = data["in_reply_to_screen_name"]
25
+ else
26
+ @created_at = DateTime.now
25
27
  end
26
28
  end
27
29
 
@@ -34,7 +36,7 @@ module Tuiter
34
36
  def initialize(data=nil)
35
37
  unless data.nil?
36
38
  super(data)
37
- @user = Tuiter::UserBasic.new(data["user"])
39
+ @user = UserBasic.new(data["user"])
38
40
  end
39
41
  end
40
42
 
@@ -53,7 +53,7 @@ module Tuiter
53
53
  @profile_sidebar_fill_color = data["profile_sidebar_fill_color"]
54
54
  @profile_sidebar_border_color = data["profile_sidebar_border_color"]
55
55
  @friends_count = data["friends_count"].to_i
56
- @created_at = Time.parse(data["created_at"])
56
+ @created_at = (data["created_at"] ? DateTime.parse(data["created_at"]) : DateTime.now)
57
57
  @favourites_count = data["favourites_count"].to_i
58
58
  @utc_offset = data["utc_offset"]
59
59
  @time_zone = data["time_zone"]
@@ -62,6 +62,8 @@ module Tuiter
62
62
  @following = data["following"]
63
63
  @notifications = data["notifications"]
64
64
  @statuses_count = data["statuses_count"].to_i
65
+ else
66
+ @created_at = DateTime.now
65
67
  end
66
68
  end
67
69
 
@@ -73,7 +75,7 @@ module Tuiter
73
75
  def initialize(data=nil)
74
76
  unless data.nil?
75
77
  super(data)
76
- @status = Tuiter::StatusBasic.new(data["status"])
78
+ @status = StatusBasic.new(data["status"])
77
79
  end
78
80
  end
79
81
 
@@ -7,7 +7,7 @@ unless defined? Tuiter::VERSION
7
7
  module VERSION
8
8
  MAJOR = 0
9
9
  MINOR = 0
10
- TINY = 1
10
+ TINY = 2
11
11
 
12
12
  STRING = [MAJOR, MINOR, TINY].join('.')
13
13
  end
data/lib/tuiter.rb CHANGED
@@ -5,7 +5,15 @@ require 'logger'
5
5
 
6
6
  require 'json'
7
7
 
8
+ libdir = File.dirname(__FILE__)
9
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
10
+
11
+ # Tuiter client and end points
8
12
  require 'tuiter/client'
13
+
14
+ # Tuiter data structures
9
15
  require 'tuiter/data/user'
10
16
  require 'tuiter/data/status'
11
17
  require 'tuiter/data/rate_limit'
18
+ require 'tuiter/data/direct_message'
19
+
@@ -0,0 +1,68 @@
1
+ [
2
+ {
3
+ "description":"Follower #1",
4
+ "followers_count":300,
5
+ "url":"http:\/\/tuitersfera.com.br\/",
6
+ "name":"Joe Doe",
7
+ "protected":false,
8
+ "status":
9
+ {
10
+ "in_reply_to_status_id":null,
11
+ "truncated":false,
12
+ "text":"I am fine",
13
+ "created_at":"Mon Mar 23 18:25:41 +0000 2009",
14
+ "favorited":false,
15
+ "id":1203219398,
16
+ "in_reply_to_user_id":null,
17
+ "source":"web"
18
+ },
19
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
20
+ "location":"S\u00e3o Paulo",
21
+ "id":11111111,
22
+ "screen_name":"follower#1"
23
+ },
24
+ {
25
+ "description":"Follower #2",
26
+ "followers_count":15,
27
+ "url":"http:\/\/tuitersfera.com.br\/",
28
+ "name":"Mark Knoffler",
29
+ "protected":false,
30
+ "status":
31
+ {
32
+ "in_reply_to_status_id":null,
33
+ "truncated":false,
34
+ "text":"Playing the blues",
35
+ "created_at":"Mon Mar 23 09:30:10 +0000 2009",
36
+ "favorited":false,
37
+ "id":1203219398,
38
+ "in_reply_to_user_id":null,
39
+ "source":"web"
40
+ },
41
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
42
+ "location":"S\u00e3o Paulo",
43
+ "id":22222222,
44
+ "screen_name":"follower#2"
45
+ },
46
+ {
47
+ "description":"Follower #3",
48
+ "followers_count":200,
49
+ "url":"http:\/\/tuitersfera.com.br\/",
50
+ "name":"Iron Man",
51
+ "protected":false,
52
+ "status":
53
+ {
54
+ "in_reply_to_status_id":null,
55
+ "truncated":false,
56
+ "text":"Saving the world",
57
+ "created_at":"Mon Mar 23 09:30:10 +0000 2009",
58
+ "favorited":false,
59
+ "id":1203219398,
60
+ "in_reply_to_user_id":null,
61
+ "source":"web"
62
+ },
63
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
64
+ "location":"San Francisco",
65
+ "id":33333333,
66
+ "screen_name":"follower#3"
67
+ }
68
+ ]
@@ -0,0 +1,48 @@
1
+ [
2
+ {
3
+ "in_reply_to_user_id":19815179,
4
+ "truncated":false,
5
+ "user":
6
+ {
7
+ "description":"I am cool",
8
+ "followers_count":50,
9
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
10
+ "url":"http:\/\/tuitersfera.com.br\/",
11
+ "name":"Morgan Freeman",
12
+ "protected":false,
13
+ "screen_name":"morgan",
14
+ "location":"Hollywood, CA, USA",
15
+ "id":99999999
16
+ },
17
+ "favorited":false,
18
+ "text":"@tuitersfera hello?",
19
+ "created_at":"Sun Mar 22 18:56:38 +0000 2009",
20
+ "id":3333,
21
+ "in_reply_to_screen_name":"tuitersfera",
22
+ "in_reply_to_status_id":null,
23
+ "source":"web"
24
+ },
25
+ {
26
+ "in_reply_to_user_id":19815179,
27
+ "truncated":false,
28
+ "user":
29
+ {
30
+ "description":"Just relaxing",
31
+ "followers_count":300,
32
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
33
+ "url":"http:\/\/tuitersfera.com.br\/",
34
+ "name":"Carla Gugino",
35
+ "protected":false,
36
+ "screen_name":"HotCarla",
37
+ "location":"Hollywood, CA, USA",
38
+ "id":88888888
39
+ },
40
+ "favorited":false,
41
+ "text":"@tuitersfera I am fine, thanks.",
42
+ "created_at":"Sun Mar 22 13:50:38 +0000 2009",
43
+ "id":2222,
44
+ "in_reply_to_screen_name":"tuitersfera",
45
+ "in_reply_to_status_id":1,
46
+ "source":"web"
47
+ }
48
+ ]
@@ -0,0 +1,37 @@
1
+ {
2
+ "profile_background_image_url":"http:\/\/static.twitter.com\/images\/themes\/theme1\/bg.gif",
3
+ "description":"Projeto focado em medir a twittersfera brasileira.",
4
+ "utc_offset":-10800,
5
+ "profile_sidebar_fill_color":"e0ff92",
6
+ "following":false,
7
+ "friends_count":2053,
8
+ "notifications":false,
9
+ "profile_sidebar_border_color":"87bc44",
10
+ "profile_background_tile":false,
11
+ "time_zone":"Brasilia",
12
+ "favourites_count":0,
13
+ "profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/102032546\/tuit_normal.jpg",
14
+ "url":"http:\/\/tuitersfera.com.br\/",
15
+ "name":"Tuitersfera Brasil",
16
+ "protected":false,
17
+ "status":
18
+ {
19
+ "text":"Yesbaaaaaaa.... Completamos 1.000 usu\u00e1rios no Tuitersfera. http:\/\/tuitersfera.com.br\/",
20
+ "favorited":false,
21
+ "in_reply_to_user_id":null,
22
+ "in_reply_to_status_id":null,
23
+ "truncated":false,
24
+ "created_at":"Thu Feb 12 16:53:55 +0000 2009",
25
+ "id":1203219398,
26
+ "source":"<a href=\"http:\/\/www.twhirl.org\/\">twhirl<\/a>"
27
+ },
28
+ "profile_background_color":"9ae4e8",
29
+ "followers_count":1946,
30
+ "screen_name":"tuitersfera",
31
+ "profile_text_color":"000000",
32
+ "statuses_count":122,
33
+ "created_at":"Sat Jan 31 13:39:45 +0000 2009",
34
+ "location":"S\u00e3o Paulo, Brasil",
35
+ "id":19815179,
36
+ "profile_link_color":"0000ff"
37
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "id":11111111,
3
+ "name":"Joe Doe",
4
+ "screen_name":"follower#1"
5
+ "description":"Follower #1",
6
+ "location":"S\u00e3o Paulo",
7
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
8
+ "url":"http:\/\/tuitersfera.com.br\/",
9
+ "protected":false,
10
+ "followers_count":300,
11
+ "status":
12
+ {
13
+ "in_reply_to_status_id":null,
14
+ "truncated":false,
15
+ "text":"I am fine",
16
+ "created_at":"Mon Mar 23 18:25:41 +0000 2009",
17
+ "favorited":false,
18
+ "id":1203219398,
19
+ "in_reply_to_user_id":null,
20
+ "source":"web"
21
+ },
22
+ }
@@ -0,0 +1,48 @@
1
+ [
2
+ {
3
+ "user":
4
+ {
5
+ "description":"Projeto focado em medir a twittersfera brasileira.",
6
+ "profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/102032546\/tuit_normal.jpg",
7
+ "url":"http:\/\/tuitersfera.com.br\/",
8
+ "name":"Tuitersfera Brasil",
9
+ "protected":false,
10
+ "followers_count":1946,
11
+ "screen_name":"tuitersfera",
12
+ "location":"S\u00e3o Paulo, Brasil",
13
+ "id":19815179
14
+ },
15
+ "text":"Yesbaaaaaaa.... Completamos 1.000 usu\u00e1rios no Tuitersfera. http:\/\/tuitersfera.com.br\/",
16
+ "in_reply_to_screen_name":null,
17
+ "favorited":false,
18
+ "in_reply_to_user_id":null,
19
+ "in_reply_to_status_id":null,
20
+ "truncated":false,
21
+ "created_at":"Thu Feb 12 16:53:55 +0000 2009",
22
+ "id":1203219398,
23
+ "source":"<a href=\"http:\/\/www.twhirl.org\/\">twhirl<\/a>"
24
+ },
25
+ {
26
+ "user":
27
+ {
28
+ "description":"Projeto focado em medir a twittersfera brasileira.",
29
+ "profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/102032546\/tuit_normal.jpg",
30
+ "url":"http:\/\/tuitersfera.com.br\/",
31
+ "name":"Tuitersfera Brasil",
32
+ "protected":false,
33
+ "followers_count":1946,
34
+ "screen_name":"tuitersfera",
35
+ "location":"S\u00e3o Paulo, Brasil",
36
+ "id":19815179
37
+ },
38
+ "text":"Hello beautiful, how you're doing?",
39
+ "in_reply_to_screen_name":"HotCarla",
40
+ "favorited":false,
41
+ "in_reply_to_user_id":88888888,
42
+ "in_reply_to_status_id":null,
43
+ "truncated":false,
44
+ "created_at":"Sun Mar 22 12:10:21 +0000 2009",
45
+ "id":1203219398,
46
+ "source":"<a href=\"http:\/\/www.twhirl.org\/\">twhirl<\/a>"
47
+ }
48
+ ]
@@ -0,0 +1,29 @@
1
+ class Test::Unit::TestCase
2
+
3
+ def self.should_attr_accessor_for(klass, attributes)
4
+ object = klass.new
5
+
6
+ attributes.each do |attribute|
7
+ should "respond_to #{attribute}" do
8
+ assert object.respond_to?(attribute)
9
+ end
10
+
11
+ should "respond_to #{attribute}=" do
12
+ assert object.respond_to?("#{attribute}=")
13
+ end
14
+ end
15
+ end
16
+
17
+ def self.should_load_attribute_on_initialize(klass, attributes, expected_value = "value", setter_value = expected_value)
18
+
19
+ attributes.each do |attribute|
20
+ should "load attribute '#{attribute}' on initialize" do
21
+ data = eval("{'#{attribute}' => #{setter_value.inspect}}")
22
+
23
+ object = klass.new data
24
+ assert_equal(expected_value, object.send(attribute))
25
+ end
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,25 @@
1
+ require "rubygems"
2
+ require "test/unit"
3
+ require "shoulda"
4
+ require "mocha"
5
+ require 'fakeweb'
6
+
7
+ # begin
8
+ # require "quietbacktrace"
9
+ # Test::Unit::TestCase.quiet_backtrace = true
10
+ # Test::Unit::TestCase.backtrace_silencers = [:test_unit, :gem_root, :e1]
11
+ # Test::Unit::TestCase.backtrace_filters = [:method_name]
12
+ # rescue LoadError
13
+ # # Just ignore it
14
+ # rescue NoMethodError
15
+ # # Just ignore it
16
+ # end
17
+
18
+ require File.dirname(__FILE__) + "/../lib/tuiter"
19
+
20
+ #Load shoulda macros
21
+ %w(macros).each do |dirname|
22
+ Dir[File.dirname(__FILE__) + "/#{dirname}/*.rb"].each do |file|
23
+ require file
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class ClientTest < Test::Unit::TestCase
4
+
5
+ context "A valid Tuiter client" do
6
+
7
+ setup do
8
+ @username = "username"
9
+ @password = "password"
10
+ @client = Tuiter::Client.new(:username => @username, :password => @password)
11
+ end
12
+
13
+ context "posting data" do
14
+ setup do
15
+ @update_message = "I'm fine"
16
+ FakeWeb.register_uri(:post, "http://twitter.com/statuses/update.json", :string => @update_message, :status => "200")
17
+ end
18
+
19
+ should "allow the user to post an update to Twitter" do
20
+ # basic authentication and form data
21
+ Net::HTTP::Post.any_instance.expects(:basic_auth).with(@username, @password)
22
+ Net::HTTP::Post.any_instance.expects(:set_form_data).with('status' => @update_message, 'in_reply_to_status_id' => nil)
23
+
24
+ @response = @client.update(@update_message)
25
+
26
+ assert_instance_of Net::HTTPOK, @response
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ class StatusTest < Test::Unit::TestCase
4
+
5
+ STATUS_BASIC_ATTRIBUTES = %w(id text source truncated in_reply_to_status_id in_reply_to_user_id favorited in_reply_to_screen_name)
6
+
7
+ context "Status" do
8
+
9
+ context "Basic" do
10
+
11
+ should_attr_accessor_for Tuiter::StatusBasic, STATUS_BASIC_ATTRIBUTES
12
+ should_load_attribute_on_initialize Tuiter::StatusBasic, STATUS_BASIC_ATTRIBUTES
13
+
14
+ should "load attribute 'created_at' on initialize" do
15
+ now_str = "2009-10-31 18:59:20"
16
+ now = DateTime.parse(now_str)
17
+ user = Tuiter::UserExtended.new("created_at" => now_str)
18
+ assert_equal now, user.created_at
19
+ end
20
+
21
+ should "load attribute 'created_at' with current time" do
22
+ current_time = DateTime.now
23
+ DateTime.stubs(:now).returns(current_time)
24
+
25
+ user_extended = Tuiter::UserExtended.new
26
+ assert_equal current_time, user_extended.created_at
27
+ end
28
+
29
+ end # context "Basic"
30
+
31
+ context "for Twitter" do
32
+ should_attr_accessor_for Tuiter::Status, STATUS_BASIC_ATTRIBUTES
33
+ should_load_attribute_on_initialize Tuiter::Status, STATUS_BASIC_ATTRIBUTES
34
+
35
+ should "load attribute 'created_at' on initialize" do
36
+ now_str = "2009-10-31 18:59:20"
37
+ now = DateTime.parse(now_str)
38
+ user = Tuiter::UserExtended.new("created_at" => now_str)
39
+ assert_equal now, user.created_at
40
+ end
41
+
42
+ should "load attribute 'created_at' with current time" do
43
+ current_time = DateTime.now
44
+ DateTime.stubs(:now).returns(current_time)
45
+
46
+ user_extended = Tuiter::UserExtended.new
47
+ assert_equal current_time, user_extended.created_at
48
+ end
49
+
50
+ should "load user correctly" do
51
+ user_expected = Tuiter::UserBasic.new
52
+ Tuiter::UserBasic.expects(:new).with("user_data").returns(user_expected)
53
+ status = Tuiter::Status.new "user" => "user_data"
54
+ assert_equal user_expected, status.user
55
+ end
56
+ end # context "for Twitter"
57
+
58
+ end # context "Status"
59
+
60
+ end
61
+
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ class UserTest < Test::Unit::TestCase
4
+
5
+ USER_BASICS_ATTRIBUTES = %w(id name screen_name location description profile_image_url url protected followers_count)
6
+ USER_EXTEDNED_ATTRIBUTES = USER_BASICS_ATTRIBUTES + %w(profile_background_color profile_text_color profile_link_color profile_sidebar_fill_color profile_sidebar_border_color utc_offset time_zone profile_background_image_url profile_background_tile following notifications)
7
+ USER_EXTEDNED_ATTRIBUTES_INTEGER = %w(friends_count statuses_count favourites_count)
8
+ USER_EXTEDNED_ATTRIBUTES_TIME = %w(created_at)
9
+ USER_TWITTER_ATTRIBUTES = USER_BASICS_ATTRIBUTES + %w(status)
10
+
11
+ context "User" do
12
+ context "Basic" do
13
+ should_attr_accessor_for Tuiter::UserBasic, USER_BASICS_ATTRIBUTES
14
+ should_load_attribute_on_initialize Tuiter::UserBasic, USER_BASICS_ATTRIBUTES
15
+ end # context "Basic"
16
+
17
+ context "Extended" do
18
+ setup do
19
+ @now_str = "2009-10-31 18:59:20"
20
+ @now = DateTime.parse(@now_str)
21
+ end
22
+ should_attr_accessor_for Tuiter::UserExtended, USER_EXTEDNED_ATTRIBUTES
23
+ should_load_attribute_on_initialize Tuiter::UserExtended, USER_EXTEDNED_ATTRIBUTES
24
+ should_load_attribute_on_initialize Tuiter::UserExtended, USER_EXTEDNED_ATTRIBUTES_INTEGER, 10
25
+
26
+ should "load attribute 'created_at' on initialize" do
27
+ now_str = "2009-10-31 18:59:20"
28
+ now = DateTime.parse(now_str)
29
+ user = Tuiter::UserExtended.new("created_at" => now_str)
30
+ assert_equal now, user.created_at
31
+ end
32
+
33
+ should "load attribute 'created_at' with current time" do
34
+ current_time = DateTime.now
35
+ DateTime.stubs(:now).returns(current_time)
36
+
37
+ user_extended = Tuiter::UserExtended.new
38
+ assert_equal current_time, user_extended.created_at
39
+ end
40
+ end # context "Extended"
41
+
42
+ context "for Twitter" do
43
+ should_attr_accessor_for Tuiter::User, USER_TWITTER_ATTRIBUTES
44
+ should_load_attribute_on_initialize Tuiter::User, USER_BASICS_ATTRIBUTES
45
+
46
+ should "load attribute 'status' correctly" do
47
+ status_expected = Tuiter::StatusBasic.new
48
+ Tuiter::StatusBasic.expects(:new).with("teste").returns(status_expected)
49
+ user = Tuiter::User.new "status" => "teste"
50
+ assert_equal status_expected, user.status
51
+ end
52
+
53
+ end # context "for Twitter"
54
+
55
+
56
+
57
+ end # context "User"
58
+
59
+
60
+ end
61
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webco-tuiter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manoel Lemos
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-02-25 00:00:00 -08:00
13
+ date: 2009-04-04 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -36,10 +36,11 @@ files:
36
36
  - AUTHORS
37
37
  - CHANGELOG
38
38
  - LICENSE
39
- - README.markdown
39
+ - README.rdoc
40
40
  - lib/tuiter
41
41
  - lib/tuiter/client.rb
42
42
  - lib/tuiter/data
43
+ - lib/tuiter/data/direct_message.rb
43
44
  - lib/tuiter/data/rate_limit.rb
44
45
  - lib/tuiter/data/status.rb
45
46
  - lib/tuiter/data/user.rb
@@ -47,6 +48,19 @@ files:
47
48
  - lib/tuiter.log
48
49
  - lib/tuiter.rb
49
50
  - examples/basic_example.rb
51
+ - test/fixtures
52
+ - test/fixtures/followers.json
53
+ - test/fixtures/replies.json
54
+ - test/fixtures/tuitersfera.json
55
+ - test/fixtures/user_basic.json
56
+ - test/fixtures/user_timeline.json
57
+ - test/macros
58
+ - test/macros/attr_accessor_macro.rb
59
+ - test/test_helper.rb
60
+ - test/unit
61
+ - test/unit/client_test.rb
62
+ - test/unit/status_test.rb
63
+ - test/unit/user_test.rb
50
64
  has_rdoc: false
51
65
  homepage: http://github.com/webco/tuiter
52
66
  post_install_message:
@@ -68,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
82
  version:
69
83
  requirements: []
70
84
 
71
- rubyforge_project:
85
+ rubyforge_project: tuiter
72
86
  rubygems_version: 1.2.0
73
87
  signing_key:
74
88
  specification_version: 2
data/README.markdown DELETED
@@ -1,16 +0,0 @@
1
- # Tuiter #
2
-
3
- Tuiter was design and developed by Manoel Lemos (manoel@lemos.net), to provide access to the Twitter API. It was developed for the experimental project called [Tuitersfera Brasil](http://tuitersfera.com.br), an application to monitor the Twitter usage in Brazil.
4
-
5
- # Basic Usage #
6
-
7
- require 'tuiter'
8
- client = Tuiter::Client.new(:username => '<twitter_login>', :password => '<twitter_pwd>')
9
- client.update('Hey Ho, Twitters!')
10
-
11
- # Current Status #
12
-
13
- Tuiter is currently being extracted from Tuitersfera and transformed into a full-fledged Ruby library.
14
-
15
- Stay in tune for updates!
16
-