-
Notifications
You must be signed in to change notification settings - Fork 0
/
panoptes.rb
158 lines (136 loc) · 3.91 KB
/
panoptes.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# frozen_string_literal: true
require 'pg'
require 'securerandom'
class PanoptesClient
attr_reader :list_emailable_users
EXPORT_FIELDS = [
'global_email_communication',
'beta_email_communication',
'nasa_email_communication'
].freeze
def initialize
@list_emailable_users = {}
end
def build_lists
EXPORT_FIELDS.each do |export_type|
build_list_by_type(export_type)
end
end
def build_list_by_type(export_type)
return 'List already built' if @list_emailable_users[export_type]
@list_emailable_users[export_type] ||= conn.exec(
"SELECT
users.id,
users.email,
users.display_name,
users.unsubscribe_token
FROM
users
WHERE
users.activated_state = 0
AND users.valid_email = TRUE
AND users.#{export_type} = TRUE"
).entries
end
def delisted
return @delisted if @delisted
return 'Lists not built' if @list_emailable_users.empty?
@delisted = []
EXPORT_FIELDS.each do |export_type|
@delisted << @list_emailable_users[export_type]
end
@delisted.flatten!
end
def project_emailable_users
@project_emailable_users ||= conn.exec(
"SELECT
users.id,
users.email,
users.display_name,
users.unsubscribe_token,
user_project_preferences.project_id,
projects.slug,
projects.display_name AS project_display_name
FROM
users
INNER JOIN user_project_preferences ON user_project_preferences.user_id = users.id
LEFT JOIN projects ON projects.id = user_project_preferences.project_id
WHERE
user_project_preferences.email_communication = TRUE
AND users.activated_state = 0
AND users.valid_email = TRUE
AND projects.launch_approved = TRUE"
).entries
end
# Strip project info to do better deduping
def deprojected
@deprojected ||= project_emailable_users.map do |h|
{
'id' => h['id'],
'email' => h['email'],
'display_name' => h['display_name'],
'unsubscribe_token' => h['unsubscribe_token']
}
end
end
def subscribers
return @subscribers if @subscribers
@subscribers = (delisted.uniq + deprojected.uniq).uniq
@subscribers.map { |s| s['uuid'] = SecureRandom.uuid }
@subscribers
end
def general_lists
# Don't create the beta list, that gets broken up later
@general_lists ||= %w[global_email_communication nasa_email_communication].map(&:to_s).each_with_index.map do |list_name, index|
{
'id' => generate_id(index),
'uuid' => SecureRandom.uuid,
'name' => list_name,
'type' => 'private',
'description' => list_name
}
end
end
def beta_lists
@beta_lists ||= %w[beta_list_1 beta_list_2 beta_list_3 beta_list_4].each_with_index.map do |list_name, index|
{
'id' => generate_id(index, 2),
'uuid' => SecureRandom.uuid,
'name' => list_name,
'type' => 'private',
'description' => list_name
}
end
end
def shuffled_beta_list
@shuffled_beta_list ||= list_emailable_users['beta_email_communication'].shuffle
end
def split_beta_lists
return @split_beta_lists if @split_beta_lists
@split_beta_lists = {}
shuffled_beta_list.each_slice(75000).with_index(1) do |a, i|
@split_beta_lists["beta_list_#{i}"] = a
end
@split_beta_lists
end
def project_lists
@project_lists ||= project_emailable_users.uniq { |list| list['slug'] }.map do |h|
{
'id' => h['project_id'],
'uuid' => SecureRandom.uuid,
'name' => h['project_display_name'],
'type' => 'private',
'description' => h['slug']
}
end
end
private
#generates new id for beta/general lists
def generate_id(index, offset = 0)
new_id = 90000 + (index + offset)
new_id
end
def conn
@conn ||= PG.connect(ENV.fetch('PANOPTES_DB_URI'), sslmode: 'require')
end
end