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.
data/lib/google/errors.rb CHANGED
@@ -1,8 +1,78 @@
1
1
  module Google
2
- class HTTPRequestFailed < StandardError; end
2
+ # Signet::AuthorizationError
3
+ # Not part of Google Calendar API Errors
3
4
  class HTTPAuthorizationFailed < StandardError; end
5
+
6
+ # Google Calendar API Errors per documentation
7
+ # https://developers.google.com/google-apps/calendar/v3/errors
8
+
9
+ # 400: Bad Request
10
+ #
11
+ # User error. This can mean that a required field or parameter has not been
12
+ # provided, the value supplied is invalid, or the combination of provided
13
+ # fields is invalid.
14
+ class HTTPRequestFailed < StandardError; end
15
+
16
+ # 401: Invalid Credentials
17
+ #
18
+ # Invalid authorization header. The access token you're using is either
19
+ # expired or invalid.
20
+ class InvalidCredentialsError < StandardError; end
21
+
22
+ # 403: Daily Limit Exceeded
23
+ #
24
+ # The Courtesy API limit for your project has been reached.
25
+ class DailyLimitExceededError < StandardError; end
26
+
27
+ # 403: User Rate Limit Exceeded
28
+ #
29
+ # The per-user limit from the Developer Console has been reached.
30
+ class UserRateLimitExceededError < StandardError; end
31
+
32
+ # 403: Rate Limit Exceeded
33
+ #
34
+ # The user has reached Google Calendar API's maximum request rate per
35
+ # calendar or per authenticated user.
36
+ class RateLimitExceededError < StandardError; end
37
+
38
+ # 403: Calendar usage limits exceeded
39
+ #
40
+ # The user reached one of the Google Calendar limits in place to protect
41
+ # Google users and infrastructure from abusive behavior.
42
+ class CalendarUsageLimitExceededError < StandardError; end
43
+
44
+ # 404: Not Found
45
+ #
46
+ # The specified resource was not found.
4
47
  class HTTPNotFound < StandardError; end
5
- class HTTPTooManyRedirections < StandardError; end
6
- class InvalidCalendar < StandardError; end
7
- class CalenarIDMissing < StandardError; end
48
+
49
+ # 409: The requested identifier already exists
50
+ #
51
+ # An instance with the given ID already exists in the storage.
52
+ class RequestedIdentifierAlreadyExistsError < StandardError; end
53
+
54
+ # 410: Gone
55
+ #
56
+ # SyncToken or updatedMin parameters are no longer valid. This error can also
57
+ # occur if a request attempts to delete an event that has already been
58
+ # deleted.
59
+ class GoneError < StandardError; end
60
+
61
+ # 412: Precondition Failed
62
+ #
63
+ # The etag supplied in the If-match header no longer corresponds to the
64
+ # current etag of the resource.
65
+ class PreconditionFailedError < StandardError; end
66
+
67
+ # 500: Backend Error
68
+ #
69
+ # An unexpected error occurred while processing the request.
70
+ class BackendError < StandardError; end
71
+
72
+ #
73
+ # 403: Forbidden Error
74
+ #
75
+ # User has no authority to conduct the requested operation on the resource.
76
+ # This is not a part of official Google Calendar API Errors documentation.
77
+ class ForbiddenError < StandardError; end
8
78
  end
data/lib/google/event.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'time'
2
2
  require 'json'
3
+ require 'sorted_set' # TimezoneParser relies on the top-level SortedSet, removed from stdlib in Ruby 3.2+
3
4
  require 'timezone_parser'
4
5
 
5
6
  module Google
@@ -120,7 +121,7 @@ module Google
120
121
  # Returns whether the Event is an all-day event, based on whether the event starts at the beginning and ends at the end of the day.
121
122
  #
122
123
  def all_day?
123
- time = (@start_time.is_a? String) ? Time.parse(@start_time) : @start_time.dup.utc
124
+ time = (@start_time.is_a? String) ? Time.parse(@start_time) : @start_time.dup.utc
124
125
  duration % (24 * 60 * 60) == 0 && time == Time.local(time.year,time.month,time.day)
125
126
  end
126
127
 
@@ -216,10 +217,10 @@ module Google
216
217
  # You can pass true or false. Defaults to transparent.
217
218
  #
218
219
  def transparency=(val)
