google_calendar 0.6.2 → 0.7.0

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,4 +1,7 @@
1
1
  ---
2
+ SHA256:
3
+ metadata.gz: acefcd4148fb09fb9ae42a28e6e2ebe85507e3388cc9a83c9ae79ec36eaa9349
4
+ data.tar.gz: b4df360b6242f88fcbd9d85cf32200bd47561e3482a0fad413904fc421e6832c
2
5
  SHA512:
3
- metadata.gz: 37b7d1c2914d9c4975ff8477a94a5c5ae18d5cb8dacf089bbadb1a16414984adc4b606a97a08f52b9baae9beb018344c6cf6616f65d1064d4c5499d7ddc494a9
4
- data.tar.gz: be2f3af778d82be79cebfac47135c2441363eeeffeed43d7eab04a3935f192b287fcc79b9b55b3bd02ccb6beac58eaf33c75db9d2a947efe42aadf64e106a25b
6
+ metadata.gz: 7705625116e7cc2c86f74c88d22f714d210f6ba955eab9775520883ee9274b6d624e118cae0d1401775bc2b28b4d5ed2ee4842652afdd2eb5dc019b61e904e50
7
+ data.tar.gz: 99e7c4f88747a310a2cafebd561a521c432b10fe40b7ddc658d891297fe978ec15f9d4f6ffa01c0b379800983d11ffbda3474ace8aa40e2a2ba028459a08d64e
data/.env.test CHANGED
@@ -3,4 +3,4 @@ CLIENT_SECRET='roBgdbfEmJwPgrgi2mRbbO-f'
3
3
  REFRESH_TOKEN='1/eiqBWx8aj-BsdhwvlzDMFOUN1IN_HyThvYTujyksO4c'
4
4
  CALENDAR_ID='klei8jnelo09nflqehnvfzipgs@group.calendar.google.com'
5
5
  ACCESS_TOKEN='ya29.hYjPO0uHt63uWr5qmQtMEReZEvILcdGlPCOHDy6quKPyEQaQQvqaVAlLAVASaRm_O0a7vkZ91T8xyQ'
6
- REDIRECT_URL='urn:ietf:wg:oauth:2.0:oob'
6
+ REDIRECT_URL='https://mytesturl.com/'
@@ -0,0 +1,27 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby-version:
16
+ - '3.2'
17
+ - '3.3'
18
+ - '3.4'
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - name: Set up Ruby ${{ matrix.ruby-version }}
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: ${{ matrix.ruby-version }}
25
+ bundler-cache: true
26
+ - name: Run tests
27
+ run: bundle exec rake test
data/Gemfile CHANGED
@@ -1,5 +1,4 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Using google_calendar to manage dependencies
4
- gemspec
5
- gem "codeclimate-test-reporter", group: :test, require: nil
4
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,78 +1,104 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- google_calendar (0.6.1)
5
- TimezoneParser (~> 0.2.0)
6
- json (>= 1.8.3, < 2.1)
4
+ google_calendar (0.7.0)
5
+ TimezoneParser (>= 0.3, < 1.1)
6
+ addressable (> 2.7.0)
7
+ json (>= 1.8.3)
7
8
  signet (~> 0.7)
9
+ sorted_set (~> 1.0)
8
10
 
9
11
  GEM
10
- remote: http://rubygems.org/
12
+ remote: https://rubygems.org/
11
13
  specs:
12
- TimezoneParser (0.2.0)
14
+ TimezoneParser (1.0.0)
13
15
  insensitive_hash
16
+ sqlite3
14
17
  tzinfo
15
- addressable (2.5.0)
16
- public_suffix (~> 2.0, >= 2.0.2)
18
+ addressable (2.9.0)
19
+ public_suffix (>= 2.0.2, < 8.0)
17
20
  ansi (1.5.0)
18
- builder (3.2.3)
19
- codeclimate-test-reporter (1.0.5)
20
- simplecov
21
+ base64 (0.3.0)
22
+ builder (3.2.4)
23
+ concurrent-ruby (1.3.7)
21
24
  docile (1.1.5)
