jekyll-google-calendar 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/jekyll-google-calendar.rb +2 -0
- data/lib/jekyll/google/calendar/generator.rb +199 -0
- data/lib/jekyll/google/calendar/version.rb +7 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e06adaeb38c724cc03d99243029b324e2eec6a5666d172cdfc15c0e7ef4baa5c
|
4
|
+
data.tar.gz: ad161dc7631552325f281c719b5b01c63022f7f2f9c5438cd1a808a9be8545af
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5901df73058533ed77bb811efd07e31e8b6a120a4e0ce0ec55ee7b8840fef4f6386b90387aaba433161b7e293071caa3bd04222bbb453e16cf62e80b557f20f5
|
7
|
+
data.tar.gz: cea226530f428b6e90b0700414e789023f03a2cda456add96ccb16f3d39fa1efa0d72f12b97ef43aec9ceae90f23c77172220b437668d11444a98e0e8ebd97a4
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'google/apis/calendar_v3'
|
2
|
+
require 'googleauth'
|
3
|
+
|
4
|
+
GoogleCalendar = ::Google::Apis::CalendarV3
|
5
|
+
|
6
|
+
#TODO: Handle case where calendar doesn't exist or is not readable
|
7
|
+
#TODO: Add conference data to hash
|
8
|
+
#TODO: Add remaining calendar response data to hash
|
9
|
+
|
10
|
+
module Jekyll
|
11
|
+
module Google
|
12
|
+
module Calendar
|
13
|
+
|
14
|
+
##
|
15
|
+
# This class represents a Jekyll page generated from a calendar event.
|
16
|
+
|
17
|
+
class EventPage < Page
|
18
|
+
def initialize(site, base, dir, name, layout, data, calendar_data, calendar_id)
|
19
|
+
@site = site
|
20
|
+
@base = base
|
21
|
+
@dir = dir
|
22
|
+
@name = name
|
23
|
+
self.process(@name)
|
24
|
+
self.data = site.layouts[layout].data.dup
|
25
|
+
self.content = site.layouts[layout].content.dup
|
26
|
+
self.data['layout'] = layout
|
27
|
+
self.data['event'] = data
|
28
|
+
self.data['calendar'] = calendar_data
|
29
|
+
self.data['calendar_id'] = calendar_id
|
30
|
+
self.data['title'] = data['summary']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# This class is a Generator that Jekyll will call to generate events from our Google Calendars
|
36
|
+
|
37
|
+
class EventPageGenerator < Generator
|
38
|
+
safe true
|
39
|
+
|
40
|
+
##
|
41
|
+
# Called by Jekyll when generating pages. Here we set up the Google Calendar service,
|
42
|
+
# and for each calendar described in our _config.yml, we generate pages for each event
|
43
|
+
# Params:
|
44
|
+
# +site+:: Jekyll site variable
|
45
|
+
|
46
|
+
def generate(site)
|
47
|
+
@gcallendar_config = site.config['gcalendar']
|
48
|
+
raise 'Missing Google Calendar configuration in _config.yml' unless @gcallendar_config
|
49
|
+
service = setup_calendar()
|
50
|
+
@gcallendar_config['calendars'].each do |calendar|
|
51
|
+
process_calendar(site, service, calendar['id'], calendar['look_ahead'], calendar['directory'], calendar['date_format'], calendar['layout'])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def setup_calendar()
|
58
|
+
scope = 'https://www.googleapis.com/auth/calendar'
|
59
|
+
calendar = GoogleCalendar::CalendarService.new
|
60
|
+
authorizer = ::Google::Auth::ServiceAccountCredentials.make_creds(
|
61
|
+
json_key_io: File.open(@gcallendar_config['key_file']),
|
62
|
+
scope: scope)
|
63
|
+
authorizer.fetch_access_token!
|
64
|
+
calendar.authorization = authorizer
|
65
|
+
calendar
|
66
|
+
end
|
67
|
+
|
68
|
+
def process_calendar(site, calendar, calendar_id, look_ahead, dir, date_format, layout)
|
69
|
+
page_token = nil
|
70
|
+
calendar_data = nil
|
71
|
+
end_time = DateTime.now + look_ahead
|
72
|
+
begin
|
73
|
+
response = get_events(calendar, calendar_id, page_token, end_time)
|
74
|
+
calendar_data = calendar_data ? calendar_data : hash_calendar_data(response)
|
75
|
+
response.items.each do |event|
|
76
|
+
create_event(site, event, calendar_data, calendar_id, dir, date_format, layout)
|
77
|
+
end
|
78
|
+
page_token = response.next_page_token != page_token ? response.next_page_token : nil
|
79
|
+
end while !page_token.nil?
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_events(calendar, calendar_id, page_token, end_time)
|
83
|
+
response = calendar.list_events(calendar_id,
|
84
|
+
page_token: page_token,
|
85
|
+
single_events: true,
|
86
|
+
order_by: "startTime",
|
87
|
+
time_max: end_time.rfc3339)
|
88
|
+
response
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_event(site, data, calendar_data, calendar_id, dir, date_format, layout)
|
92
|
+
hash = hash_event_data(data)
|
93
|
+
slug = data.summary.strip.downcase.gsub(/[\s\.\/\\]/, '-').gsub(/[^\w-]/, '').gsub(/[-_]{2,}/, '-').gsub(/^[-_]/, '').gsub(/[-_]$/, '')
|
94
|
+
if !date_format.nil? && date_format != ""
|
95
|
+
if !data.start.date_time.nil?
|
96
|
+
slug += "-" + data.start.date_time.strftime(date_format)
|
97
|
+
elsif !data.start.date.nil?
|
98
|
+
slug += "-" + data.start.date.strftime(date_format)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
path = (dir[-1] == "/" ? dir : dir + "/") + slug
|
102
|
+
overlap = site.pages.select do |hash|
|
103
|
+
hash['url']== "/"+path+"/"
|
104
|
+
end
|
105
|
+
if overlap.length > 0
|
106
|
+
path += "-" + overlap.length.to_s
|
107
|
+
end
|
108
|
+
site.pages << EventPage.new(site, site.source, path, 'index.html', layout, hash, calendar_data, calendar_id)
|
109
|
+
end
|
110
|
+
|
111
|
+
def hash_calendar_data(response)
|
112
|
+
hash = {}
|
113
|
+
hash['kind'] = response.kind
|
114
|
+
hash['etag'] = response.etag
|
115
|
+
hash['summary'] = response.summary
|
116
|
+
hash['description'] = response.description
|
117
|
+
hash['updated'] = response.updated
|
118
|
+
hash['timeZone'] = response.time_zone
|
119
|
+
hash['accessRole'] = response.access_role
|
120
|
+
hash['defaultReminders'] = response.default_reminders ? response.default_reminders.map { |a| { "method" => a.method, "minutes" => a.minutes } } : nil
|
121
|
+
hash['nextPageToken'] = response.next_page_token
|
122
|
+
hash['nextSyncToken'] = response.next_sync_token
|
123
|
+
hash
|
124
|
+
end
|
125
|
+
|
126
|
+
def hash_event_data(data)
|
127
|
+
hash = {}
|
128
|
+
hash['kind'] = data.kind
|
129
|
+
hash['etag'] = data.etag
|
130
|
+
hash['id'] = data.id
|
131
|
+
hash['status'] = data.status
|
132
|
+
hash['htmlLink'] = data.html_link
|
133
|
+
hash['created'] = data.created
|
134
|
+
hash['summary'] = data.summary
|
135
|
+
hash['description'] = data.description
|
136
|
+
hash['location'] = data.location
|
137
|
+
hash['colorId'] = data.color_id
|
138
|
+
hash['creator'] = data.creator ? {"id" => data.creator.id, "email" => data.creator.email, "displayName" => data.creator.display_name, "self" => data.creator.self } : nil
|
139
|
+
hash['organizer'] = data.organizer ? {"id" => data.organizer.id, "email" => data.organizer.email, "displayName" => data.organizer.display_name, "self" => data.organizer.self } : nil
|
140
|
+
hash['start'] = data.start ? {"date" => data.start.date, "dateTime" => data.start.date_time, "timeZone" => data.start.time_zone } : nil
|
141
|
+
hash['end'] = data.end ? {"date" => data.end.date, "dateTime" => data.end.date_time, "timeZone" => data.end.time_zone } : nil
|
142
|
+
hash['endTimeUnspecified'] = data.end_time_unspecified
|
143
|
+
hash['recurrence'] = data.recurrence
|
144
|
+
hash['recurringEventId'] = data.recurring_event_id
|
145
|
+
hash['originalStartTime'] = data.original_start_time ? {"data" => data.original_start_time.date, "dateTime" => data.original_start_time.date_time, "timeZone" => data.original_start_time.time_zone } : nil
|
146
|
+
hash['transparency'] = data.transparency
|
147
|
+
hash['visibility'] = data.visibility
|
148
|
+
hash['iCalUID'] = data.i_cal_uid
|
149
|
+
hash['sequence'] = data.sequence
|
150
|
+
hash['attendees'] = data.attendees ? {"id" => data.attendees.id, "email" => data.attendees.email, "displayName" => data.attendees.display_name, "organizer" => data.attendees.organizer, "self" => data.attendees.self, "resource" => data.attendees.resource, "optional" => data.attendees.optional, "responseStatus" => data.attendees.response_status, "comment" => data.attendees.comment, "additionalGuests" => data.attendees.additionalGuests} : nil
|
151
|
+
hash['attendeesOmitted'] = data.attendees_omitted
|
152
|
+
hash['extendedProperties'] = data.extended_properties ? {"private" => data.extended_properties.private, "shared" => data.extended_properties.shared} : nil
|
153
|
+
hash['hangoutLink'] = data.hangout_link
|
154
|
+
hash['conferenceData'] = data.conference_data ? hash_conference_data(data.conference_data) : nil
|
155
|
+
hash["anyoneCanAddSelf"] = data.anyone_can_add_self
|
156
|
+
hash["guestsCanInviteOthers"] = data.guests_can_invite_others
|
157
|
+
hash["guestsCanModify"] = data.guests_can_modify
|
158
|
+
hash["guestsCanSeeOtherGuests"] = data.guests_can_see_other_guests
|
159
|
+
hash["privateCopy"] = data.private_copy
|
160
|
+
hash["locked"] = data.locked
|
161
|
+
hash['reminders'] = data.reminders ? {"useDefault" => data.reminders.use_default, "overrides" => data.reminders.overrides ? data.reminders.overrides.map { |o| {"methods" => o.methods, "minutes" => o.minutes} } : nil } : nil
|
162
|
+
hash['source'] = data.source ? {"url" => data.source.url, "title" => data.source.title } : nil
|
163
|
+
hash['attachments'] = data.attachments ? data.attachments.map { |a| { "fileUrl" => a.file_url, "title" => a.title, "mime_type" => a.mime_type, "iconLink" => a.icon_link, "fileId" => a.file_id } } : nil
|
164
|
+
hash
|
165
|
+
end
|
166
|
+
|
167
|
+
def hash_conference_data(data)
|
168
|
+
hash = {}
|
169
|
+
hash['createRequest'] = data.create_request ? data.create_request.map { |a| { "requestId" => a.request_id, "conferenceSolutionKey" => a.conference_solution_key ? a.conference_solution_key.map { |b| { "type" => b.type } } : nil } }: nil
|
170
|
+
hash['status'] = data.status ? {
|
171
|
+
'statusCode' => data.status.statusCode
|
172
|
+
} : nil
|
173
|
+
hash['entryPoints'] = data.entry_points ? data.entry_points.map { |a| { "entryPointType" => a.entry_point_type, "uri" => a.uri, "label" => a.label, "pin" => a.pin, "accessCode" => a.access_code, "meetingCode" => a.meeting_code, "passcode" => a.passcode, "password" => a.password }} : nil
|
174
|
+
|
175
|
+
hash['conferenceSolution'] = data.conference_solution ? {
|
176
|
+
"key" => data.conference_solution.key ? { "type" => data.conference_solution.key.type} : nil,
|
177
|
+
"name" => data.conference_solution.name,
|
178
|
+
"iconUri" => data.conference_solution.iconUri
|
179
|
+
} : nil
|
180
|
+
|
181
|
+
hash['conferenceId'] = data.conference_id
|
182
|
+
hash['signature'] = data.signature
|
183
|
+
hash['notes'] = data.notes
|
184
|
+
hash['gadget'] = data.gadget ? {
|
185
|
+
'type' => data.gadget.type,
|
186
|
+
'title' => data.gadget.title,
|
187
|
+
'link' => data.gadget.link,
|
188
|
+
'iconLink' => data.gadget.iconLink,
|
189
|
+
'width' => data.gadget.width,
|
190
|
+
'height' => data.gadget.height,
|
191
|
+
'display' => data.gadget.display,
|
192
|
+
'preferences' => data.preferences
|
193
|
+
}: nil
|
194
|
+
hash
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jekyll-google-calendar
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Gundry
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: google-api-client
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.9'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.9'
|
55
|
+
description: 'Scrapes events from one or more Google Calendars based on their calendar
|
56
|
+
ids and generates pages, providing the event data through Jekyll''s page variable. '
|
57
|
+
email:
|
58
|
+
- david@davidgundry.co.uk
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/jekyll-google-calendar.rb
|
64
|
+
- lib/jekyll/google/calendar/generator.rb
|
65
|
+
- lib/jekyll/google/calendar/version.rb
|
66
|
+
homepage: https://github.com/davidgundry/jekyll-google-calendar
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubygems_version: 3.0.4
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: Generate Jekyll posts from Google Calendar events
|
89
|
+
test_files: []
|