219
- if val == false || val.to_s.downcase == 'opaque'
220
- @transparency = 'opaque'
221
- else
220
+ if val == true || val.to_s.downcase == 'transparent'
222
221
  @transparency = 'transparent'
222
+ else
223
+ @transparency = 'opaque'
223
224
  end
224
225
  end
225
226
 
@@ -314,7 +315,7 @@ module Google
314
315
  return {} unless @attendees
315
316
 
316
317
  attendees = @attendees.map do |attendee|
317
- attendee.select { |k,v| ['displayName', 'email', 'responseStatus'].include?(k) }
318
+ attendee.select { |k,_v| ['displayName', 'email', 'responseStatus'].include?(k) }
318
319
  end
319
320
 
320
321
  { "attendees" => attendees }
@@ -396,7 +397,7 @@ module Google
396
397
  def extended_properties_attributes
397
398
  return {} unless @extended_properties && (@extended_properties['shared'] || @extended_properties['private'])
398
399
 
399
- { "extendedProperties" => @extended_properties.select {|k,v| ['shared', 'private'].include?(k) } }
400
+ { "extendedProperties" => @extended_properties.select {|k,_v| ['shared', 'private'].include?(k) } }
400
401
  end
401
402
 
402
403
  #
@@ -16,7 +16,7 @@ module Google
16
16
  # The +params+ parameter accepts
17
17
  # * :client_id => the client ID that you received from Google after registering your application with them (https://console.developers.google.com/). REQUIRED
18
18
  # * :client_secret => the client secret you received from Google after registering your application with them. REQUIRED
19
- # * :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
19
+ # * :redirect_url => the url where your users will be redirected to after they have successfully permitted access to their calendars. REQUIRED
20
20
  # * :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
21
21
  #
22
22
  # See Readme.rdoc or readme_code.rb for an explication on the OAuth2 authorization process.
@@ -46,7 +46,7 @@ module Google
46
46
  private
47
47
 
48
48
  #
49
- # Prepare the JSON
49
+ # Prepare the JSON
50
50
  #
51
51
  def json_for_query(calendar_ids, start_time, end_time)
52
52
  {}.tap{ |obj|
@@ -62,10 +62,9 @@ module Google
62
62
  return nil unless query_result['calendars'].is_a? Hash
63
63
 
64
64
  query_result['calendars'].each_with_object({}) do |(calendar_id, value), result|
65
+ value['busy'].each { |date_times| date_times.transform_values! { |date_time| DateTime.parse(date_time) } }
65
66
  result[calendar_id] = value['busy'] || []
66
67
  end
67
68
  end
68
-
69
69
  end
70
-
71
70
  end
data/readme_code.rb CHANGED
@@ -12,7 +12,7 @@ require 'google_calendar'
12
12
  cal = Google::Calendar.new(:client_id => YOUR_CLIENT_ID,
13
13
  :client_secret => YOUR_SECRET,
14
14
  :calendar => YOUR_CALENDAR_ID,
15
- :redirect_url => "urn:ietf:wg:oauth:2.0:oob" # this is what Google uses for 'applications'
15
+ :redirect_url => YOUR_REDIRECT_URL # this is what Google uses for 'applications'
16
16
  )
17
17
 
18
18
  puts "Do you already have a refresh token? (y/n)"
@@ -23,7 +23,7 @@ if has_token.downcase != 'y'
23
23
  # A user needs to approve access in order to work with their calendars.
24
24
  puts "Visit the following web page in your browser and approve access."
25
25
  puts cal.authorize_url
26
- puts "\nCopy the code that Google returned and paste it here:"
26
+ puts "\nCopy the code out of the paramters after Google redirects you to your provided redirect_url"
27
27
 
28
28
  # Pass the ONE TIME USE access code here to login and get a refresh token that you can use for access from now on.
29
29
  refresh_token = cal.login_with_auth_code( $stdin.gets.chomp )
data/test/helper.rb CHANGED
@@ -14,7 +14,7 @@ end
14
14
  require "minitest/autorun"
15
15
  require 'minitest/reporters'
16
16
  require 'shoulda/context'
17
- require 'mocha/setup'
17
+ require 'mocha/minitest'
18
18
  require 'faraday'
19
19
 
20
20
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
@@ -0,0 +1,15 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "calendar",
6
+ "reason": "timeRangeEmpty",
7
+ "message": "The specified time range is empty.",
8
+ "locationType": "parameter",
9
+ "location": "timeMax",
10
+ }
11
+ ],
12
+ "code": 400,
13
+ "message": "The specified time range is empty."
14
+ }
15
+ }
data/test/mocks/401.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
- "error": {
3
- "code": 401,
4
- "message": "Invalid Credentials",
5
- "errors": [
6
- {
7
- "locationType": "header",
8
- "domain": "global",
9
- "message": "Invalid Credentials",
10
- "reason": "authError",
11
- "location": "Authorization"
12
- }
13
- ]
14
- }
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "global",
6
+ "reason": "authError",
7
+ "message": "Invalid Credentials",
8
+ "locationType": "header",
9
+ "location": "Authorization",
10
+ }
11
+ ],
12
+ "code": 401,
13
+ "message": "Invalid Credentials"
14
+ }
15
15
  }
