evernote_oauth 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Copyright (c) 2007-2012 by Evernote Corporation, All rights reserved.
3
+ *
4
+ * Use of the source code and binary libraries included in this package
5
+ * is permitted under the following terms:
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions
9
+ * are met:
10
+ *
11
+ * 1. Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * 2. Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ Evernote OAuth / Thrift API client library for Ruby
2
+ ===================================================
3
+ Evernote OAuth version 0.01
4
+ Evernote API version 1.21
5
+
6
+ Install the gem
7
+ ---------------
8
+ gem install evernote_oauth
9
+
10
+ Prerequisites
11
+ -------------
12
+ In order to use the code in this SDK, you need to obtain an API key from http://dev.evernote.com/documentation/cloud. You'll also find full API documentation on that page.
13
+
14
+ In order to run the sample code, you need a user account on the sandbox service where you will do your development. Sign up for an account at https://sandbox.evernote.com/Registration.action
15
+
16
+ In order to run the client client sample code, you need a developer token. Get one at https://sandbox.evernote.com/api/DeveloperToken.action
17
+
18
+ Setup
19
+ -----
20
+ Put your API keys in the config/evernote.yml
21
+ ```ruby
22
+ development:
23
+ consumer_key: YOUR CONSUMER KEY
24
+ consumer_secret: YOUR CONSUMER SECRET
25
+ sandbox: [true or false]
26
+ ```
27
+ Or you can just pass those information when you create an instance of the client
28
+ ```ruby
29
+ client = EvernoteOAuth::Client.new(
30
+ consumer_key: YOUR CONSUMER KEY
31
+ consumer_secret: YOUR CONSUMER SECRET
32
+ sandbox: [true or false]
33
+ )
34
+ ```
35
+
36
+ Usage
37
+ -----
38
+ ```ruby
39
+ client = EvernoteOAuth::Client.new
40
+ request_token = client.request_token(:oauth_callback => 'YOUR CALLBACK URL')
41
+ request_token.authorize_url
42
+ => https://sandbox.evernote.com/OAuth.action?oauth_token=OAUTH_TOKEN
43
+ ```
44
+ To obtain the access token
45
+ ```ruby
46
+ access_token = request_token.get_access_token(oauth_verifier: params[:oauth_verifier])
47
+ ```
48
+ Now you can make other API calls
49
+ ```ruby
50
+ client = EvernoteOAuth::Client.new(token: access_token.token)
51
+ note_store = client.note_store
52
+ notebooks = note_store.listNotebooks(access_token.token)
53
+ ```
54
+
55
+ References
56
+ ----------
57
+ - Evernote Developers: http://dev.evernote.com/
58
+ - API Document: http://dev.evernote.com/documentation/reference/
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'evernote_oauth/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = %q{evernote_oauth}
9
+ s.version = EvernoteOAuth::VERSION
10
+
11
+ s.authors = ["Kentaro Suzuki"]
12
+ s.date = %q{2012-08-14}
13
+ s.description = %q{evernote_oauth is a Ruby client for the Evernote API using OAuth and Thrift.}
14
+ s.email = %q{ksuzuki@gmail.com}
15
+ s.files = ["LICENSE", "README.md", "evernote_oauth.gemspec"] + Dir.glob('{lib,spec,vendor}/**/*')
16
+ s.has_rdoc = false
17
+ s.homepage = %q{http://github.com/rekotan/evernote_oauth}
18
+ s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{evernote_oauth}
21
+ s.rubygems_version = %q{0.0.1}
22
+ s.summary = %q{evernote_oauth is a Ruby client for the Evernote API using OAuth and Thrift.}
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 2
27
+
28
+ s.add_dependency 'oauth', '>= 0.4.1'
29
+ s.add_dependency 'thrift_client', '>= 0.8.1'
30
+ s.add_development_dependency 'rspec'
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'thrift_client'
3
+ require 'oauth'
4
+ require 'yaml'
5
+
6
+ vendor_path = File.expand_path(File.dirname(__FILE__) + "/../vendor")
7
+ $LOAD_PATH.unshift "#{vendor_path}/evernote/edam"
8
+
9
+ require "#{vendor_path}/evernote"
10
+
11
+ require 'evernote_oauth/client'
12
+ require 'evernote_oauth/user_store'
13
+ require 'evernote_oauth/note_store'
14
+ require 'evernote_oauth/version'
15
+
16
+ # Path Thrift 0.8.0 Gem for Ruby 1.9.3 compatibility
17
+ # See: http://discussion.evernote.com/topic/15321-evernote-ruby-thrift-client-error/
18
+ #
19
+ if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('1.9.3') &&
20
+ Gem.loaded_specs['thrift'].version == Gem::Version.new('0.8.0')
21
+ module Thrift
22
+ class HTTPClientTransport < BaseTransport
23
+
24
+ def flush
25
+ http = Net::HTTP.new @url.host, @url.port
26
+ http.use_ssl = @url.scheme == "https"
27
+ resp, data = http.post(@url.request_uri, @outbuf, @headers)
28
+ # Was: @inbuf = StringIO.new data
29
+ @inbuf = StringIO.new resp.body
30
+ @outbuf = ""
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,65 @@
1
+ module EvernoteOAuth
2
+ class Client
3
+
4
+ def initialize(options={})
5
+ config_file = "config/evernote.yml"
6
+ if File.exist?(config_file)
7
+ config = YAML.load(ERB.new(File.read(config_file)).result)[Rails.env]
8
+ @consumer_key = config['consumer_key']
9
+ @consumer_secret = config['consumer_secret']
10
+ @sandbox = config['sandbox'] ? true : false
11
+ end
12
+
13
+ @consumer_key ||= options[:consumer_key]
14
+ @consumer_secret ||= options[:consumer_secret]
15
+ @sandbox ||= (options[:sandbox] == nil ? true : options[:sandbox])
16
+ @token = options[:token]
17
+ @secret = options[:secret]
18
+ end
19
+
20
+ def authorize(token, secret, options={})
21
+ request_token = OAuth::RequestToken.new(consumer, token, secret)
22
+ @access_token = request_token.get_access_token(options)
23
+ @token = @access_token.token
24
+ @secret = @access_token.secret
25
+ @access_token
26
+ end
27
+
28
+ def request_token(options={})
29
+ consumer.get_request_token(options)
30
+ end
31
+
32
+ def authentication_request_token(options={})
33
+ consumer.options[:authorize_path] = '/OAuth.action'
34
+ request_token(options)
35
+ end
36
+
37
+ private
38
+ def consumer
39
+ @consumer ||= OAuth::Consumer.new(
40
+ @consumer_key,
41
+ @consumer_secret,
42
+ {site: endpoint,
43
+ request_token_path: "/oauth",
44
+ access_token_path: "/oauth"}
45
+ )
46
+ end
47
+
48
+ def endpoint(path=nil)
49
+ url = @sandbox ? "https://sandbox.evernote.com" : "https://www.evernote.com"
50
+ url += "/#{path}" if path
51
+ url
52
+ end
53
+
54
+ def access_token
55
+ @access_token ||= OAuth::AccessToken.new(consumer, @token, @secret)
56
+ end
57
+
58
+ def thrift_client(client_class, url, options={})
59
+ @thrift_client = ThriftClient.new(client_class, url, options.merge(
60
+ transport: Thrift::HTTPClientTransport))
61
+ end
62
+
63
+ end
64
+ end
65
+
@@ -0,0 +1,23 @@
1
+ module EvernoteOAuth
2
+
3
+ class Client
4
+ def note_store(options={})
5
+ @note_store = EvernoteOAuth::NoteStore.new(
6
+ client: thrift_client(::Evernote::EDAM::NoteStore::NoteStore::Client,
7
+ user_store(options).getNoteStoreUrl(@token),
8
+ options)
9
+ )
10
+ end
11
+ end
12
+
13
+ class NoteStore
14
+ def initialize(options={})
15
+ @client = options[:client]
16
+ end
17
+
18
+ def method_missing(name, *args, &block)
19
+ @client.send(name, *args, &block)
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,29 @@
1
+ module EvernoteOAuth
2
+
3
+ class Client
4
+ def user_store(options={})
5
+ @user_store = EvernoteOAuth::UserStore.new(
6
+ client: thrift_client(::Evernote::EDAM::UserStore::UserStore::Client,
7
+ endpoint('edam/user'), options)
8
+ )
9
+ end
10
+ end
11
+
12
+ class UserStore
13
+ def initialize(options={})
14
+ @client = options[:client]
15
+ raise 'API version is not up to date' unless version_valid?
16
+ end
17
+
18
+ def method_missing(name, *args, &block)
19
+ @client.send(name, *args, &block)
20
+ end
21
+
22
+ def version_valid?
23
+ checkVersion("EDAMTest",
24
+ ::Evernote::EDAM::UserStore::EDAM_VERSION_MAJOR,
25
+ ::Evernote::EDAM::UserStore::EDAM_VERSION_MINOR)
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,3 @@
1
+ module EvernoteOAuth
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,55 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper")
2
+
3
+ describe "EvernoteOAuth::Client" do
4
+ before :each do
5
+ @client = EvernoteOAuth::Client.new(
6
+ consumer_key: 'consumer_key',
7
+ consumer_secret: 'consumer_secret',
8
+ sandbox: false,
9
+ token: 'token',
10
+ secret: 'secret'
11
+ )
12
+ end
13
+ context "#initialize" do
14
+ it "assigns instance variables" do
15
+ @client.instance_variable_get(:@consumer_key).should == 'consumer_key'
16
+ @client.instance_variable_get(:@consumer_secret).should == 'consumer_secret'
17
+ @client.instance_variable_get(:@sandbox).should == false
18
+ @client.instance_variable_get(:@token).should == 'token'
19
+ @client.instance_variable_get(:@secret).should == 'secret'
20
+ end
21
+ end
22
+ context "#authorize" do
23
+ it "assigns returns access token" do
24
+ mock_access_token = mock(OAuth::AccessToken)
25
+ mock_access_token.should_receive(:token).and_return('token')
26
+ mock_access_token.should_receive(:secret).and_return('secret')
27
+ mock_request_token = mock(OAuth::RequestToken)
28
+ mock_request_token.should_receive(:get_access_token).and_return(mock_access_token)
29
+ OAuth::RequestToken.stub(:new){mock_request_token}
30
+
31
+ @client.authorize('token', 'secret').should == mock_access_token
32
+ end
33
+ end
34
+ context "#request_token" do
35
+ it "calls OAuth::Consumer#get_request_token" do
36
+ mock_request_token = mock(OAuth::RequestToken)
37
+ mock_consumer = mock(OAuth::Consumer)
38
+ mock_consumer.should_receive(:get_request_token).and_return(mock_request_token)
39
+ @client.should_receive(:consumer).and_return(mock_consumer)
40
+ @client.request_token.should == mock_request_token
41
+ end
42
+ end
43
+ context "#authentication_request_token" do
44
+ it "calls request_token with 'authorize_path' options" do
45
+ option = {}
46
+ mock_request_token = mock(OAuth::RequestToken)
47
+ mock_consumer = mock(OAuth::Consumer)
48
+ mock_consumer.should_receive(:options).and_return(option)
49
+ @client.should_receive(:consumer).and_return(mock_consumer)
50
+ @client.should_receive(:request_token).and_return(mock_request_token)
51
+ @client.authentication_request_token.should == mock_request_token
52
+ option[:authorize_path].should == '/OAuth.action'
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper")
2
+
3
+ describe "EvernoteOAuth::NoteStore" do
4
+ context "#initialize" do
5
+ it "assigns instance variables and checks version" do
6
+ note_store = EvernoteOAuth::NoteStore.new(client: 'client')
7
+ note_store.instance_variable_get(:@client).should == 'client'
8
+ end
9
+ end
10
+ context "#method_missing" do
11
+ it "dispatches method" do
12
+ mock_client = mock(Object)
13
+ mock_client.should_receive(:send).with(:call_method, 'args')
14
+ note_store = EvernoteOAuth::NoteStore.new(client: mock_client)
15
+ note_store.call_method('args')
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), "/../spec_helper")
2
+
3
+ describe "EvernoteOAuth::UserStore" do
4
+ context "#initialize" do
5
+ it "assigns instance variables and checks version" do
6
+ EvernoteOAuth::UserStore.any_instance.stub(:version_valid?){true}
7
+ user_store = EvernoteOAuth::UserStore.new(client: 'client')
8
+ user_store.instance_variable_get(:@client).should == 'client'
9
+ end
10
+ it "raises error when version is not valid" do
11
+ EvernoteOAuth::UserStore.any_instance.stub(:version_valid?){false}
12
+ lambda{EvernoteOAuth::UserStore.new(client: 'client')}.should raise_error
13
+ end
14
+ end
15
+ context "#method_missing" do
16
+ it "dispatches method" do
17
+ mock_client = mock(Object)
18
+ mock_client.should_receive(:send).with(:call_method, 'args')
19
+ EvernoteOAuth::UserStore.any_instance.stub(:version_valid?){true}
20
+ user_store = EvernoteOAuth::UserStore.new(client: mock_client)
21
+ user_store.call_method('args')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+ require 'evernote_oauth'
2
+ require 'rspec'
3
+
4
+ Dir.glob(File.join(File.join(File.dirname(__FILE__), "..", "lib"), "**")).each do |file|
5
+ require file
6
+ end
@@ -0,0 +1,12 @@
1
+ require 'set'
2
+ require 'errors_types'
3
+ require 'limits_constants'
4
+ require 'limits_types'
5
+ require 'note_store'
6
+ require 'note_store_constants'
7
+ require 'note_store_types'
8
+ require 'types_constants'
9
+ require 'types_types'
10
+ require 'user_store'
11
+ require 'user_store_constants'
12
+ require 'user_store_types'
@@ -0,0 +1,14 @@
1
+ #
2
+ # Autogenerated by Thrift Compiler (0.8.0)
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+ require 'errors_types'
8
+
9
+ module Evernote
10
+ module EDAM
11
+ module Error
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,128 @@
1
+ #
2
+ # Autogenerated by Thrift Compiler (0.8.0)
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+
8
+ module Evernote
9
+ module EDAM
10
+ module Error
11
+ module EDAMErrorCode
12
+ UNKNOWN = 1
13
+ BAD_DATA_FORMAT = 2
14
+ PERMISSION_DENIED = 3
15
+ INTERNAL_ERROR = 4
16
+ DATA_REQUIRED = 5
17
+ LIMIT_REACHED = 6
18
+ QUOTA_REACHED = 7
19
+ INVALID_AUTH = 8
20
+ AUTH_EXPIRED = 9
21
+ DATA_CONFLICT = 10
22
+ ENML_VALIDATION = 11
23
+ SHARD_UNAVAILABLE = 12
24
+ LEN_TOO_SHORT = 13
25
+ LEN_TOO_LONG = 14
26
+ TOO_FEW = 15
27
+ TOO_MANY = 16
28
+ UNSUPPORTED_OPERATION = 17
29
+ VALUE_MAP = {1 => "UNKNOWN", 2 => "BAD_DATA_FORMAT", 3 => "PERMISSION_DENIED", 4 => "INTERNAL_ERROR", 5 => "DATA_REQUIRED", 6 => "LIMIT_REACHED", 7 => "QUOTA_REACHED", 8 => "INVALID_AUTH", 9 => "AUTH_EXPIRED", 10 => "DATA_CONFLICT", 11 => "ENML_VALIDATION", 12 => "SHARD_UNAVAILABLE", 13 => "LEN_TOO_SHORT", 14 => "LEN_TOO_LONG", 15 => "TOO_FEW", 16 => "TOO_MANY", 17 => "UNSUPPORTED_OPERATION"}
30
+ VALID_VALUES = Set.new([UNKNOWN, BAD_DATA_FORMAT, PERMISSION_DENIED, INTERNAL_ERROR, DATA_REQUIRED, LIMIT_REACHED, QUOTA_REACHED, INVALID_AUTH, AUTH_EXPIRED, DATA_CONFLICT, ENML_VALIDATION, SHARD_UNAVAILABLE, LEN_TOO_SHORT, LEN_TOO_LONG, TOO_FEW, TOO_MANY, UNSUPPORTED_OPERATION]).freeze
31
+ end
32
+
33
+ # This exception is thrown by EDAM procedures when a call fails as a result of
34
+ # a problem that a user may be able to resolve. For example, if the user
35
+ # attempts to add a note to their account which would exceed their storage
36
+ # quota, this type of exception may be thrown to indicate the source of the
37
+ # error so that they can choose an alternate action.
38
+ #
39
+ # This exception would not be used for internal system errors that do not
40
+ # reflect user actions, but rather reflect a problem within the service that
41
+ # the user cannot resolve.
42
+ #
43
+ # errorCode: The numeric code indicating the type of error that occurred.
44
+ # must be one of the values of EDAMErrorCode.
45
+ #
46
+ # parameter: If the error applied to a particular input parameter, this will
47
+ # indicate which parameter.
48
+ class EDAMUserException < ::Thrift::Exception
49
+ include ::Thrift::Struct, ::Thrift::Struct_Union
50
+ ERRORCODE = 1
51
+ PARAMETER = 2
52
+
53
+ FIELDS = {
54
+ ERRORCODE => {:type => ::Thrift::Types::I32, :name => 'errorCode', :enum_class => Evernote::EDAM::Error::EDAMErrorCode},
55
+ PARAMETER => {:type => ::Thrift::Types::STRING, :name => 'parameter', :optional => true}
56
+ }
57
+
58
+ def struct_fields; FIELDS; end
59
+
60
+ def validate
61
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field errorCode is unset!') unless @errorCode
62
+ unless @errorCode.nil? || Evernote::EDAM::Error::EDAMErrorCode::VALID_VALUES.include?(@errorCode)
63
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field errorCode!')
64
+ end
65
+ end
66
+
67
+ ::Thrift::Struct.generate_accessors self
68
+ end
69
+
70
+ # This exception is thrown by EDAM procedures when a call fails as a result of
71
+ # an a problem in the service that could not be changed through user action.
72
+ #
73
+ # errorCode: The numeric code indicating the type of error that occurred.
74
+ # must be one of the values of EDAMErrorCode.
75
+ #
76
+ # message: This may contain additional information about the error
77
+ class EDAMSystemException < ::Thrift::Exception
78
+ include ::Thrift::Struct, ::Thrift::Struct_Union
79
+ ERRORCODE = 1
80
+ MESSAGE = 2
81
+
82
+ FIELDS = {
83
+ ERRORCODE => {:type => ::Thrift::Types::I32, :name => 'errorCode', :enum_class => Evernote::EDAM::Error::EDAMErrorCode},
84
+ MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message', :optional => true}
85
+ }
86
+
87
+ def struct_fields; FIELDS; end
88
+
89
+ def validate
90
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field errorCode is unset!') unless @errorCode
91
+ unless @errorCode.nil? || Evernote::EDAM::Error::EDAMErrorCode::VALID_VALUES.include?(@errorCode)
92
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field errorCode!')
93
+ end
94
+ end
95
+
96
+ ::Thrift::Struct.generate_accessors self
97
+ end
98
+
99
+ # This exception is thrown by EDAM procedures when a caller asks to perform
100
+ # an operation that does not exist. This may be thrown based on an invalid
101
+ # primary identifier (e.g. a bad GUID), or when the caller refers to an object
102
+ # by another unique identifier (e.g. a User's email address).
103
+ #
104
+ # identifier: the object identifier that was not found on the server.
105
+ #
106
+ # key: the value passed from the client in the identifier, which was not
107
+ # found. E.g. the GUID of an object that was not found.
108
+ class EDAMNotFoundException < ::Thrift::Exception
109
+ include ::Thrift::Struct, ::Thrift::Struct_Union
110
+ IDENTIFIER = 1
111
+ KEY = 2
112
+
113
+ FIELDS = {
114
+ IDENTIFIER => {:type => ::Thrift::Types::STRING, :name => 'identifier', :optional => true},
115
+ KEY => {:type => ::Thrift::Types::STRING, :name => 'key', :optional => true}
116
+ }
117
+
118
+ def struct_fields; FIELDS; end
119
+
120
+ def validate
121
+ end
122
+
123
+ ::Thrift::Struct.generate_accessors self
124
+ end
125
+
126
+ end
127
+ end
128
+ end