cronofy 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b7af5ec983510f03b2d3ef8361becea185d8a0d1
4
- data.tar.gz: 13a2b60a3c2b377c80b8ad9f41b6587c41c8c57e
3
+ metadata.gz: bf3f22a7f76781d1e6ea8671f870cf5fd4b159a3
4
+ data.tar.gz: d4d4aea42bf0198af8af3bc7cab228eadf224c90
5
5
  SHA512:
6
- metadata.gz: 7a7872c4415fba00b2797cc0ce953b4cbdf0a9b6b36b09a065ffa2660334f00002e8a127e02a70edee7259c63bb520b117e06a97de3a1c8583950e3c443b0f59
7
- data.tar.gz: f1f5875132b96a55ad8d22e2a9816585ee2bbb1efef786314f1850592496c0ef7c07f57149b1ba7c45a67c354ea8ba94a1cae8aa4e097a9234c53eb412829f6c
6
+ metadata.gz: f495b40c4541fddd2a58eaa26371bed12bafa0760a332ff0c389a9fa8b7955526ab48fdd1081bd7097a566cd0f7bda5a103d95488711fa57edcadd1cee381657
7
+ data.tar.gz: 453719f98f0620ee3bc0d4f61fe1c61c19f09fa5f8362685f8e64d9d6f64f5feeb0a30075d0ff8f7b5d1889d1ac3d82925f08837cc06387ffe47b743a5e7734d
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ script: 'script/ci'
3
+ rvm:
4
+ - 2.0
5
+ - 2.1
6
+ - 2.2
7
+ - jruby-head
8
+ - rbx-2
9
+ - ruby-head
10
+ notifications:
11
+ webhooks:
12
+ urls:
13
+ - https://webhooks.gitter.im/e/9ca8d56f4d3a17425b18
14
+ on_success: change # options: [always|never|change] default: always
15
+ on_failure: always # options: [always|never|change] default: always
16
+ on_start: false # default: false
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Cronofy
2
2
 
