nora 0.9 → 0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|