pmoran-yammer4r 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,16 @@
1
+ = Yammer4R
2
+
3
+ == Developers
4
+ * {Jim Patterson} <jimp79 at gmail dot com>
5
+
6
+ == Description
7
+ Yammer4R provides an object based API to query or update your Yammer account via pure Ruby. It hides the ugly HTTP/REST code from your code.
8
+
9
+ == External Dependencies
10
+ * Ruby 1.8 (tested with 1.8.7)
11
+ * JSON gem (tested with versions: 1.1.3)
12
+ * OAuth gem (tested with versions: 0.2.7)
13
+ * RSpec gem (tested with versions: 1.1.11)
14
+
15
+ == Usage Examples
16
+ Coming soon...
@@ -0,0 +1,13 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'spec/rake/spectask'
6
+ require 'yammer4r'
7
+
8
+ desc "Run all specs"
9
+ Spec::Rake::SpecTask.new('spec') do |t|
10
+ t.spec_files = FileList['spec/**/*spec.rb']
11
+ end
12
+
13
+ task :default => [:spec]
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+ Test! There are currently no tests for yammer4r, and that makes me very sad.
2
+ Switch to HTTParty instead of yammer_request.
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Instructions:
4
+ #
5
+ # Register your application at https://www.yammer.com/client_applications/new
6
+ # Upon successful registration, you'll recieve your consumer key and secret.
7
+ # Pass these values on the command line as --key (-k) and --secret (-s) then
8
+ # follow the instructions.
9
+
10
+ require 'optparse'
11
+ require 'rubygems'
12
+ require 'oauth'
13
+
14
+ OPTIONS = {
15
+ :outfile => 'oauth.yml'
16
+ }
17
+
18
+ YAMMER_OAUTH = "https://www.yammer.com"
19
+
20
+ ARGV.options do |o|
21
+ script_name = File.basename($0)
22
+
23
+ o.set_summary_indent(' ')
24
+ o.banner = "Usage: #{script_name} [OPTIONS]"
25
+ o.define_head "Create a yaml file for yammer oauth"
26
+ o.separator ""
27
+ o.separator "[-k] and [-s] options are mandatory"
28
+ o.separator ""
29
+
30
+ o.on("-o", "--outfile=[val]", String,
31
+ "Yaml output file",
32
+ "Default: #{OPTIONS[:outfile]}") { |OPTIONS[:outfile]| }
33
+ o.on("-k", "--key=val", String,
34
+ "Consumer key for Yammer app") { |key| OPTIONS[:key] = key}
35
+ o.on("-s", "--secret=val", String,
36
+ "Consumer secret for Yammer app") { |secret| OPTIONS[:secret] = secret}
37
+
38
+ o.separator ""
39
+
40
+ o.on_tail("-h", "--help", "Show this help message.") { puts o; exit }
41
+ o.parse!
42
+ end
43
+
44
+ unless OPTIONS[:key] && OPTIONS[:secret]
45
+ raise ArgumentError, "Must supply consumer key and secret (use -h for help)"
46
+ end
47
+
48
+ consumer = OAuth::Consumer.new OPTIONS[:key], OPTIONS[:secret], {:site => YAMMER_OAUTH}
49
+ request_token = consumer.get_request_token
50
+
51
+ puts "Please visit the following URL in your browser to authorize your application, then enter the 4 character security code when done: #{request_token.authorize_url}"
52
+ oauth_verifier = gets
53
+ response = consumer.token_request(consumer.http_method,
54
+ (consumer.access_token_url? ? consumer.access_token_url : consumer.access_token_path),
55
+ request_token,
56
+ {},
57
+ :oauth_verifier => oauth_verifier.chomp)
58
+ access_token = OAuth::AccessToken.new(consumer,response[:oauth_token],response[:oauth_token_secret])
59
+
60
+ oauth_yml = <<-EOT
61
+ consumer:
62
+ key: #{OPTIONS[:key]}
63
+ secret: #{OPTIONS[:secret]}
64
+ access:
65
+ token: #{access_token.token}
66
+ secret: #{access_token.secret}
67
+ EOT
68
+
69
+ File.open(OPTIONS[:outfile], "w") do |f|
70
+ f.write oauth_yml
71
+ end
@@ -0,0 +1,15 @@
1
+ require 'yammer4r'
2
+
3
+ config_path = File.dirname(__FILE__) + 'oauth.yml'
4
+ yammer = Yammer::Client.new(:config => config_path)
5
+
6
+ # Get all messages
7
+ messages = yammer.messages
8
+ puts messages.size
9
+ puts messages.last.body.plain
10
+ puts messages.last.body.parsed
11
+
12
+ # Print out all the users
13
+ yammer.users.each do |u|
14
+ puts "#{u.name} - #{u.me?}"
15
+ end
@@ -0,0 +1,30 @@
1
+ class String
2
+ def to_boolean
3
+ case self
4
+ when 'true'
5
+ true
6
+ when 'false'
7
+ false
8
+ else
9
+ nil
10
+ end
11
+ end
12
+ end
13
+
14
+ class Hash
15
+ def symbolize_keys
16
+ inject({}) do |options, (key, value)|
17
+ options[(key.to_sym rescue key) || key] = value
18
+ options
19
+ end
20
+ end
21
+
22
+ def symbolize_keys!
23
+ self.replace(self.symbolize_keys)
24
+ end
25
+
26
+ def assert_has_keys(*valid_keys)
27
+ missing_keys = [valid_keys].flatten - keys
28
+ raise(ArgumentError, "Missing Option(s): #{missing_keys.join(", ")}") unless missing_keys.empty?
29
+ end
30
+ end
@@ -0,0 +1,100 @@
1
+ module Yammer
2
+ class Client
3
+ def initialize(options={})
4
+ options.assert_has_keys(:consumer, :access) unless options.has_key?(:config)
5
+
6
+ yammer_url = options.delete(:yammer_host) || "https://www.yammer.com"
7
+ @api_path = "/api/v1/"
8
+
9
+ if options[:config]
10
+ config = YAML.load(open(options[:config]))
11
+ options[:consumer] = config['consumer'].symbolize_keys
12
+ options[:access] = config['access'].symbolize_keys
13
+ end
14
+
15
+ consumer = OAuth::Consumer.new(options[:consumer][:key], options[:consumer][:secret], :site => yammer_url)
16
+ consumer.http.set_debug_output($stderr) if options[:verbose] == true
17
+ @access_token = OAuth::AccessToken.new(consumer, options[:access][:token], options[:access][:secret])
18
+ end
19
+
20
+
21
+ # TODO: modularize message and user handling
22
+ def messages(action = :all, params = {})
23
+ params.merge!(:resource => :messages)
24
+ params.merge!(:action => action) unless action == :all
25
+
26
+ parsed_response = JSON.parse(yammer_request(:get, params).body)
27
+ older_available = parsed_response['meta']['older_available']
28
+
29
+ ml = parsed_response['messages'].map do |m|
30
+ mash(m)
31
+ end
32
+ Yammer::MessageList.new(ml, older_available, self)
33
+ end
34
+
35
+ # POST or DELETE a message
36
+ def message(action, params)
37
+ params.merge!(:resource => :messages)
38
+ yammer_request(action, params)
39
+ end
40
+
41
+ def users(params = {})
42
+ params.merge!(:resource => :users)
43
+ JSON.parse(yammer_request(:get, params).body).map { |u| Yammer::User.new(mash(u), self) }
44
+ end
45
+
46
+ def user(id)
47
+ u = JSON.parse(yammer_request(:get, {:resource => :users, :id => id}).body)
48
+ Yammer::User.new(mash(u), self)
49
+ end
50
+
51
+ def current_user
52
+ u = JSON.parse(yammer_request(:get, {:resource => :users, :action => :current}).body)
53
+ Yammer::User.new(mash(u), self)
54
+ end
55
+ alias_method :me, :current_user
56
+
57
+ private
58
+
59
+ def yammer_request(http_method, options)
60
+ request_uri = @api_path + options.delete(:resource).to_s
61
+ [:action, :id].each {|k| request_uri += "/#{options.delete(k)}" if options.has_key?(k) }
62
+ request_uri += ".json"
63
+
64
+ if options.any?
65
+ request_uri += "?#{create_query_string(options)}" unless http_method == :post
66
+ end
67
+
68
+ if http_method == :post
69
+ handle_response(@access_token.send(http_method, request_uri, options))
70
+ else
71
+ handle_response(@access_token.send(http_method, request_uri))
72
+ end
73
+ end
74
+
75
+ def create_query_string(options)
76
+ options.map {|k, v| "#{OAuth::Helper.escape(k)}=#{OAuth::Helper.escape(v)}"}.join('&')
77
+ end
78
+
79
+ def mash(json)
80
+ Mash.new(json)
81
+ end
82
+
83
+ def handle_response(response)
84
+ # TODO: Write classes for exceptions
85
+ case response.code.to_i
86
+ when 200..201
87
+ response
88
+ when 400
89
+ raise "400 Bad request"
90
+ when 401
91
+ raise "Authentication failed. Check your username and password"
92
+ when 503
93
+ raise "503: Service Unavailable"
94
+ else
95
+ raise "Error. HTTP Response #{response.code}"
96
+ end
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,26 @@
1
+ class Yammer::Message
2
+
3
+ attr_reader :id, :url, :web_url, :replied_to_id, :thread_id,
4
+ :body_plain, :body_parsed, :message_type, :client_type,
5
+ :sender_id, :sender_type
6
+
7
+ def initialize(m)
8
+ @id = m['id']
9
+ @url = m['url']
10
+ @web_url = m['web_url']
11
+ @replied_to_id = m['replied_to_id']
12
+ @thread_id = m['thread_id']
13
+ @body_plain = m['body']['plain']
14
+ @body_parsed = m['body']['parsed']
15
+ @message_type = m['message_type']
16
+ @client_type = m['client_type']
17
+ @sender_id = m['sender_id']
18
+ @sender_type = m['sender_type']
19
+ begin
20
+ @created_at = m['created_at']
21
+ rescue ArgumentError => e
22
+ @created_at = nil
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,20 @@
1
+ class Yammer::MessageList < Array
2
+
3
+ attr_reader :older_available, :ids
4
+
5
+ def initialize(a, oa, c)
6
+ super(a)
7
+ @older_available = oa
8
+ @client = c
9
+ @ids = a.map {|m| m.id}.sort
10
+ end
11
+
12
+ def first
13
+ self[0]
14
+ end
15
+
16
+ def last
17
+ self[self.size - 1]
18
+ end
19
+
20
+ end
@@ -0,0 +1,17 @@
1
+ class Yammer::User
2
+ extend Forwardable
3
+ def_delegator :@user, :id
4
+
5
+ def initialize(mash, client)
6
+ @user = mash
7
+ @client = client
8
+ end
9
+
10
+ def me?
11
+ @user.id == @client.me.id
12
+ end
13
+
14
+ def method_missing(call, *args)
15
+ @user.send(call, *args)
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ require 'forwardable'
2
+ require 'rubygems'
3
+ require 'date'
4
+ require 'yaml'
5
+ require 'open-uri'
6
+
7
+ gem 'json', '>= 1.1.7'
8
+ require 'json'
9
+
10
+ gem 'oauth', '>=0.3.5'
11
+ require 'oauth'
12
+
13
+ gem 'mash', '>=0.0.3'
14
+ require 'mash'
15
+
16
+ $:.unshift(File.dirname(__FILE__))
17
+ require 'ext/core_ext'
18
+ require 'yammer/client'
19
+ require 'yammer/message'
20
+ require 'yammer/message_list'
21
+ require 'yammer/user'
@@ -0,0 +1,7 @@
1
+ consumer:
2
+ key: CLIENT_KEY
3
+ secret: CLIENT_SECRET
4
+
5
+ access:
6
+ token: CONSUMER_TOKEN
7
+ secret: CONSUMER_SECRET
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
2
+ require 'yammer4r'
3
+ require 'spec'
@@ -0,0 +1,53 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'ostruct'
3
+
4
+ describe Yammer::Client do
5
+
6
+ context "creating" do
7
+
8
+ before(:each) do
9
+ mock_consumer = mock(OAuth::Consumer)
10
+ OAuth::Consumer.stub!("new").and_return(mock_consumer)
11
+ @mock_http = mock("http")
12
+ mock_consumer.stub!("http").and_return(@mock_http)
13
+ end
14
+
15
+ it "can be configured to be verbose" do
16
+ @mock_http.should_receive("set_debug_output").with($stderr)
17
+ Yammer::Client.new(:consumer => {}, :access => {}, :verbose => true)
18
+ end
19
+
20
+ it "should not be configured to be verbose unless asked to be" do
21
+ @mock_http.should_not_receive("set_debug_output")
22
+ Yammer::Client.new(:consumer => {}, :access => {})
23
+ end
24
+
25
+ it "should not be configured to be verbose if asked not to be" do
26
+ @mock_http.should_not_receive("set_debug_output")
27
+ Yammer::Client.new(:consumer => {}, :access => {}, :verbose => false)
28
+ end
29
+
30
+ end
31
+
32
+ context "users" do
33
+
34
+ before(:each) do
35
+ @mock_access_token = mock(OAuth::AccessToken)
36
+ @response = OpenStruct.new(:code => 200, :body => '{}')
37
+ OAuth::AccessToken.stub!("new").and_return(@mock_access_token)
38
+ @client = Yammer::Client.new(:consumer => {}, :access => {})
39
+ end
40
+
41
+ it "should request the first page by default" do
42
+ @mock_access_token.should_receive("get").with("/api/v1/users.json").and_return(@response)
43
+ @client.users
44
+ end
45
+
46
+ it "can request a specified page" do
47
+ @mock_access_token.should_receive("get").with("/api/v1/users.json?page=2").and_return(@response)
48
+ @client.users(:page => 2)
49
+ end
50
+
51
+ end
52
+
53
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pmoran-yammer4r
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Jim Patterson
8
+ - Jason Stewart
9
+ - Peter Moran
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-12-29 00:00:00 +11:00
15
+ default_executable:
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: mash
19
+ type: :runtime
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 0.0.3
26
+ version:
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ type: :runtime
30
+ version_requirement:
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 1.1.7
36
+ version:
37
+ - !ruby/object:Gem::Dependency
38
+ name: oauth
39
+ type: :runtime
40
+ version_requirement:
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 0.3.5
46
+ version:
47
+ description: Yammer4R provides an object based API to query or update your Yammer account via pure Ruby. It hides the ugly HTTP/REST code from your code.
48
+ email: workingpeter@gmail.com
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ extra_rdoc_files: []
54
+
55
+ files:
56
+ - README
57
+ - example.rb
58
+ - Rakefile
59
+ - TODO
60
+ - oauth.yml.template
61
+ - bin/yammer_create_oauth_yml.rb
62
+ - spec/spec_helper.rb
63
+ - spec/yammer/client_spec.rb
64
+ - lib/ext/core_ext.rb
65
+ - lib/yammer/client.rb
66
+ - lib/yammer/message.rb
67
+ - lib/yammer/message_list.rb
68
+ - lib/yammer/user.rb
69
+ - lib/yammer4r.rb
70
+ has_rdoc: true
71
+ homepage: http://github.com/pmoran/yammer4r
72
+ licenses: []
73
+
74
+ post_install_message:
75
+ rdoc_options: []
76
+
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ version:
91
+ requirements: []
92
+
93
+ rubyforge_project:
94
+ rubygems_version: 1.3.5
95
+ signing_key:
96
+ specification_version: 2
97
+ summary: Yammer access for ruby
98
+ test_files: []
99
+