3
+ [![Build Status](https://travis-ci.org/cronofy/cronofy-ruby.svg?branch=master)](https://travis-ci.org/cronofy/cronofy-ruby)
4
+ [![Gem Version](https://badge.fury.io/rb/cronofy.svg)](http://badge.fury.io/rb/cronofy)
3
5
  [![Join the chat at https://gitter.im/cronofy/cronofy-ruby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cronofy/cronofy-ruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
6
 
5
7
  [Cronofy](http://www.cronofy.com) - one API for all the calendars (Google, Outlook, iCloud, Exchange). This gem is an interface for easy use of [Cronofy API](http://www.cronofy.com/developers/api) with Ruby.
@@ -86,3 +88,7 @@ To delete an event from user's calendar:
86
88
  ```ruby
87
89
  cronofy.delete_event(calendar_id, event_id)
88
90
  ```
91
+
92
+ ## Links
93
+
94
+ * [API mailing list](https://groups.google.com/d/forum/cronofy-api)
@@ -1,40 +1,114 @@
1
1
  require "cronofy/version"
2
2
  require "cronofy/auth"
3
3
  require "cronofy/response_parser"
4
+ require "cronofy/errors"
4
5
 
5
6
  module Cronofy
6
7
  class Cronofy
7
8
 
8
- def initialize(client_id, client_secret, token = false)
9
- @auth = Auth.new(client_id, client_secret, token)
9
+ def initialize(client_id, client_secret, token=nil, refresh_token=nil)
10
+ @auth = Auth.new(client_id, client_secret, token, refresh_token)
10
11
  end
11
12
 
13
+ def access_token!
14
+ raise CredentialsMissingError.new unless @auth.access_token
15
+ @auth.access_token
16
+ end
17
+
18
+ # Public : Lists the calendars or the user across all of the calendar accounts
19
+ # see http://www.cronofy.com/developers/api#calendars
20
+ #
21
+ # Returns Hash of calendars
12
22
  def list_calendars
13
- ResponseParser.new(request(:get, 'calendars')).parse_json
23
+ response = do_request { access_token!.get("/v1/calendars") }
24
+ ResponseParser.new(response).parse_json
14
25
  end
15
26
 
16
- def create_or_update_event(calendar_id, event_data)
17
- event_data[:start] = event_data[:start].utc.iso8601
18
- event_data[:end] = event_data[:end].utc.iso8601
19
- request(:post, "calendars/#{calendar_id}/events", event_data)
27
+ # Public : Creates or updates an existing event that matches the event_id, in the calendar
28
+ # see: http://www.cronofy.com/developers/api#upsert-event
29
+ # aliased as upsert_event
30
+ #
31
+ # calendar_id - String Cronofy ID for the the calendar to contain the event
32
+ # event - Hash describing the event with symbolized keys.
33
+ # :event_id String client identifier for event NOT Cronofy's
34
+ # :summary String
35
+ # :start Time
36
+ # :end Time
37
+ #
38
+ # Returns nothing
39
+ def create_or_update_event(calendar_id, event)
40
+ body = event.dup
41
+ body[:start] = event[:start].utc.iso8601
42
+ body[:end] = event[:end].utc.iso8601
43
+
44
+ headers = {
45
+ 'Content-Type' => 'application/json'
46
+ }
47
+
48
+ do_request { access_token!.post("/v1/calendars/#{calendar_id}/events", { body: body.to_json, headers: headers }) }
20
49
  end
50
+ alias_method :upsert_event, :create_or_update_event
21
51
 
52
+ # Public : Deletes an event from the specified calendar
53
+ # see http://www.cronofy.com/developers/api#delete-event
54
+ #
55
+ # calendar_id - String Cronofy ID for the calendar containing the event
56
+ # event_id - String client ID for the event
57
+ #
58
+ # Returns nothing
22
59
  def delete_event(calendar_id, event_id)
23
- request(:delete, "calendars/#{calendar_id}/events", event_id: event_id)
60
+ params = { event_id: event_id }
61
+
62
+ do_request { access_token!.delete("/v1/calendars/#{calendar_id}/events", { params: params }) }
24
63
  end
25
64
 
26
- def user_auth_link(redirect_uri)
27
- @auth.user_auth_link(redirect_uri)
65
+ # Public : Generate the authorization URL to send the user to in order to generate
66
+ # and authorization code in order for an access_token to be issued
67
+ # see http://www.cronofy.com/developers/api#authorization
68
+ #
69
+ # redirect_uri - String URI to return the user to once authorization process completed
70
+ # scope - Array of scopes describing access required to the users calendars (default: all scopes)
71
+ #
72
+ # Returns String
73
+ def user_auth_link(redirect_uri, scope=nil)
74
+ @auth.user_auth_link(redirect_uri, scope)
28
75
  end
29
76
 
77
+ # Public : Returns the access_token for a given code and redirect_uri pair
78
+ # see http://www.cronofy.com/developers/api#token-issue
79
+ #
80
+ # code - String code returned to redirect_uri after authorization
81
+ # redirect_uri - String URI returned to
82
+ #
83
+ # Returns Cronofy::Credentials
30
84
  def get_token_from_code(code, redirect_uri)
31
85
  @auth.get_token_from_code(code, redirect_uri)
32
86
  end
33
87
 
34
- private
88
+ # Public : Refreshes the access_token and periodically the refresh_token for authorization
89
+ # see http://www.cronofy.com/developers/api#token-refresh
90
+ #
91
+ # Returns Cronofy::Credentials
92
+ def refresh_access_token
93
+ @auth.refresh!
94
+ end
95
+
96
+ private
97
+
98
+ ERROR_MAP = {
99
+ 401 => AuthorizationFailureError,
100
+ 404 => NotFoundError,
101
+ 422 => InvalidRequestError,
102
+ 429 => TooManyRequestsError
103
+ }
35
104
 
36
- def request(method, path, params = {})
37
- @auth.request.send(method, "/v1/#{path}", params: params)
105
+ def do_request(&block)
106
+ begin
107
+ block.call
108
+ rescue OAuth2::Error => e
109
+ error_class = ERROR_MAP.fetch(e.response.status, UnknownError)
110
+ raise error_class.new(e.response.headers['status'], e.response)
111
+ end
38
112
  end
39
113
 
40
114
  end
@@ -2,28 +2,77 @@ require "oauth2"
2
2
 
3
3
  module Cronofy
4
4
  class Auth
5
- API_URL = 'https://api.cronofy.com'
6
5
  APP_URL = 'https://app.cronofy.com'
6
+ API_URL = 'https://api.cronofy.com'
7
+
8
+ class Credentials
9
+
10
+ attr_reader :access_token,
11
+ :expires_at,
12
+ :expires_in,
13
+ :refresh_token
7
14
 
8
- def initialize(client_id, client_secret, token)
9
- @client = OAuth2::Client.new(client_id, client_secret, site: API_URL)
10
- @token = token
15
+ def initialize(oauth_token)
16
+ @access_token = oauth_token.token
17
+ @expires_at = oauth_token.expires_at
18
+ @expires_in = oauth_token.expires_in
19
+ @refresh_token = oauth_token.refresh_token
20
+ end
21
+
22
+ def to_hash
23
+ {
24
+ access_token: access_token,
25
+ refresh_token: refresh_token,
26
+ expires_in: expires_in,
27
+ expires_at: expires_at
28
+ }
29
+ end
11
30
  end
12
31
 
13
- def user_auth_link(redirect_uri)
14
- url = @client.auth_code.authorize_url(
15
- :redirect_uri => redirect_uri,
16
- :response_type => 'code'
17
- ).gsub(API_URL, APP_URL)
18
- "#{url}&scope=list_calendars read_events create_event delete_event"
32
+ attr_reader :access_token
33
+
34
+ def initialize(client_id, client_secret, token=nil, refresh_token=nil)
35
+ @auth_client = OAuth2::Client.new(client_id, client_secret, site: APP_URL)
36
+ @api_client = OAuth2::Client.new(client_id, client_secret, site: API_URL)
37
+
38
+ set_access_token(token, refresh_token) if token
39
+ end
40
+
41
+ # Public: generate a URL for authorizing the application with Cronofy
42
+ #
43
+ # redirect_uri String, the URI to return to after authorization
44
+ # scope Array of String, the scope requested
45
+ # Default: [read_account, list_calendars, read_events, create_event, delete_event]
46
+ # see: http://www.cronofy.com/developers/api#authorization
47
+ #
48
+ # Returns String URL
49
+ def user_auth_link(redirect_uri, scope=nil)
50
+ scope ||= %w{read_account list_calendars read_events create_event delete_event}
51
+
52
+ @auth_client.auth_code.authorize_url(:redirect_uri => redirect_uri, :response_type => 'code', :scope => scope.join(' '))
19
53
  end
20
54
 
21
55
  def get_token_from_code(code, redirect_uri)
22
- @client.auth_code.get_token(code, :redirect_uri => redirect_uri).token
56
+ auth_token = @auth_client.auth_code.get_token(code, :redirect_uri => redirect_uri)
57
+ set_access_token_from_auth_token(auth_token)
58
+ Credentials.new(@access_token)
59
+ end
60
+
61
+ # Public: Refreshes the access token
62
+ # Returns Hash of token elements to allow client to update in local store for user
63
+ def refresh!
64
+ auth_token = access_token.refresh!
65
+ set_access_token_from_auth_token(auth_token)
66
+ Credentials.new(@access_token)
23
67
  end
24
68
 
25
- def request
26
- @request ||= OAuth2::AccessToken.new(@client, @token)
69
+ def set_access_token_from_auth_token(auth_token)
70
+ set_access_token(auth_token.token, auth_token.refresh_token)
27
71
  end
72
+
73
+ def set_access_token(token, refresh_token)
74
+ @access_token = OAuth2::AccessToken.new(@api_client, token, { refresh_token: refresh_token })
75
+ end
76
+
28
77
  end
29
78
  end
@@ -0,0 +1,55 @@
1
+ module Cronofy
2
+ class CronofyError < StandardError
3
+
4
+ end
5
+
6
+ class CredentialsMissingError < CronofyError
7
+
8
+ def initialize(message=nil)
9
+ super(message || "No credentials supplied")
10
+ end
11
+
12
+ end
13
+
14
+ class APIError < CronofyError
15
+ attr_reader :response
16
+
17
+ def initialize(message, response=nil)
18
+ super(message)
19
+ @response = response
20
+ end
21
+
22
+ def body
23
+ response.body if response
24
+ end
25
+
26
+ def headers
27
+ response.headers if response
28
+ end
29
+
30
+ def inspect
31
+ "<#{self.class.name} message=#{message} headers=#{headers.inspect} body=#{body}>"
32
+ end
33
+ end
34
+
35
+ class NotFoundError < APIError
36
+
37
+ end
38
+
39
+ class AuthorizationFailureError < APIError
40
+
41
+ end
42
+
43
+ class InvalidRequestError < APIError
44
+
45
+ end
46
+
47
+ class TooManyRequestsError < APIError
48
+
49
+ end
50
+
51
+ class UnknownError < APIError
52
+
53
+ end
54
+
55
+ end
@@ -1,3 +1,3 @@
1
1
  module Cronofy
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,7 @@
1
+ #! /bin/bash
2
+
3
+ # Fail fast
4
+ set -o errexit
5
+
6
+ bundle install
7
+ bundle exec rake spec
metadata CHANGED
@@ -1,69 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cronofy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergii Paryzhskyi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-11 00:00:00.000000000 Z
11
+ date: 2015-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.7'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.7'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '3.2'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.2'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: oauth2
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.0'
69
69
  description:
@@ -73,7 +73,8 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
- - .gitignore
76
+ - ".gitignore"
77
+ - ".travis.yml"
77
78
  - Gemfile
78
79
  - LICENSE.txt
79
80
  - README.md
@@ -81,8 +82,10 @@ files:
81
82
  - cronofy.gemspec
82
83
  - lib/cronofy.rb
83
84
  - lib/cronofy/auth.rb
85
+ - lib/cronofy/errors.rb
84
86
  - lib/cronofy/response_parser.rb
85
87
  - lib/cronofy/version.rb
88
+ - script/ci
86
89
  - spec/response_parser_spec.rb
87
90
  - spec/spec_helper.rb
88
91
  homepage: https://github.com/cronofy/cronofy-ruby
@@ -95,17 +98,17 @@ require_paths:
95
98
  - lib
96
99
  required_ruby_version: !ruby/object:Gem::Requirement
97
100
  requirements:
98
- - - '>='
101
+ - - ">="
99
102
  - !ruby/object:Gem::Version
100
103
  version: '0'
101
104
  required_rubygems_version: !ruby/object:Gem::Requirement
102
105
  requirements:
103
- - - '>='
106
+ - - ">="
104
107
  - !ruby/object:Gem::Version
105
108
  version: '0'
106
109
  requirements: []
107
110
  rubyforge_project:
108
- rubygems_version: 2.4.5
111
+ rubygems_version: 2.2.2
109
112
  signing_key:
110
113
  specification_version: 4
111
114
  summary: Cronofy - one API for all the calendars