tuiter 0.0.1

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 ADDED
@@ -0,0 +1,14 @@
1
+ Tuiter was design and developed by Manoel Lemos (manoel@lemos.net), to provide
2
+ basic access to the Twitter API. It was developed for the experimental project
3
+ called Tuitersfera Brasil (http://tuitersfera.com.br), an application to
4
+ monitor the Twitter usage in Brazil.
5
+
6
+ Both projects were latter adopted by WebCo Internet (http://webcointernet.com).
7
+
8
+ The authors and contributors of Tuiter are:
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)
14
+
@@ -0,0 +1,3 @@
1
+ == Tuiter 0.0.1
2
+ * extracting tuiter from tuitersfera
3
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009, Manoel Lemos
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
20
+
@@ -0,0 +1,27 @@
1
+ = Tuiter
2
+
3
+ Tuiter was design and developed by {Manoel Lemos}[http://manoellemos.com] 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
+ Both Tuiter and Tuitersfera were adopted, further developed and maintained by {Webco Internet}[http://webcointernet.com].
6
+
7
+ == Instalation
8
+
9
+ A tuiter gem is avaliable in Github. To install simply run on a console:
10
+
11
+ gem install webco-utils --source=http://gems.github.com
12
+
13
+ If you already have Github gem repository on you gem source, you can leave the source part out.
14
+
15
+ == Basic Usage
16
+
17
+ require 'tuiter'
18
+ client = Tuiter::Client.new(:username => '<twitter_login>', :password => '<twitter_pwd>')
19
+
20
+ client.update('Hey Ho, Twitters!')
21
+
22
+ There are (or at least we pretend to add :-) another examples in the examples/ folder.
23
+
24
+ == Roadmap and TO-DO list
25
+
26
+ Check out the library roadmap and to-do list {in the wiki}[http://wiki.github.com/webco/tuiter]
27
+
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rake"
4
+ require "rake/testtask"
5
+ require "rake/rdoctask"
6
+
7
+ require "lib/tuiter/version"
8
+
9
+ desc "Run test suite"
10
+ Rake::TestTask.new do |t|
11
+ t.libs << "test"
12
+ t.pattern = "test/**/*_test.rb"
13
+ t.verbose = false
14
+ end
15
+
16
+ desc "Report code statistics (KLOCs, etc) from the library"
17
+ task "stats" do
18
+ require "code_statistics"
19
+ ::CodeStatistics::TEST_TYPES << "Tests"
20
+ ::CodeStatistics.new(["Libraries", "lib"], ["Tests", "test"]).to_s
21
+ end
22
+
23
+ desc "List the names of the test methods"
24
+ task "list" do
25
+ $LOAD_PATH.unshift("test")
26
+ $LOAD_PATH.unshift("lib")
27
+ require "test/unit"
28
+ Test::Unit.run = true
29
+ test_files = Dir.glob(File.join('test', '**/*_test.rb'))
30
+ test_files.each do |file|
31
+ load file
32
+ klass = File.basename(file, '.rb').classify.constantize
33
+ puts klass.name.gsub('Test', '')
34
+ test_methods = klass.instance_methods.grep(/^test/).map {|s| s.gsub(/^test: /, '')}.sort
35
+ test_methods.each {|m| puts " " + m }
36
+ end
37
+ end
38
+
39
+ def spec_files
40
+ %w( Rakefile AUTHORS CHANGELOG LICENSE README.rdoc ) + Dir["{lib,examples,test}/**/*"]
41
+ end
42
+
43
+ def spec
44
+ spec = Gem::Specification.new do |s|
45
+ s.name = "tuiter"
46
+ s.version = Tuiter::VERSION::STRING
47
+ s.summary = "Yet another Twitter API wrapper library in Ruby"
48
+ s.authors = ["Manoel Lemos", "WebCo Internet"]
49
+ s.email = "opensource@webcointernet.com"
50
+ s.homepage = "http://github.com/webco/tuiter"
51
+ s.description = "Yet another Twitter API wrapper library in Ruby"
52
+ s.has_rdoc = false
53
+ # s.extra_rdoc_files = ["LICENSE", "README.rdoc", "CHANGELOG"]
54
+ # s.rdoc_options = ["--inline-source", "--charset=utf-8"]
55
+ s.files = spec_files
56
+ s.rubyforge_project = "tuiter"
57
+
58
+ # Dependencies
59
+ s.add_dependency "json", ">= 1.1"
60
+ end
61
+ end
62
+
63
+ desc "Creates the gemspec"
64
+ task "gemify" do
65
+ skip_fields = %w(new_platform original_platform specification_version loaded required_ruby_version rubygems_version platform bindir )
66
+
67
+ result = "# WARNING: RAKE AUTO-GENERATED FILE. DO NOT MANUALLY EDIT!\n"
68
+ result << "# RUN: 'rake gemify'\n\n"
69
+ result << "Gem::Specification.new do |s|\n"
70
+
71
+ spec.instance_variables.each do |ivar|
72
+ value = spec.instance_variable_get(ivar)
73
+ name = ivar.split("@").last
74
+ value = Date.today.to_s if name == "date"
75
+
76
+ next if skip_fields.include?(name) || value.nil? || value == "" || (value.respond_to?(:empty?) && value.empty?)
77
+ if name == "dependencies"
78
+ value.each do |d|
79
+ dep, *ver = d.to_s.split(" ")
80
+ result << " s.add_dependency #{dep.inspect}, #{ver.join(" ").inspect.gsub(/[()]/, "").gsub(", runtime", "")}\n"
81
+ end
82
+ elsif name == "required_rubygems_version"
83
+ result << " s.required_rubygems_version = Gem::Requirement.new(\">= 0\") if s.respond_to? :required_rubygems_version=\n"
84
+ else
85
+ case value
86
+ when Array
87
+ value = name != "files" ? value.inspect : value.inspect.split(",").join(",\n")
88
+ when FalseClass
89
+ when TrueClass
90
+ when Fixnum
91
+ when String
92
+ value = value.inspect
93
+ else
94
+ value = value.to_s.inspect
95
+ end
96
+ result << " s.#{name} = #{value}\n"
97
+ end
98
+ end
99
+
100
+ result << "end"
101
+ File.open(File.join(File.dirname(__FILE__), "#{spec.name}.gemspec"), "w"){|f| f << result}
102
+ end
103
+
104
+ desc "Build the gem"
105
+ task "build" => "gemify" do
106
+ sh "gem build #{spec.name}.gemspec"
107
+ end
108
+
109
+ desc "Install the gem locally"
110
+ task "install" => "build" do
111
+ sh "gem install #{spec.name}-#{spec.version}.gem && rm -r *.gem *.gemspec"
112
+ end
113
+
114
+ desc "Publish the gem to Rubyforge"
115
+ task "rubyforge" => "build" do
116
+ require 'rubyforge'
117
+ rubyforge_config_path = File.expand_path(File.join('~', '.rubyforge'))
118
+ user_config = YAML::load(File.open(rubyforge_config_path + '/user-config.yml'))
119
+ auto_config = YAML::load(File.open(rubyforge_config_path + '/auto-config.yml'))
120
+
121
+ @rubyforge = RubyForge.new(user_config, auto_config)
122
+
123
+ @rubyforge.login
124
+ @rubyforge.add_release('tuiter', 'tuiter', "#{spec.version}", "#{spec.name}-#{spec.version}.gem")
125
+ end
126
+
127
+ task :default => ["test"]
128
+
@@ -0,0 +1,8 @@
1
+ require 'tuiter'
2
+
3
+ client = Tuiter::Client.new(:username => 'screen_name', :password => 'password')
4
+
5
+ 15.times do
6
+ client.update('All work and no play makes Jack a dull boy')
7
+ end
8
+
@@ -0,0 +1,11 @@
1
+ require 'open-uri'
2
+ require 'uri'
3
+ require 'net/http'
4
+ require 'logger'
5
+
6
+ require 'json'
7
+
8
+ require 'tuiter/client'
9
+ require 'tuiter/data/user'
10
+ require 'tuiter/data/status'
11
+ require 'tuiter/data/rate_limit'
@@ -0,0 +1,189 @@
1
+ module Tuiter
2
+
3
+ class Client
4
+ attr_accessor :username, :password
5
+
6
+ def initialize(options = {})
7
+ @pid = Process.pid
8
+ @logger = options[:logger] || Logger.new('tuiter.log')
9
+ @username = options[:username]
10
+ @password = options[:password]
11
+ log("initialize()")
12
+ end
13
+
14
+ def update(status, in_reply_to_status_id = nil)
15
+ log("update() sending: #{status}")
16
+ url = URI.parse('http://twitter.com/statuses/update.json')
17
+ req = Net::HTTP::Post.new(url.path)
18
+ req.basic_auth @username, @password
19
+ 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
+ case res
22
+ when Net::HTTPSuccess, Net::HTTPRedirection
23
+ log("update() success: OK")
24
+ return res # OK
25
+ else
26
+ log("update() error: #{res.error!}")
27
+ res.error!
28
+ end
29
+ end
30
+
31
+ def direct_new(user, text)
32
+ log("direct_new() sending: #{text} to #{user}")
33
+ url = URI.parse('http://twitter.com/direct_messages/new.json')
34
+ req = Net::HTTP::Post.new(url.path)
35
+ req.basic_auth @username, @password
36
+ req.set_form_data({'user'=>user, 'text'=>text })
37
+ res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
38
+ case res
39
+ when Net::HTTPSuccess, Net::HTTPRedirection
40
+ log("direct_new() success: OK")
41
+ return res # OK
42
+ else
43
+ log("direct_new() error: #{res.error!}")
44
+ res.error!
45
+ end
46
+ end
47
+
48
+ def friendship_new(user, follow = nil)
49
+ log("friendship_new() following: #{user}")
50
+ url = URI.parse("http://twitter.com/friendships/create/#{user}.json")
51
+ req = Net::HTTP::Post.new(url.path)
52
+ req.basic_auth @username, @password
53
+ req.set_form_data({'follow'=>"true"}) if follow
54
+ res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
55
+ case res
56
+ when Net::HTTPSuccess, Net::HTTPRedirection
57
+ log("friendship_new() success: OK")
58
+ return res # OK
59
+ else
60
+ log("friendship_new() error: #{res.error!}")
61
+ res.error!
62
+ end
63
+ end
64
+
65
+ def verify_credentials?
66
+ if res = request("http://twitter.com/account/verify_credentials.json")
67
+ return UserExtended.new(JSON.parse(res))
68
+ else
69
+ return nil
70
+ end
71
+ end
72
+
73
+ def get_followers(options = {})
74
+ if options[:id]
75
+ query = "http://twitter.com/statuses/followers/#{options[:id]}.json"
76
+ else
77
+ query = "http://twitter.com/statuses/followers.json"
78
+ end
79
+ if options[:page]
80
+ params = "?page=#{options[:page]}"
81
+ else
82
+ params = ""
83
+ end
84
+ if res = request(query+params)
85
+ data = JSON.parse(res)
86
+ return data.map { |d| User.new(d) }
87
+ else
88
+ return nil
89
+ end
90
+ end
91
+
92
+ def get_replies(options = {})
93
+ query = "http://twitter.com/statuses/replies.json"
94
+ if options[:since]
95
+ params = "?since=#{options[:since]}"
96
+ elsif options[:since_id]
97
+ params = "?since_id=#{options[:since_id]}"
98
+ else
99
+ params = ""
100
+ end
101
+ if options[:page]
102
+ if params == ""
103
+ params = "?page=#{options[:page]}"
104
+ else
105
+ params = params + "&" + "page=#{options[:page]}"
106
+ end
107
+ end
108
+ if res = request(query+params)
109
+ data = JSON.parse(res)
110
+ return data.map { |d| Status.new(d) }
111
+ else
112
+ return nil
113
+ end
114
+ end
115
+
116
+ def get_client
117
+ if res = request("http://twitter.com/users/show/#{@username}.json")
118
+ return UserExtended.new(JSON.parse(res))
119
+ else
120
+ return nil
121
+ end
122
+ end
123
+
124
+ def get_user(id)
125
+ if res = request("http://twitter.com/users/show/#{id}.json")
126
+ return UserExtended.new(JSON.parse(res))
127
+ else
128
+ return nil
129
+ end
130
+ end
131
+
132
+ def get_status(id)
133
+ if res = request("http://twitter.com/statuses/show/#{id}.json")
134
+ return Status.new(JSON.parse(res))
135
+ else
136
+ return nil
137
+ end
138
+ end
139
+
140
+ def rate_limit
141
+ if res = request("http://twitter.com/account/rate_limit_status.json")
142
+ return RateLimit.new(JSON.parse(res))
143
+ else
144
+ return nil
145
+ end
146
+ end
147
+
148
+ def follows_me?(id)
149
+ if res = request("http://twitter.com/friendships/exists.json?user_a=#{id}&user_b=#{@username}")
150
+ return true if res == "true"
151
+ return false
152
+ else
153
+ return nil
154
+ end
155
+ end
156
+
157
+ private
158
+
159
+ def request(url)
160
+ http = nil
161
+ status = Timeout::timeout(10) do
162
+ log("request() query: #{url}")
163
+ http = open(url, :http_basic_authentication=>[@username, @password])
164
+ log("request() debug: http status is #{http.status.join(' ')}")
165
+ if http.status == ["200", "OK"]
166
+ res = http.read
167
+ return res
168
+ end
169
+ return nil
170
+ end
171
+ rescue Timeout::Error
172
+ log("request() error: timeout error")
173
+ return nil
174
+ rescue OpenURI::HTTPError => e
175
+ log("request() http error: #{e.message} in #{e.backtrace.first.to_s}")
176
+ return nil
177
+ rescue Exception => e
178
+ log("request() error: #{e.message} in #{e.backtrace.first.to_s}")
179
+ return nil
180
+ end
181
+
182
+ def log(message)
183
+ @logger.info "[Tuiter:#{@pid}] #{Time.now.to_s} : #{message}"
184
+ end
185
+
186
+ end
187
+
188
+ end
189
+
@@ -0,0 +1,22 @@
1
+ module Tuiter
2
+
3
+ class RateLimit
4
+ attr_accessor :reset_time
5
+ attr_accessor :reset_time_in_seconds
6
+ attr_accessor :reset_window
7
+ attr_accessor :remaining_hits
8
+ attr_accessor :hourly_limit
9
+
10
+ def initialize(data = nil)
11
+ unless data.nil?
12
+ @reset_time_in_seconds = Time.at(data["reset_time_in_seconds"].to_i)
13
+ @reset_time = Time.parse(data["reset_time"])
14
+ @reset_window = @reset_time - Time.now
15
+ @remaining_hits = data["remaining_hits"].to_i
16
+ @hourly_limit = data["hourly_limit"].to_i
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+
@@ -0,0 +1,44 @@
1
+ module Tuiter
2
+
3
+ class StatusBasic
4
+ attr_accessor :created_at
5
+ attr_accessor :id
6
+ attr_accessor :text
7
+ attr_accessor :source
8
+ attr_accessor :truncated
9
+ attr_accessor :in_reply_to_status_id
10
+ attr_accessor :in_reply_to_user_id
11
+ attr_accessor :favorited
12
+ attr_accessor :in_reply_to_screen_name
13
+
14
+ def initialize(data = nil)
15
+ unless data.nil?
16
+ @created_at = Time.parse(data["created_at"])
17
+ @id = data["id"]
18
+ @text = data["text"]
19
+ @source = data["source"]
20
+ @truncated = data["truncated"]
21
+ @in_reply_to_status_id = data["in_reply_to_status_id"]
22
+ @in_reply_to_user_id = data["in_reply_to_user_id"]
23
+ @favorited = data["favorited"]
24
+ @in_reply_to_screen_name = data["in_reply_to_screen_name"]
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+
31
+ class Status < StatusBasic
32
+ attr_accessor :user
33
+
34
+ def initialize(data=nil)
35
+ unless data.nil?
36
+ super(data)
37
+ @user = UserBasic.new(data["user"])
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
@@ -0,0 +1,83 @@
1
+ module Tuiter
2
+
3
+ class UserBasic
4
+ attr_accessor :id
5
+ attr_accessor :name
6
+ attr_accessor :screen_name
7
+ attr_accessor :location
8
+ attr_accessor :description
9
+ attr_accessor :profile_image_url
10
+ attr_accessor :url
11
+ attr_accessor :protected
12
+ attr_accessor :followers_count
13
+
14
+ def initialize(data = nil)
15
+ unless data.nil?
16
+ @id = data["id"]
17
+ @name = data["name"]
18
+ @screen_name = data["screen_name"]
19
+ @location = data["location"]
20
+ @description = data["description"]
21
+ @profile_image_url = data["profile_image_url"]
22
+ @url = data["url"]
23
+ @protected = data["protected"]
24
+ @followers_count = data["followers_count"]
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ class UserExtended < UserBasic
31
+ attr_accessor :profile_background_color
32
+ attr_accessor :profile_text_color
33
+ attr_accessor :profile_link_color
34
+ attr_accessor :profile_sidebar_fill_color
35
+ attr_accessor :profile_sidebar_border_color
36
+ attr_accessor :friends_count
37
+ attr_accessor :created_at
38
+ attr_accessor :favourites_count
39
+ attr_accessor :utc_offset
40
+ attr_accessor :time_zone
41
+ attr_accessor :profile_background_image_url
42
+ attr_accessor :profile_background_tile
43
+ attr_accessor :following
44
+ attr_accessor :notifications
45
+ attr_accessor :statuses_count
46
+
47
+ def initialize(data = nil)
48
+ unless data.nil?
49
+ super(data)
50
+ @profile_background_color = data["profile_background_color"]
51
+ @profile_text_color = data["profile_text_color"]
52
+ @profile_link_color = data["profile_link_color"]
53
+ @profile_sidebar_fill_color = data["profile_sidebar_fill_color"]
54
+ @profile_sidebar_border_color = data["profile_sidebar_border_color"]
55
+ @friends_count = data["friends_count"].to_i
56
+ @created_at = Time.parse(data["created_at"])
57
+ @favourites_count = data["favourites_count"].to_i
58
+ @utc_offset = data["utc_offset"]
59
+ @time_zone = data["time_zone"]
60
+ @profile_background_image_url = data["profile_background_image_url"]
61
+ @profile_background_tile = data["profile_background_tile"]
62
+ @following = data["following"]
63
+ @notifications = data["notifications"]
64
+ @statuses_count = data["statuses_count"].to_i
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ class User < UserBasic
71
+ attr_accessor :status
72
+
73
+ def initialize(data=nil)
74
+ unless data.nil?
75
+ super(data)
76
+ @status = StatusBasic.new(data["status"])
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+
@@ -0,0 +1,16 @@
1
+ #
2
+ # Tuiter, Copyright (c) 2009 Manoel Lemos & WebCo Internet
3
+ #
4
+
5
+ unless defined? Tuiter::VERSION
6
+ module Tuiter
7
+ module VERSION
8
+ MAJOR = 0
9
+ MINOR = 0
10
+ TINY = 1
11
+
12
+ STRING = [MAJOR, MINOR, TINY].join('.')
13
+ end
14
+ end
15
+ end
16
+
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tuiter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Manoel Lemos
8
+ - WebCo Internet
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-03-20 00:00:00 -03:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: json
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "1.1"
25
+ version:
26
+ description: Yet another Twitter API wrapper library in Ruby
27
+ email: opensource@webcointernet.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - Rakefile
36
+ - AUTHORS
37
+ - CHANGELOG
38
+ - LICENSE
39
+ - README.rdoc
40
+ - lib/tuiter
41
+ - lib/tuiter/client.rb
42
+ - lib/tuiter/data
43
+ - lib/tuiter/data/rate_limit.rb
44
+ - lib/tuiter/data/status.rb
45
+ - lib/tuiter/data/user.rb
46
+ - lib/tuiter/version.rb
47
+ - lib/tuiter.rb
48
+ - examples/basic_example.rb
49
+ has_rdoc: false
50
+ homepage: http://github.com/webco/tuiter
51
+ post_install_message:
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project: tuiter
71
+ rubygems_version: 1.3.1
72
+ signing_key:
73
+ specification_version: 2
74
+ summary: Yet another Twitter API wrapper library in Ruby
75
+ test_files: []
76
+