@@ -0,0 +1,13 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "usageLimits",
6
+ "message": "Calendar usage limits exceeded.",
7
+ "reason": "quotaExceeded"
8
+ }
9
+ ],
10
+ "code": 403,
11
+ "message": "Calendar usage limits exceeded."
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "usageLimits",
6
+ "reason": "dailyLimitExceeded",
7
+ "message": "Daily Limit Exceeded"
8
+ }
9
+ ],
10
+ "code": 403,
11
+ "message": "Daily Limit Exceeded"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "usageLimits",
6
+ "reason": "ForbiddenError",
7
+ "message": "Forbidden"
8
+ }
9
+ ],
10
+ "code": 403,
11
+ "message": "Forbidden"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "usageLimits",
6
+ "reason": "rateLimitExceeded",
7
+ "message": "Rate Limit Exceeded"
8
+ }
9
+ ],
10
+ "code": 403,
11
+ "message": "Rate Limit Exceeded"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "usageLimits",
6
+ "reason": "SomeRandomError",
7
+ "message": "RandomError"
8
+ }
9
+ ],
10
+ "code": 403,
11
+ "message": "RandomError"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "usageLimits",
6
+ "reason": "userRateLimitExceeded",
7
+ "message": "User Rate Limit Exceeded"
8
+ }
9
+ ],
10
+ "code": 403,
11
+ "message": "User Rate Limit Exceeded"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "global",
6
+ "reason": "duplicate",
7
+ "message": "The requested identifier already exists."
8
+ }
9
+ ],
10
+ "code": 409,
11
+ "message": "The requested identifier already exists."
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "global",
6
+ "reason": "deleted",
7
+ "message": "Resource has been deleted"
8
+ }
9
+ ],
10
+ "code": 410,
11
+ "message": "Resource has been deleted"
12
+ }
13
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "global",
6
+ "reason": "conditionNotMet",
7
+ "message": "Precondition Failed",
8
+ "locationType": "header",
9
+ "location": "If-Match",
10
+ }
11
+ ],
12
+ "code": 412,
13
+ "message": "Precondition Failed"
14
+ }
15
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "error": {
3
+ "errors": [
4
+ {
5
+ "domain": "global",
6
+ "reason": "backendError",
7
+ "message": "Backend Error",
8
+ }
9
+ ],
10
+ "code": 500,
11
+ "message": "Backend Error"
12
+ }
13
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "kind": "calendar#calendar",
3
+ "etag": "\"W8S50vTLOjlc76YTrehSZVQwSEE/ai1KY6CkM6KpTpfYTn2jy_Z5fsc\"",
4
+ "id": "djg1ts9g20ih03ccb0fgsegkio@group.calendar.google.com",
5
+ "summary": "A New Calendar"
6
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "kind": "calendar#calendar",
3
+ "etag": "\"W8S50vTLOjlc76YTghtSZVQwSEE/cpIguMlgGWrAb4L_lleRpa2ALCA\"",
4
+ "id": "gqeb0i6v737kfu5md0f35htjlg@group.calendar.google.com",
5
+ "summary": "Some Calendar",
6
+ "description": "Our work events",
7
+ "location": "Portland",
8
+ "timeZone": "America/Los_Angeles"
9
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "kind": "calendar#calendar",
3
+ "etag": "\"W8S50vTLOjlc76YTghtSZVQwSEE/cpIguMlgGWrAb4L_lleRpa2ALCA\"",
4
+ "id": "gqeb0i6v737kfu5md0f35htjlg@group.calendar.google.com",
5
+ "summary": "Our Company",
6
+ "description": "Work event list"
7
+ }