nora 0.9 → 0.10
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 +5 -5
- data/.ruby-version +1 -1
- data/lib/nora/core.rb +51 -46
- data/lib/nora/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: eba54fcfe1ba7880878b3fb8f22a0a357d81ad08d1a037c162526d2989be84d2
|
4
|
+
data.tar.gz: 45314bb6328729955beed198f3606584d8275649b2352b835d1c9096b909ff3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9cf57358ca8f4a5f9a73b9dee65ade7f92627a87617c13a0b8ef1594540baf8ace3f2df01dc3c30104782f80fb3135b68a7cf0b197b129af39794b1cfbade4d3
|
7
|
+
data.tar.gz: 57df09cc016e551cc3d0c1b974e2208be62bc147647ba3194faa1086c0c794a978c0dba59209849b4dea929b7cf70fd1543d64a48ff451a6bf828f038022f9ae
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5
|
data/lib/nora/core.rb
CHANGED
@@ -25,6 +25,7 @@ module Nora
|
|
25
25
|
CREDENTIALS_PATH = "calendar-ruby-quickstart.yaml"
|
26
26
|
SCOPE = Google::Apis::CalendarV3::AUTH_CALENDAR
|
27
27
|
|
28
|
+
CALENDAR_BATCH_SIZE = 250 # The maximum Google Calendar allows
|
28
29
|
FREE_BUSY_QUERY_BATCH_SIZE = 5
|
29
30
|
|
30
31
|
CONFIGURATION = JSON.parse(File.read("nora_configuration.json"))
|
@@ -65,13 +66,7 @@ module Nora
|
|
65
66
|
def run!
|
66
67
|
load_history! # Populate @history for load_calendars!
|
67
68
|
load_calendars! # Outside the loop to reduce calls to Google API.
|
68
|
-
|
69
|
-
shuffle_emails!
|
70
|
-
create_groups!
|
71
|
-
rescue SystemStackError
|
72
|
-
remove_oldest_pair!
|
73
|
-
retry
|
74
|
-
end
|
69
|
+
create_groups!
|
75
70
|
|
76
71
|
send_emails(
|
77
72
|
template_emails_for(
|
@@ -92,15 +87,8 @@ module Nora
|
|
92
87
|
puts "Loading calendars..."
|
93
88
|
@emails = CONFIGURATION["people"].map { |p| p["email"] }
|
94
89
|
|
95
|
-
emails_in_history = []
|
96
|
-
File.open(PAIRINGS_FILE).each do |line|
|
97
|
-
line.split(PAIRINGS_FILE_SEPARATOR).each do |email|
|
98
|
-
emails_in_history << email
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
90
|
# Load all calendars that aren't in our history.
|
103
|
-
(@emails -
|
91
|
+
(Set.new(@emails) - @previously_loaded_emails).each do |email|
|
104
92
|
puts "Loading calendar: #{email}"
|
105
93
|
@service.insert_calendar_list(
|
106
94
|
Google::Apis::CalendarV3::CalendarListEntry.new(id: email)
|
@@ -109,35 +97,39 @@ module Nora
|
|
109
97
|
end
|
110
98
|
end
|
111
99
|
|
112
|
-
def shuffle_emails!
|
113
|
-
puts "Shuffling emails..."
|
114
|
-
@emails = @emails.shuffle
|
115
|
-
end
|
116
|
-
|
117
|
-
def remove_oldest_pair!
|
118
|
-
puts "Removing oldest pair and retrying..."
|
119
|
-
File.open("past_pairings_tmp.txt", "w") do |file|
|
120
|
-
File.open(PAIRINGS_FILE).each.with_index(1) do |line, line_num|
|
121
|
-
file.puts(line) unless line_num == 1
|
122
|
-
end
|
123
|
-
end
|
124
|
-
FileUtils.mv("past_pairings_tmp.txt", PAIRINGS_FILE)
|
125
|
-
end
|
126
|
-
|
127
100
|
def load_history!
|
128
101
|
puts "Loading history..."
|
129
|
-
@
|
102
|
+
@past_pairing_counts = Hash.new { |h, k| h[k] = 0 }
|
103
|
+
@previously_loaded_emails = Set.new
|
130
104
|
File.open(PAIRINGS_FILE).each do |line|
|
131
|
-
line.split(PAIRINGS_FILE_SEPARATOR).
|
132
|
-
@
|
105
|
+
line.split(PAIRINGS_FILE_SEPARATOR).each do |email|
|
106
|
+
@previously_loaded_emails << email
|
107
|
+
end.permutation.each do |emails|
|
108
|
+
@past_pairing_counts[group_key(emails: emails)] += 1
|
133
109
|
end
|
134
110
|
end
|
135
111
|
end
|
136
112
|
|
113
|
+
def group_key(emails:)
|
114
|
+
emails.sort.join(",")
|
115
|
+
end
|
116
|
+
|
137
117
|
def create_groups!
|
138
118
|
puts "Creating groups..."
|
139
|
-
@emails
|
140
|
-
|
119
|
+
unmatched_emails = Set.new(@emails)
|
120
|
+
@groups = []
|
121
|
+
|
122
|
+
while unmatched_emails.size >= group_size
|
123
|
+
@emails.shuffle.combination(group_size).each do |emails|
|
124
|
+
next unless emails.all? { |email| unmatched_emails.include?(email) }
|
125
|
+
key = group_key(emails: emails)
|
126
|
+
if @past_pairing_counts[key].zero?
|
127
|
+
@groups << emails
|
128
|
+
unmatched_emails.subtract(emails)
|
129
|
+
else
|
130
|
+
@past_pairing_counts[key] -= 1
|
131
|
+
end
|
132
|
+
end
|
141
133
|
end
|
142
134
|
end
|
143
135
|
|
@@ -148,7 +140,7 @@ module Nora
|
|
148
140
|
|
149
141
|
meetings = []
|
150
142
|
|
151
|
-
@
|
143
|
+
@groups.each do |emails|
|
152
144
|
if emails.size < group_size
|
153
145
|
puts "\nNot enough people in group: #{emails}\n"
|
154
146
|
meetings << {
|
@@ -161,6 +153,14 @@ module Nora
|
|
161
153
|
next
|
162
154
|
end
|
163
155
|
|
156
|
+
unless @test
|
157
|
+
File.open(PAIRINGS_FILE, "a") do |file|
|
158
|
+
emails.combination(2) do |email_pair|
|
159
|
+
file.puts email_pair.join(PAIRINGS_FILE_SEPARATOR)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
164
|
time = availability_schedule.select do |_, ids|
|
165
165
|
ids.superset? Set.new(emails)
|
166
166
|
end.keys.sample
|
@@ -178,14 +178,6 @@ module Nora
|
|
178
178
|
puts "#{time} => #{emails}"
|
179
179
|
add_meeting(time: time, attendee_ids: emails)
|
180
180
|
|
181
|
-
unless @test
|
182
|
-
File.open(PAIRINGS_FILE, "a") do |file|
|
183
|
-
emails.combination(2) do |email_pair|
|
184
|
-
file.puts email_pair.join(PAIRINGS_FILE_SEPARATOR)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
181
|
meetings << {
|
190
182
|
on: time,
|
191
183
|
who: emails.map do |email|
|
@@ -342,9 +334,22 @@ module Nora
|
|
342
334
|
memoize :email_name_map
|
343
335
|
|
344
336
|
def calendars
|
345
|
-
|
346
|
-
|
337
|
+
output = []
|
338
|
+
lists = @service.list_calendar_lists(max_results: CALENDAR_BATCH_SIZE)
|
339
|
+
lists.items.each do |calendar|
|
340
|
+
output << calendar if @emails.include? calendar.id
|
341
|
+
end
|
342
|
+
|
343
|
+
while lists.next_page_token
|
344
|
+
lists = @service.list_calendar_lists(
|
345
|
+
max_results: CALENDAR_BATCH_SIZE,
|
346
|
+
page_token: lists.next_page_token
|
347
|
+
)
|
348
|
+
lists.items.each do |calendar|
|
349
|
+
output << calendar if @emails.include? calendar.id
|
350
|
+
end
|
347
351
|
end
|
352
|
+
output
|
348
353
|
end
|
349
354
|
memoize :calendars
|
350
355
|
|
data/lib/nora/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nora
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.10'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Evelyn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -151,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
151
|
version: '0'
|
152
152
|
requirements: []
|
153
153
|
rubyforge_project:
|
154
|
-
rubygems_version: 2.
|
154
|
+
rubygems_version: 2.7.6
|
155
155
|
signing_key:
|
156
156
|
specification_version: 4
|
157
157
|
summary: Bringing P-A-NORA-M-A together.
|