22
- dotenv (2.2.0)
23
- faraday (0.11.0)
24
- multipart-post (>= 1.2, < 3)
25
+ dotenv (2.7.6)
26
+ erb (6.0.4)
27
+ faraday (2.14.3)
28
+ faraday-net_http (>= 2.0, < 3.5)
29
+ json
30
+ logger
31
+ faraday-net_http (3.4.4)
32
+ net-http (~> 0.5)
25
33
  insensitive_hash (0.3.3)
26
- json (2.0.3)
27
- jwt (1.5.6)
28
- metaclass (0.0.4)
29
- minitest (5.10.1)
30
- minitest-reporters (1.1.14)
34
+ json (2.3.1)
35
+ jwt (3.2.0)
36
+ base64
37
+ logger (1.7.0)
38
+ mini_portile2 (2.8.9)
39
+ minitest (5.27.0)
40
+ minitest-reporters (1.4.2)
31
41
  ansi
32
42
  builder
33
43
  minitest (>= 5.0)
34
44
  ruby-progressbar
35
- mocha (1.2.1)
36
- metaclass (~> 0.0.1)
37
- multi_json (1.12.1)
38
- multipart-post (2.0.0)
39
- public_suffix (2.0.5)
40
- rake (11.3.0)
41
- rb-fsevent (0.9.8)
42
- rdoc (4.3.0)
43
- ruby-progressbar (1.8.1)
44
- shoulda-context (1.2.2)
45
- signet (0.7.3)
46
- addressable (~> 2.3)
47
- faraday (~> 0.9)
48
- jwt (~> 1.5)
49
- multi_json (~> 1.10)
50
- simplecov (0.13.0)
51
- docile (~> 1.1.0)
52
- json (>= 1.8, < 3)
53
- simplecov-html (~> 0.10.0)
54
- simplecov-html (0.10.0)
45
+ mocha (2.8.2)
46
+ ruby2_keywords (>= 0.0.5)
47
+ net-http (0.9.1)
48
+ uri (>= 0.11.1)
49
+ prism (1.9.0)
50
+ public_suffix (7.0.5)
51
+ rake (13.0.1)
52
+ rb-fsevent (0.10.4)
53
+ rbs (4.0.3)
54
+ logger
55
+ prism (>= 1.6.0)
56
+ tsort
57
+ rbtree (0.4.7)
58
+ rdoc (8.0.0)
59
+ erb
60
+ prism (>= 1.6.0)
61
+ rbs (>= 4.0.0)
62
+ tsort
63
+ ruby-progressbar (1.10.1)
64
+ ruby2_keywords (0.0.5)
65
+ shoulda-context (2.0.0)
66
+ signet (0.22.0)
67
+ addressable (~> 2.8)
68
+ faraday (>= 0.17.5, < 3.a)
69
+ jwt (>= 1.5, < 4.0)
70
+ simplecov (0.22.0)
71
+ docile (~> 1.1)
72
+ simplecov-html (~> 0.11)
73
+ simplecov_json_formatter (~> 0.1)
74
+ simplecov-html (0.13.2)
75
+ simplecov_json_formatter (0.1.4)
76
+ sorted_set (1.1.0)
77
+ rbtree
78
+ sqlite3 (2.9.5)
79
+ mini_portile2 (~> 2.8.0)
55
80
  terminal-notifier-guard (1.7.0)
56
- thread_safe (0.3.5)
57
- tzinfo (1.2.2)
58
- thread_safe (~> 0.1)
81
+ tsort (0.2.0)
82
+ tzinfo (2.0.2)
83
+ concurrent-ruby (~> 1.0)
84
+ uri (1.1.1)
59
85
 
60
86
  PLATFORMS
61
87
  ruby
62
88
 
63
89
  DEPENDENCIES
64
90
  bundler (>= 1.2)
65
- codeclimate-test-reporter
66
91
  dotenv (~> 2.1)
67
92
  google_calendar!
68
93
  minitest (~> 5.1)
69
- minitest-reporters (~> 1.0)
70
- mocha (~> 1.1)
71
- rake (~> 11)
94
+ minitest-reporters (~> 1.2)
95
+ mocha (~> 2.0)
96
+ rake (>= 11)
72
97
  rb-fsevent (~> 0.9)
73
- rdoc (~> 4.1)
74
- shoulda-context (~> 1.2)
98
+ rdoc (> 6.3.1)
99
+ shoulda-context (~> 2.0)
100
+ simplecov (~> 0.22)
75
101
  terminal-notifier-guard (~> 1.6)
