nora 0.9 → 0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 575265c4cadad14393ba8736a3973ed7704d2e59
4
- data.tar.gz: 97fc379e85cf8793ec121f4d3eccf33f07905ecc
2
+ SHA256:
3
+ metadata.gz: eba54fcfe1ba7880878b3fb8f22a0a357d81ad08d1a037c162526d2989be84d2
4
+ data.tar.gz: 45314bb6328729955beed198f3606584d8275649b2352b835d1c9096b909ff3c
5
5
  SHA512:
6
- metadata.gz: 714cdab8af8e284c2458ff1de4a55035be2f8fce1f80af89d51486364506846bf25eb5cef794051aacb043c79884ca87686be55fbc671d69f133088d3f0c1eb6
7
- data.tar.gz: c1b39413b22b5e18247dc6cf1e2fb69165e6049ff484d4a98a964a901839f6f232179e1256a281f46b72dddf6e57e951a618c506b9aaf1d4f437b846cf594b22
6
+ metadata.gz: 9cf57358ca8f4a5f9a73b9dee65ade7f92627a87617c13a0b8ef1594540baf8ace3f2df01dc3c30104782f80fb3135b68a7cf0b197b129af39794b1cfbade4d3
7
+ data.tar.gz: 57df09cc016e551cc3d0c1b974e2208be62bc147647ba3194faa1086c0c794a978c0dba59209849b4dea929b7cf70fd1543d64a48ff451a6bf828f038022f9ae
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.0
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
- begin
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 - emails_in_history).each do |email|
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
- @history = Set.new
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).permutation.each do |emails|
132
- @history << emails
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.each_slice(group_size).each do |emails|
140
- return create_groups! unless (@history & emails.combination(2)).empty?
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
- @emails.each_slice(group_size) do |emails|
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
- @service.list_calendar_lists.items.select do |calendar|
346
- @emails.include? calendar.id
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nora
4
- VERSION = "0.9"
4
+ VERSION = "0.10"
5
5
  end
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.9'
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: 2018-08-27 00:00:00.000000000 Z
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.5.1
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.