google_calendar 0.4.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ac5c278ba3dc50398192d02b52e133f0dbf7394d
4
+ data.tar.gz: 69d8905b95b054d7c373243f4237ce9dfc434c1e
5
+ SHA512:
6
+ metadata.gz: a5237336f30472193452d47bd2690b04ea6c574f86eafa2add99b97ad1ee6f90a489066fac7c47f18e4a630262847c14e44ce2713d764bd5f3a3b2508def7740
7
+ data.tar.gz: e54a2cb56293fd44585e15da46e236e0eef390d7cdff5efe23418be2bc096b1f471740f663cd3dddf9b22e620df65ee9241a752a9f57e12310843088baa904a8
data/Gemfile.lock CHANGED
@@ -1,82 +1,53 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- google_calendar (0.4.3)
4
+ google_calendar (0.5)
5
5
  json (~> 1.8)
6
- signet (~> 0.5)
6
+ signet (~> 0.6)
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- addressable (2.3.6)
12
- ansi (1.4.3)
11
+ addressable (2.3.8)
12
+ ansi (1.5.0)
13
13
  builder (3.2.2)
14
- celluloid (0.16.0)
15
- timers (~> 4.0.0)
16
- codeclimate-test-reporter (0.4.2)
14
+ codeclimate-test-reporter (0.4.7)
17
15
  simplecov (>= 0.7.1, < 1.0.0)
18
- coderay (1.1.0)
19
16
  docile (1.1.5)
20
- faraday (0.9.0)
17
+ extlib (0.9.16)
18
+ faraday (0.9.1)
21
19
  multipart-post (>= 1.2, < 3)
22
- ffi (1.9.6)
23
- formatador (0.2.5)
24
- guard (2.10.1)
25
- formatador (>= 0.2.4)
26
- listen (~> 2.7)
27
- lumberjack (~> 1.0)
28
- pry (>= 0.9.12)
29
- thor (>= 0.18.1)
30
- guard-minitest (2.3.2)
31
- guard (~> 2.0)
32
- minitest (>= 3.0)
33
- hitimes (1.2.2)
34
- json (1.8.1)
35
- jwt (1.2.0)
36
- listen (2.8.3)
37
- celluloid (>= 0.15.2)
38
- rb-fsevent (>= 0.9.3)
39
- rb-inotify (>= 0.9)
40
- lumberjack (1.0.9)
20
+ json (1.8.2)
21
+ jwt (1.5.0)
41
22
  metaclass (0.0.4)
42
- method_source (0.8.2)
43
- minitest (5.4.3)
44
- minitest-reporters (1.0.8)
23
+ minitest (5.6.1)
24
+ minitest-reporters (1.0.16)
45
25
  ansi
46
26
  builder
47
27
  minitest (>= 5.0)
48
28
  ruby-progressbar
49
29
  mocha (1.1.0)
50
30
  metaclass (~> 0.0.1)
51
- multi_json (1.10.1)
31
+ multi_json (1.11.0)
52
32
  multipart-post (2.0.0)
53
- pry (0.10.1)
54
- coderay (~> 1.1.0)
55
- method_source (~> 0.8.1)
56
- slop (~> 3.4)
57
33
  rake (10.4.2)
58
- rb-fsevent (0.9.4)
59
- rb-inotify (0.9.5)
60
- ffi (>= 0.5.0)
61
- rdoc (4.1.2)
34
+ rb-fsevent (0.9.5)
35
+ rdoc (4.2.0)
62
36
  json (~> 1.4)
63
- ruby-progressbar (1.7.0)
37
+ ruby-progressbar (1.7.5)
64
38
  shoulda-context (1.2.1)
65
- signet (0.5.1)
66
- addressable (>= 2.2.3)
67
- faraday (>= 0.9.0.rc5)
68
- jwt (>= 0.1.5)
69
- multi_json (>= 1.0.0)
70
- simplecov (0.9.1)
39
+ signet (0.6.0)
40
+ addressable (~> 2.3)
41
+ extlib (~> 0.9)
42
+ faraday (~> 0.9)
43
+ jwt (~> 1.0)
44
+ multi_json (~> 1.10)
45
+ simplecov (0.10.0)
71
46
  docile (~> 1.1.0)