76
102
 
77
103
  BUNDLED WITH
78
- 1.14.4
104
+ 4.0.3
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Steve Zich
1
+ Copyright (c) 2010 Northworld, LLC.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -2,31 +2,36 @@
2
2
 
3
3
  A fast lightweight and minimalist wrapper around the {Google Calendar}[https://www.google.com/calendar/] api.
4
4
 
5
- {<img src="https://badge.fury.io/rb/google_calendar.svg" alt="Gem Version" />}[http://badge.fury.io/rb/google_calendar] {<img src="https://travis-ci.org/northworld/google_calendar.png?branch=master" alt="Build Status" />}[https://travis-ci.org/northworld/google_calendar] {<img src="https://gemnasium.com/northworld/google_calendar.png" alt="Dependency Status" />}[https://gemnasium.com/northworld/google_calendar] {<img src="https://codeclimate.com/github/northworld/google_calendar/badges/gpa.svg" />}[https://codeclimate.com/github/northworld/google_calendar] {<img src="https://codeclimate.com/github/northworld/google_calendar/badges/coverage.svg" />}[https://codeclimate.com/github/northworld/google_calendar]
5
+ {<img src="https://badge.fury.io/rb/google_calendar.svg" alt="Gem Version" />}[http://badge.fury.io/rb/google_calendar] {<img src="https://github.com/northworld/google_calendar/actions/workflows/ci.yml/badge.svg" alt="Build Status" />}[https://github.com/northworld/google_calendar/actions/workflows/ci.yml]
6
6
  == Install
7
7
  [sudo] gem install 'google_calendar'
8
8
 
9
9
  == Setup
10
10
 
11
+ <b>Important Changes: Google no longer supports the 'urn:ietf:wg:oauth:2.0:oob' out-of-band OAuth method. You must setup your OAuth Credentials with a publically accessible URL where you can grab your code from the URL paramaters after approving the OAuth request. If your product is a Web Application, you can automate this set up by pointing the redirect_url to the appropriate method of your application.</b>
12
+
11
13
  <b>Obtain a Client ID and Secret</b>
12
14
 
13
15
  1. Go to the {Google Developers Console}[https://console.developers.google.com/].
14
- 1. Select a project, or create a new one.
15
- 1. In the sidebar on the left, expand APIs & auth. Next, click APIs. In the list of APIs, make sure the status is ON for the Calendar API.
16
+ 1. Select a project, or create a new one (at the top of the page).
17
+ 1. In the sidebar on the left, select Library.
18
+ 1. Type in 'Google Calendar' in the search box and click on 'Google Calendar API' in the results.
19
+ 1. Click on the 'Enable' link at the top of the page.
16
20
  1. In the sidebar on the left, select Credentials.
17
- 1. In either case, you end up on the Credentials page and can create your project's credentials from here.
18
- 1. If you haven't done so already, create your OAuth 2.0 credentials by clicking Create new Client ID under the OAuth heading. Next, look for your application's client ID and client secret in the relevant table. You may also create and edit redirect URIs from this page.
19
-
20
- <em>Take note of the Client ID as you'll need to add it to your code later.</em>
21
+ 1. If you haven't done so already, create your 'OAuth client ID' by clicking 'Create Credentials -> OAuth client ID'. Choose Web Application as the type.
22
+ 1. You must also provide an "Authorized redirect URIs" which is a publically reachable URL where google will redirect to after the OAuth approval. Google will append the paramater 'code=<your auth code>' to this URL during redirection which will include the necessary code to authenticate the usage of this application.
23
+ 1. <em>Take note of the Client ID and Client Secret as you'll need to add it to your code later.</em>
24
+ 1. In the sidebar on the left, select "OAuth consent screen". You must setup your Application Name, and add "Test users" if this is for personal use (i.e. you are setting up links to at limited set of known users' calendars), or "Publish" your app if this is for public use.
21
25
 
22
26
  <b>Find your calendar ID</b>
23
27
 
24
28
  1. Visit {Google Calendar}[https://www.google.com/calendar/] in your web browser.
25
- 1. In the calendar list on the left, click the down-arrow button next to the appropriate calendar, then select Calendar settings.
26
- 1. In the Calendar Address section, locate the Calendar ID listed next to the XML, ICAL and HTML buttons.
29
+ 1. In the calendar list on the left, click the three vertical dots next to the appropriate calendar, then select 'Settings and sharing'.
30
+ 1. From the left toolbar, choose 'Integrate Calendar'.
31
+ 1. In the Integrate Calendar section, locate the Calendar ID at the top of the section.
27
32
  1. Copy the Calendar ID.
28
33
 
29
- == Usage
34
+ == Usage (readme_code.rb)
30
35
  require 'rubygems'
31
36
  require 'google_calendar'
32
37
 
@@ -34,7 +39,7 @@ A fast lightweight and minimalist wrapper around the {Google Calendar}[https://w
34
39
  cal = Google::Calendar.new(:client_id => YOUR_CLIENT_ID,
35
40
  :client_secret => YOUR_SECRET,
36
41
  :calendar => YOUR_CALENDAR_ID,
37
- :redirect_url => "urn:ietf:wg:oauth:2.0:oob" # this is what Google uses for 'applications'
42
+ :redirect_url => YOUR_REDIRECT_URL # This must match a url you permitted in your OAuth setting
38
43
  )
39
44
 
40
45
  puts "Do you already have a refresh token? (y/n)"
@@ -45,7 +50,7 @@ A fast lightweight and minimalist wrapper around the {Google Calendar}[https://w
45
50
  # A user needs to approve access in order to work with their calendars.
46
51
  puts "Visit the following web page in your browser and approve access."
47
52
  puts cal.authorize_url
48
- puts "\nCopy the code that Google returned and paste it here:"
53
+ puts "\nCopy the code out of the paramters after Google redirects you to your provided redirect_url"
49
54
 
50
55
  # Pass the ONE TIME USE access code here to login and get a refresh token that you can use for access from now on.
51
56
  refresh_token = cal.login_with_auth_code( $stdin.gets.chomp )
@@ -89,7 +94,7 @@ A fast lightweight and minimalist wrapper around the {Google Calendar}[https://w
89
94
  This sample code is located in readme_code.rb in the root folder.
90
95
 
91
96
  == Ruby Support
92
- The current google_calendar gem supports Ruby 2.1 and higher -- because of the json gem dependency. We maintain support for Ruby 1.8.7, 1.9.3 and 2.0 on different branches.
97
+ The current google_calendar gem supports Ruby 3.2 and higher -- the +signet+ OAuth2 dependency requires it. Older Ruby versions (1.8.7 through 2.7) are maintained on different branches.
93
98
 
94
99
  == Notes
95
100
  * This is not a complete implementation of the calendar api, it just includes the features we needed to support our internal calendar integration. Feel free to add additional features and we will happily integrate them.
@@ -111,9 +116,9 @@ to +.env+ for use by Dotenv. You can also use +.env.default+ as your
111
116
  own starting point, just remember to copy it over to +.env+ before
112
117
  running tests.
113
118
 
114
- You can modify +.env+ with your own credentials and not worry about
119
+ You can modify +.env+ with your own credentials and don't worry about
115
120
  accidentally committing to the repo as +.env+ is in the +.gitignore+.
116
121
 
117
122
  == Copyright
118
123
 
119
- Copyright (c) 2010-2014 Steve Zich. See LICENSE.txt for further details.
124
+ Copyright (c) 2010-2022 Northworld, LLC. See LICENSE.txt for further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.1
1
+ 0.7.0
@@ -2,10 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "google_calendar"
5
- s.version = "0.6.2"
6
- s.date = "2017-02-17"
5
+ s.version = "0.7.0"
6
+ s.date = "2026-07-07"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
+ s.required_ruby_version = ">= 3.2"
9
10
 
10
11
  s.authors = ["Steve Zich"]
11
12
  s.email = "steve.zich@gmail.com"
@@ -24,21 +25,23 @@ Gem::Specification.new do |s|
24
25
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
26
 
26
27
  s.require_paths = ["lib"]
27
- s.rubygems_version = "2.6.10"
28
28
 
29
+ s.add_runtime_dependency(%q<addressable>, ["> 2.7.0"])
29
30
  s.add_runtime_dependency(%q<signet>, ["~> 0.7"])
30
- s.add_runtime_dependency(%q<json>, [">= 1.8.3", "< 2.1"])
31
- s.add_runtime_dependency(%q<TimezoneParser>, ["~> 0.2.0"])
31
+ s.add_runtime_dependency(%q<json>, [">= 1.8.3"])
32
+ s.add_runtime_dependency(%q<TimezoneParser>, ">= 0.3", "< 1.1")
33
+ s.add_runtime_dependency(%q<sorted_set>, ["~> 1.0"])
32
34
 
33
35
  s.add_development_dependency(%q<terminal-notifier-guard>, ["~> 1.6"])
34
36
  s.add_development_dependency(%q<rb-fsevent>, ["~> 0.9"])
35
37
  s.add_development_dependency(%q<minitest>, ["~> 5.1"])
36
- s.add_development_dependency(%q<minitest-reporters>, ["~> 1.0"])
37
- s.add_development_dependency(%q<shoulda-context>, ["~> 1.2"])
38
+ s.add_development_dependency(%q<minitest-reporters>, ["~> 1.2"])
39
+ s.add_development_dependency(%q<shoulda-context>, "~> 2.0")
38
40
  s.add_development_dependency(%q<bundler>, [">= 1.2"])
39
- s.add_development_dependency(%q<mocha>, ["~> 1.1"])
40
- s.add_development_dependency(%q<rake>, ["~> 11"])
41
- s.add_development_dependency(%q<rdoc>, ["~> 4.1"])
41
+ s.add_development_dependency(%q<mocha>, ["~> 2.0"])
42
+ s.add_development_dependency(%q<rake>, [">= 11"])
43
+ s.add_development_dependency(%q<rdoc>, ["> 6.3.1"])
42
44
  s.add_development_dependency(%q<dotenv>, ["~> 2.1"])
45
+ s.add_development_dependency(%q<simplecov>, ["~> 0.22"])
43
46
 
44
47
  end
@@ -6,15 +6,15 @@ module Google
6
6
  #
7
7
  class Calendar
8
8
 
9
- attr_reader :id, :connection, :summary
9
+ attr_reader :id, :connection, :summary, :location, :description, :time_zone
10
10
 
11
11
  #
12
12
  # Setup and connect to the specified Google Calendar.
13
13
  # the +params+ paramater accepts
14
14
  # * :client_id => the client ID that you received from Google after registering your application with them (https://console.developers.google.com/). REQUIRED
15
15
  # * :client_secret => the client secret you received from Google after registering your application with them. REQUIRED
16
- # * :redirect_url => the url where your users will be redirected to after they have successfully permitted access to their calendars. Use 'urn:ietf:wg:oauth:2.0:oob' if you are using an 'application'" REQUIRED
17
- # * :calendar_id => the id of the calendar you would like to work with (see Readme.rdoc for instructions on how to find yours)
16
+ # * :redirect_url => the url where your users will be redirected to after they have successfully permitted access to their calendars. REQUIRED
17
+ # * :calendar => the id of the calendar you would like to work with (see Readme.rdoc for instructions on how to find yours). REQUIRED
18
18
  # * :refresh_token => if a user has already given you access to their calendars, you can specify their refresh token here and you will be 'logged on' automatically (i.e. they don't need to authorize access again). OPTIONAL
19
19
  #
20
20
  # See Readme.rdoc or readme_code.rb for an explication on the OAuth2 authorization process.
@@ -23,7 +23,7 @@ module Google
23
23
  # Google::Calendar.new(:client_id => YOUR_CLIENT_ID,
24
24
  # :client_secret => YOUR_SECRET,
25
25
  # :calendar => YOUR_CALENDAR_ID,
26
- # :redirect_url => "urn:ietf:wg:oauth:2.0:oob" # this is what Google uses for 'applications'
26
+ # :redirect_url => "http://myapplicationurl.com/"
27
27
  # )
28
28
  #
29
29
  def initialize(params={}, connection=nil)
@@ -36,8 +36,11 @@ module Google
36
36
  # the +params+ paramater accepts
37
37
  # * :client_id => the client ID that you received from Google after registering your application with them (https://console.developers.google.com/). REQUIRED
38
38
  # * :client_secret => the client secret you received from Google after registering your application with them. REQUIRED
39
- # * :redirect_url => the url where your users will be redirected to after they have successfully permitted access to their calendars. Use 'urn:ietf:wg:oauth:2.0:oob' if you are using an 'application'" REQUIRED
40
- # * :summary => title of the calendar being created.
39
+ # * :redirect_url => the url where your users will be redirected to after they have successfully permitted access to their calendars. REQUIRED
40
+ # * :summary => title of the calendar being created. OPTIONAL
41
+ # * :location => geographic location of the calendar as free-form text. OPTIONAL
42
+ # * :time_zone => the time zone of the calendar. (Formatted as an IANA Time Zone Database name, e.g. "Europe/Zurich".) OPTIONAL
43
+ # * :description => description of the calendar. OPTIONAL
41
44
  # * :refresh_token => if a user has already given you access to their calendars, you can specify their refresh token here and you will be 'logged on' automatically (i.e. they don't need to authorize access again). OPTIONAL
42
45
  #
43
46
  # See Readme.rdoc or readme_code.rb for an explication on the OAuth2 authorization process.
@@ -47,16 +50,98 @@ module Google
47
50
  # :client_id => YOUR_CLIENT_ID,
48
51
  # :client_secret => YOUR_SECRET,
49
52
  # :summary => 'Test Calendar',
50
- # :redirect_url => "urn:ietf:wg:oauth:2.0:oob" # this is what Google uses for 'applications'
53
+ # :location => 'Somewhere',
54
+ # :description => 'Test Calendar Description',
55
+ # :time_zone => 'Europe/Zurich',
56
+ # :redirect_url => "http://myapplicationurl.com/"
51
57
  # )
52
58
  #
53
59
  def self.create(params={}, connection=nil)
54
60
  cal = new(params, connection)
55
61
  cal.instance_variable_set(:@summary, params[:summary])
62
+ cal.instance_variable_set(:@location, params[:location])
63
+ cal.instance_variable_set(:@description, params[:description])
64
+ cal.instance_variable_set(:@time_zone, params[:time_zone])
56
65
 
57
66
  cal.save
58
67
  end
59
68
 
69
+ #
70
+ # Connect and retrieve a Google Calendar.
71
+ # the +params+ paramater accepts
72
+ # * :client_id => the client ID that you received from Google after registering your application with them (https://console.developers.google.com/). REQUIRED
73
+ # * :client_secret => the client secret you received from Google after registering your application with them. REQUIRED
74
+ # * :redirect_url => the url where your users will be redirected to after they have successfully permitted access to their calendars. REQUIRED
75
+ # * :calendar => the id of the calendar you would like to work with (see Readme.rdoc for instructions on how to find yours). REQUIRED
76
+ # * :refresh_token => if a user has already given you access to their calendars, you can specify their refresh token here and you will be 'logged on' automatically (i.e. they don't need to authorize access again). OPTIONAL
77
+ #
78
+ # See Readme.rdoc or readme_code.rb for an explication on the OAuth2 authorization process.
79
+ #
80
+ # ==== Example
81
+ # Google::Calendar.get(
82
+ # :client_id => YOUR_CLIENT_ID,
83
+ # :client_secret => YOUR_SECRET,
84
+ # :calendar => YOUR_CALENDAR_ID,
85
+ # :redirect_url => "http://myapplicationurl.com/"
86
+ # )
87
+ #
88
+ def self.get(params={}, connection=nil)
89
+ cal = new(params, connection)
90
+ cal.retrieve_calendar
91
+ end
92
+
93
+ #
94
+ # Connect and update a Google Calendar.
95
+ # the +params+ paramater accepts
96
+ # * :summary => title of the calendar being created. OPTIONAL
97
+ # * :location => geographic location of the calendar as free-form text. OPTIONAL
98
+ # * :time_zone => the time zone of the calendar. (Formatted as an IANA Time Zone Database name, e.g. "Europe/Zurich".) OPTIONAL
99
+ # * :description => description of the calendar. OPTIONAL
100
+ # * :refresh_token => if a user has already given you access to their calendars, you can specify their refresh token here and you will be 'logged on' automatically (i.e. they don't need to authorize access again). OPTIONAL
101
+ #
102
+ # See Readme.rdoc or readme_code.rb for an explication on the OAuth2 authorization process.
103
+ #
104
+ # ==== Example
105
+ # google_calendar_object.update(
106
+ # :summary => 'Test Calendar',
107
+ # :location => 'Somewhere',
108
+ # :description => 'Test Calendar Description',
109
+ # :time_zone => 'Europe/Zurich',
110
+ # )
111
+ #
112
+ def update(params={})
113
+ instance_variable_set(:@summary, params[:summary])
114
+ instance_variable_set(:@location, params[:location])
115
+ instance_variable_set(:@description, params[:description])
116
+ instance_variable_set(:@time_zone, params[:time_zone])
117
+
118
+ response =
119
+ send_calendar_request(
120
+ "/#{@id}",
121
+ :put,
122
+ {
123
+ summary: @summary,
124
+ location: @location,
125
+ description: @description,
126
+ timeZone: @time_zone,
127
+ }.to_json
128
+ )
129
+ @raw = JSON.parse(response.body)
130
+ self
131
+ end
132
+
133
+ #
134
+ # Destroy a Google Calendar.
135
+ #
136
+ # See Readme.rdoc or readme_code.rb for an explication on the OAuth2 authorization process.
137
+ #
138
+ # ==== Example
139
+ # google_calendar_object.destroy
140
+ #
141
+ def destroy
142
+ send_calendar_request("/#{@id}", :delete)
143
+ end
144
+
60
145
  #
61
146
  # The URL you need to send a user in order to let them grant you access to their calendars.
62
147
  #
@@ -105,10 +190,27 @@ module Google
105
190
  # the calendar that was saved.
106
191
  #
107
192
  def save
108
- response = send_calendar_request("/", :post, {:summary => @summary}.to_json)
193
+ response = send_calendar_request("/", :post, {:summary => @summary}.to_json)
109
194
  update_after_save(response)
110
195
  end
111
196
 
197
+ #
198
+ # Get an existing calender.
199
+ # Returns:
200
+ # the calendar that was requested.
201
+ #
202
+ def retrieve_calendar
203
+ response = send_calendar_request("/#{@id}", :get)
204
+ @raw = JSON.parse(response.body)
205
+ instance_variable_set(:@summary, @raw['summary'])
206
+ instance_variable_set(:@location, @raw['location'])
207
+ instance_variable_set(:@description, @raw['description'])
208
+ instance_variable_set(:@time_zone, @raw['timeZone'])
209
+ @html_link = @raw['htmlLink']
210
+
211
+ self
212
+ end
213
+
112
214
  #
113
215
  # Find all of the events associated with this calendar.
114
216
  # Returns:
@@ -269,8 +371,10 @@ module Google
269
371
  # If the event is no longer on the server it creates a new one with the specified values.
270
372
  # Works like the create_event method.
271
373
  #
272
- def find_or_create_event_by_id(id, &blk)
273
- if id && event = find_event_by_id(id)[0]
374
+ def find_or_create_event_by_id(id, &blk)
375
+ event = id ? find_event_by_id(id)[0] : nil
376
+
377
+ if event
274
378
  setup_event(event, &blk)
275
379
  elsif id
276
380
  event = Event.new(id: id, new_event_with_id_specified: true)
@@ -290,12 +394,12 @@ module Google
290
394
  body = event.use_quickadd? ? nil : event.to_json
291
395
  notifications = "sendNotifications=#{event.send_notifications?}"
292
396
  query_string = if event.use_quickadd?
293
- "/quickAdd?#{notifications}&text=#{event.title}"
294
- elsif event.new_event?
295
- "?#{notifications}"
296
- else # update existing event.
297
- "/#{event.id}?#{notifications}"
298
- end
397
+ "/quickAdd?#{notifications}&text=#{event.title}"
398
+ elsif event.new_event?
399
+ "?#{notifications}"
400
+ else # update existing event.
401
+ "/#{event.id}?#{notifications}"
402
+ end
299
403
 
300
404
  send_events_request(query_string, method, body)
301
405
  end
@@ -13,7 +13,7 @@ module Google
13
13
  # The +params+ parameter accepts
14
14
  # * :client_id => the client ID that you received from Google after registering your application with them (https://console.developers.google.com/). REQUIRED
15
15
  # * :client_secret => the client secret you received from Google after registering your application with them. REQUIRED
16
- # * :redirect_url => the url where your users will be redirected to after they have successfully permitted access to their calendars. Use 'urn:ietf:wg:oauth:2.0:oob' if you are using an 'application'" REQUIRED
16
+ # * :redirect_url => the url where your users will be redirected to after they have successfully permitted access to their calendars. REQUIRED
17
17
  # * :refresh_token => if a user has already given you access to their calendars, you can specify their refresh token here and you will be 'logged on' automatically (i.e. they don't need to authorize access again). OPTIONAL
18
18
  #
19
19
  # See Readme.rdoc or readme_code.rb for an explication on the OAuth2 authorization process.
@@ -9,12 +9,13 @@ module Google
9
9
  BASE_URI = "https://www.googleapis.com/calendar/v3"
10
10
  TOKEN_URI ="https://accounts.google.com/o/oauth2/token"
11
11
  AUTH_URI = "https://accounts.google.com/o/oauth2/auth"
12
- SCOPE = "https://www.googleapis.com/auth/calendar"
12
+ DEFAULT_SCOPE = "https://www.googleapis.com/auth/calendar"
13
+
13
14
  attr_accessor :client
14
15
 
15
16
  def self.new_with_service_account(params)
16
17
  client = Signet::OAuth2::Client.new(
17
- :scope => SCOPE,
18
+ :scope => params.fetch(:scope, DEFAULT_SCOPE),
18
19
  :issuer => params[:client_id],
19
20
  :audience => TOKEN_URI,
20
21
  :token_credential_uri => TOKEN_URI,
@@ -43,8 +44,9 @@ module Google
43
44
  # the +params+ paramater accepts
44
45
  # * :client_id => the client ID that you received from Google after registering your application with them (https://console.developers.google.com/)
45
46
  # * :client_secret => the client secret you received from Google after registering your application with them.
46
- # * :redirect_uri => the url where your users will be redirected to after they have successfully permitted access to their calendars. Use 'urn:ietf:wg:oauth:2.0:oob' if you are using an 'application'"
47
+ # * :redirect_uri => the url where your users will be redirected to after they have successfully permitted access to their calendars."
47
48
  # * :refresh_token => if a user has already given you access to their calendars, you can specify their refresh token here and you will be 'logged on' automatically (i.e. they don't need to authorize access again)
49
+ # * :scope => Optional. The scope of the access request, expressed either as an Array or as a space-delimited String.
48
50
  #
49
51
  def initialize(params, client=nil)
50
52
 
@@ -58,7 +60,7 @@ module Google
58
60
  :state => params[:state],
59
61
  :authorization_uri => AUTH_URI,
60
62
  :token_credential_uri => TOKEN_URI,
61
- :scope => SCOPE
63
+ :scope => params.fetch(:scope, DEFAULT_SCOPE)
62
64
  )
63
65
 
64
66
  # try to get an access token if possible.
@@ -153,15 +155,33 @@ module Google
153
155
 
154
156
  #
155
157
  # Check for common HTTP Errors and raise the appropriate response.
158
+ # Note: error 401 (InvalidCredentialsError) is handled by Signet.
156
159
  #
157
160
  def check_for_errors(response) #:nodoc
158
161
  case response.status
159
162
  when 400 then raise HTTPRequestFailed, response.body
163
+ when 403 then parse_403_error(response)
160
164
  when 404 then raise HTTPNotFound, response.body
165
+ when 409 then raise RequestedIdentifierAlreadyExistsError, response.body
166
+ when 410 then raise GoneError, response.body
167
+ when 412 then raise PreconditionFailedError, response.body
168
+ when 500 then raise BackendError, response.body
161
169
  end
162
170
  end
163
171
 
164
- private
172
+ #
173
+ # Utility method to centralize handling of 403 errors.
174
+ #
175
+ def parse_403_error(response)
176
+ case JSON.parse(response.body)["error"]["message"]
177
+ when "Forbidden" then raise ForbiddenError, response.body
178
+ when "Daily Limit Exceeded" then raise DailyLimitExceededError, response.body
179
+ when "User Rate Limit Exceeded" then raise UserRateLimitExceededError, response.body
180
+ when "Rate Limit Exceeded" then raise RateLimitExceededError, response.body
181
+ when "Calendar usage limits exceeded." then raise CalendarUsageLimitExceededError, response.body
182
+ else raise ForbiddenError, response.body
183
+ end
184
+ end
165
185
 
166
186
  #
167
187
  # Utility method to centralize credential validation.