cronofy 0.0.2 → 0.0.3

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.
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