72
- multi_json (~> 1.0)
73
- simplecov-html (~> 0.8.0)
74
- simplecov-html (0.8.0)
75
- slop (3.6.0)
47
+ json (~> 1.8)
48
+ simplecov-html (~> 0.10.0)
49
+ simplecov-html (0.10.0)
76
50
  terminal-notifier-guard (1.6.4)
77
- thor (0.19.1)
78
- timers (4.0.1)
79
- hitimes
80
51
 
81
52
  PLATFORMS
82
53
  ruby
@@ -85,7 +56,6 @@ DEPENDENCIES
85
56
  bundler (>= 1.2)
86
57
  codeclimate-test-reporter
87
58
  google_calendar!
88
- guard-minitest (~> 2.3)
89
59
  minitest (~> 5.1)
90
60
  minitest-reporters (~> 1.0)
91
61
  mocha (~> 1.1)
data/Guardfile CHANGED
@@ -1,7 +1,7 @@
1
- guard 'minitest' do
2
- # with Minitest::Unit
3
- watch(%r|^test/(.*)\/?test_(.*)\.rb|)
4
- watch(%r|^lib/(.*)([^/]+)\.rb|) { 'test' }
5
- watch(%r|^test/mocks(.*)([^/]+)\.json|) { 'test' }
6
- watch(%r|^test/helper\.rb|) { 'test' }
7
- end
1
+ # guard 'minitest' do
2
+ # # with Minitest::Unit
3
+ # watch(%r|^test/(.*)\/?test_(.*)\.rb|)
4
+ # watch(%r|^lib/(.*)([^/]+)\.rb|) { 'test' }
5
+ # watch(%r|^test/mocks(.*)([^/]+)\.json|) { 'test' }
6
+ # watch(%r|^test/helper\.rb|) { 'test' }
7
+ # end
data/README.rdoc CHANGED
@@ -89,7 +89,9 @@ A fast lightweight and minimalist wrapper around the {Google Calendar}[https://w
89
89
 
90
90
  This sample code is located in readme_code.rb in the root folder.
91
91
 
92
- Note: This is not a complete implementation of the calendar api, it just includes the features we needed to support our internal calendar integration.
92
+ == Notes
93
+ * 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.
94
+ * Did you get an SSL exception? If so take a look at this: https://gist.github.com/fnichol/867550
93
95
 
94
96
  == Contributing to google_calendar
95
97
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.5
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "google_calendar"
5
- s.version = "0.4.4"
5
+ s.version = "0.5"
6
6
  s.date = "2014-11-30"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  s.summary = "A lightweight Google Calendar API wrapper"
14
14
  s.description = "A minimal wrapper around the google calendar API"
15
15
  s.homepage = "http://northworld.github.io/google_calendar/"
16
- s.licenses = ["MIT"]
17
-
16
+ s.licenses = ["MIT"]
17
+
18
18
  s.extra_rdoc_files = [
19
19
  "LICENSE.txt",
20
20
  "README.rdoc"
@@ -26,12 +26,12 @@ Gem::Specification.new do |s|
26
26
  s.require_paths = ["lib"]
27
27
  s.rubygems_version = "2.2.2"
28
28
 
29
- s.add_runtime_dependency(%q<signet>, ["~> 0.5"])
29
+ s.add_runtime_dependency(%q<signet>, ["~> 0.6"])
30
30
  s.add_runtime_dependency(%q<json>, ["~> 1.8"])
31
31
 
32
32
  s.add_development_dependency(%q<terminal-notifier-guard>, ["~> 1.6"])
33
33
  s.add_development_dependency(%q<rb-fsevent>, ["~> 0.9"])
34
- s.add_development_dependency(%q<guard-minitest>, ["~> 2.3"])
34
+ # s.add_development_dependency(%q<guard-minitest>, ["~> 2.3"])
35
35
  s.add_development_dependency(%q<minitest>, ["~> 5.1"])
36
36
  s.add_development_dependency(%q<minitest-reporters>, ["~> 1.0"])
37
37
  s.add_development_dependency(%q<shoulda-context>, ["~> 1.2"])
@@ -39,5 +39,5 @@ Gem::Specification.new do |s|
39
39
  s.add_development_dependency(%q<mocha>, ["~> 1.1"])
40
40
  s.add_development_dependency(%q<rake>, ["~> 10"])
41
41
  s.add_development_dependency(%q<rdoc>, ["~> 4.1"])
42
-
43
- end
42
+
43
+ end
@@ -6,7 +6,7 @@ module Google
6
6
  #
7
7
  class Calendar
8
8
 
9
- attr_reader :connection
9
+ attr_reader :id, :connection, :summary
10
10
 
11
11
  #
12
12
  # Setup and connect to the specified Google Calendar.
@@ -20,22 +20,22 @@ module Google
20
20
  # See Readme.rdoc or readme_code.rb for an explication on the OAuth2 authorization process.
21
21
  #
22
22
  # ==== Example
23
- # Google::Calendar.new(:client_id => YOUR_CLIENT_ID,
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 => "urn:ietf:wg:oauth:2.0:oob" # this is what Google uses for 'applications'
27
27
  # )
28
28
  #
29
- def initialize(params={})
30
- options = {
29
+ def initialize(params={}, connection=nil)
30
+ @connection = connection || Connection.new(
31
31
  :client_id => params[:client_id],
32
32
  :client_secret => params[:client_secret],
33
33
  :refresh_token => params[:refresh_token],
34
- :redirect_url => params[:redirect_url],
35
- :calendar_id => params[:calendar]
36
- }
34
+ :redirect_url => params[:redirect_url]
35
+ )
37
36
 
38
- @connection = Connection.new options
37
+ @id = params[:calendar]
38
+ # raise CalendarIDMissing unless @id
39
39
  end
40
40
 
41
41
  #
@@ -92,8 +92,8 @@ module Google
92
92
  end
93
93
 
94
94
  #
95
- # This is equivalent to running a search in the Google calendar web application.
96
- # Google does not provide a way to specify what attributes you would like to
95
+ # This is equivalent to running a search in the Google calendar web application.
96
+ # Google does not provide a way to specify what attributes you would like to
97
97
  # search (i.e. title), by default it searches everything.
98
98
  # If you would like to find specific attribute value (i.e. title=Picnic), run a query
99
99
  # and parse the results.
@@ -121,7 +121,7 @@ module Google
121
121
  # an array with one element if only one found.
122
122
  # an array of events if many found.
123
123
  #
124
- def find_events_in_range(start_min, start_max, options = {})
124
+ def find_events_in_range(start_min, start_max, options = {})
125
125
  formatted_start_min = encode_time(start_min)
126
126
  formatted_start_max = encode_time(start_max)
127
127
  query = "?timeMin=#{formatted_start_min}&timeMax=#{formatted_start_max}#{parse_options(options)}"
@@ -155,7 +155,7 @@ module Google
155
155
  # an array of events if many found.
156
156
  #
157
157
  def find_event_by_id(id)
158
- return nil unless id && id.strip != ''
158
+ return nil unless id
159
159
  event_lookup("/#{id}")
160
160
  end
161
161
 
@@ -210,7 +210,7 @@ module Google
210
210
  "/#{event.id}"
211
211
  end
212
212
 
213
- @connection.send_events_request(query_string, method, body)
213
+ send_events_request(query_string, method, body)
214
214
  end
215
215
 
216
216
  #
@@ -218,7 +218,7 @@ module Google
218
218
  # This is a callback used by the Event class.
219
219
  #
220
220
  def delete_event(event)
221
- @connection.send_events_request("/#{event.id}", :delete)
221
+ send_events_request("/#{event.id}", :delete)
222
222
  end
223
223
 
224
224
  protected
@@ -245,8 +245,10 @@ module Google
245
245
  #
246
246
  def event_lookup(query_string = '') #:nodoc:
247
247
  begin
248
- response = @connection.send_events_request(query_string, :get)
249
- events = Event.build_from_google_feed( JSON.parse(response.body) , self) || []
248
+ response = send_events_request(query_string, :get)
249
+ parsed_json = JSON.parse(response.body)
250
+ @summary = parsed_json['summary']
251
+ events = Event.build_from_google_feed(parsed_json, self) || []
250
252
  return events if events.empty?
251
253
  events.length > 1 ? events : [events[0]]
252
254
  rescue Google::HTTPNotFound
@@ -265,6 +267,13 @@ module Google
265
267
  event.save
266
268
  event
267
269
  end
270
+
271
+ #
272
+ # Wraps the `send` method. Send an event related request to Google.
273
+ #
274
+ def send_events_request(path_and_query_string, method, content = '')
275
+ @connection.send("/calendars/#{CGI::escape @id}/events#{path_and_query_string}", method, content)
276
+ end
268
277
  end
269
278
 
270
279
  end
@@ -0,0 +1,43 @@
1
+ module Google
2
+
3
+ #
4
+ # CalendarList is the main object you use to find Calendars.
5
+ #
6
+ class CalendarList
7
+
8
+ attr_reader :connection
9
+
10
+ #
11
+ # Setup and connect to the user's list of Google Calendars.
12
+ #
13
+ # The +params+ parameter accepts
14
+ # * :client_id => the client ID that you received from Google after registering your application with them (https://console.developers.google.com/). REQUIRED
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
+ # * :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
+ #
19
+ # See Readme.rdoc or readme_code.rb for an explication on the OAuth2 authorization process.
20
+ #
21
+ def initialize(params={}, connection=nil)
22
+ @connection = connection || Connection.new(
23
+ :client_id => params[:client_id],
24
+ :client_secret => params[:client_secret],
25
+ :refresh_token => params[:refresh_token],
26
+ :redirect_url => params[:redirect_url]
27
+ )
28
+ end
29
+
30
+ #
31
+ # Find all entries on the user's calendar list. Returns an array of CalendarListEntry objects.
32
+ #
33
+ def fetch_entries
34
+ response = @connection.send("/users/me/calendarList", :get)
35
+
36
+ return nil if response.status != 200 || response.body.empty?
37
+
38
+ CalendarListEntry.build_from_google_feed(JSON.parse(response.body), @connection)
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,40 @@
1
+ module Google
2
+
3
+ #
4
+ # Represents a Google Calendar List Entry
5
+ #
6
+ # See https://developers.google.com/google-apps/calendar/v3/reference/calendarList#resource
7
+ #
8
+ # === Attributes
9
+ #
10
+ # * +id+ - The Google assigned id of the calendar. Read only.
11
+ # * +summary+ - Title of the calendar. Read-only.
12
+ # * +time_zone+ - The time zone of the calendar. Optional. Read-only.
13
+ # * +access_role+ - The effective access role that the authenticated user has on the calendar. Read-only.
14
+ # * +primary?+ - Whether the calendar is the primary calendar of the authenticated user. Read-only.
15
+ #
16
+ class CalendarListEntry
17
+ attr_reader :id, :summary, :time_zone, :access_role, :primary, :connection
18
+ alias_method :primary?, :primary
19
+
20
+ def initialize(params, connection)
21
+ @id = params['id']
22
+ @summary = params['summary']
23
+ @time_zone = params['timeZone']
24
+ @access_role = params['accessRole']
25
+ @primary = params.fetch('primary', false)
26
+ @connection = connection
27
+ end
28
+
29
+ def to_calendar
30
+ Calendar.new({:calendar => @id}, @connection)
31
+ end
32
+
33
+ def self.build_from_google_feed(response, connection)
34
+ items = response['items']
35
+ items.collect { |item| CalendarListEntry.new(item, connection) }
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -7,9 +7,21 @@ module Google
7
7
  #
8
8
  class Connection
9
9
  BASE_URI = "https://www.googleapis.com/calendar/v3"
10
-
10
+ TOKEN_URI ="https://accounts.google.com/o/oauth2/token"
11
+ AUTH_URI = "https://accounts.google.com/o/oauth2/auth"
12
+ SCOPE = "https://www.googleapis.com/auth/calendar"
11
13
  attr_accessor :client
12
14
 
15
+ def self.new_with_service_account(params)
16
+ client = Signet::OAuth2::Client.new(
17
+ :scope => SCOPE,
18
+ :issuer => params[:client_id],
19
+ :audience => TOKEN_URI,
20
+ :token_credential_uri => TOKEN_URI,
21
+ :signing_key => params[:signing_key]
22
+ )
23
+ Connection.new(params, client)
24
+ end
13
25
  #
14
26
  # Prepare a connection to google for fetching a calendar events
15
27
  #
@@ -19,29 +31,27 @@ module Google
19
31
  # * :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'"
20
32
  # * :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)
21
33
  #
22
- def initialize(params)
34
+ def initialize(params, client=nil)
23
35
 
24
- raise ArgumentError unless Connection.credentials_provided?(params)
36
+ raise ArgumentError unless client || Connection.credentials_provided?(params)
25
37
 
26
- @client = Signet::OAuth2::Client.new(
38
+ @client = client || Signet::OAuth2::Client.new(
27
39
  :client_id => params[:client_id],
28
40
  :client_secret => params[:client_secret],
29
41
  :redirect_uri => params[:redirect_url],
30
42
  :refresh_token => params[:refresh_token],
31
- :authorization_uri => 'https://accounts.google.com/o/oauth2/auth',
32
- :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
33
- :scope => "https://www.googleapis.com/auth/calendar"
43
+ :authorization_uri => AUTH_URI,
44
+ :token_credential_uri => TOKEN_URI,
45
+ :scope => SCOPE
34
46
  )
35
47
 
36
- calendar_id = params[:calendar_id]
37
-
38
- # raise CalenarIDMissing unless calendar_id
39
- @events_url = "#{BASE_URI}/calendars/#{CGI::escape calendar_id}/events"
40
-
41
48
  # try to get an access token if possible.
42
49
  if params[:refresh_token]
43
50
  @client.refresh_token = params[:refresh_token]
44
51
  @client.grant_type = 'refresh_token'
52
+ end
53
+
54
+ if params[:refresh_token] || params[:signing_key]
45
55
  Connection.get_new_access_token(@client)
46
56
  end
47
57
 
@@ -97,7 +107,9 @@ module Google
97
107
  #
98
108
  # Send a request to google.
99
109
  #
100
- def send(uri, method, content = '')
110
+ def send(path, method, content = '')
111
+
112
+ uri = BASE_URI + path
101
113
 
102
114
  response = @client.fetch_protected_resource(
103
115
  :uri => uri,
@@ -111,20 +123,13 @@ module Google
111
123
  return response
112
124
  end
113
125
 
114
- #
115
- # Wraps the `send` method. Send an event related request to Google.
116
- #
117
- def send_events_request(path_and_query_string, method, content = '')
118
- send(@events_url + path_and_query_string, method, content)
119
- end
120
-
121
126
  protected
122
127
 
123
128
  #
124
129
  # Utility method to centralize the process of getting an access token.
125
130
  #
126
131
  def self.get_new_access_token(client) #:nodoc:
127
- begin
132
+ begin
128
133
  client.fetch_access_token!
129
134
  rescue Signet::AuthorizationError
130
135
  raise HTTPAuthorizationFailed
@@ -150,6 +155,5 @@ module Google
150
155
  blank = /[^[:space:]]/
151
156
  !(params[:client_id] !~ blank) && !(params[:client_secret] !~ blank)
152
157
  end
153
-
154
158
  end
155
159
  end