Skip to content
This repository was archived by the owner on Aug 13, 2020. It is now read-only.

Commit 5e6fd0a

Browse files
brascoderhopsoft
authored andcommitted
Expand data seed (#26)
Expand data seeds.
1 parent 9864c7e commit 5e6fd0a

File tree

2 files changed

+364
-204
lines changed

2 files changed

+364
-204
lines changed

db/seeds.rb

Lines changed: 260 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,279 @@
1+
# frozen_string_literal: true
2+
3+
require "csv"
4+
require "fileutils"
15
require "faker"
26

7+
require_relative "./seeds_impressions"
8+
39
unless Rails.env.development?
410
puts "SEEDS ARE FOR DEVELOPMENT ONLY!"
511
exit 1
612
end
713

8-
user_attributes = {
9-
company_name: "CodeFund",
10-
confirmation_sent_at: 2.days.ago,
11-
confirmed_at: 1.day.ago,
12-
password: "secret",
13-
password_confirmation: "secret",
14-
}
15-
16-
administrator = User.find_or_initialize_by(email: "chris.knight@codefund.io")
17-
administrator.assign_attributes(
18-
user_attributes.merge(
19-
roles: [ENUMS::USER_ROLES::ADMINISTRATOR],
20-
first_name: "Chris",
21-
last_name: "Knight",
22-
)
23-
)
24-
administrator.save!
25-
26-
publisher = User.find_or_initialize_by(email: "mitch.taylor@codefund.io")
27-
publisher.assign_attributes(
28-
user_attributes.merge(
29-
roles: [ENUMS::USER_ROLES::PUBLISHER],
30-
first_name: "Mitch",
31-
last_name: "Taylor",
32-
)
33-
)
34-
publisher.save!
35-
36-
advertiser = User.find_or_initialize_by(email: "jordan.cochran@codefund.io")
37-
advertiser.assign_attributes(
38-
user_attributes.merge(
39-
roles: [ENUMS::USER_ROLES::ADVERTISER],
40-
first_name: "Jordan",
41-
last_name: "Cochran",
42-
)
43-
)
44-
advertiser.save!
45-
46-
if advertiser.images.search_metadata_name("CodeFund Small").search_metadata_format(ENUMS::IMAGE_FORMATS::SMALL).count == 0
47-
advertiser.images.attach io: File.open(Rails.root.join("app/assets/images/seeds/code-fund-100x100.png")),
48-
filename: "code-fund-100x100.png",
49-
content_type: "image/png",
50-
metadata: {
51-
identified: true,
52-
width: 100,
53-
height: 100,
54-
analyzed: true,
55-
name: "CodeFund Small",
56-
format: ENUMS::IMAGE_FORMATS::SMALL,
14+
class Seeder
15+
def self.run
16+
new.call
17+
end
18+
19+
def initialize
20+
@user_id = User.last&.id.to_i + 1
21+
@property_id = Property.last&.id.to_i + 1
22+
@user_count = 0
23+
@users = []
24+
@publishers = []
25+
@properties = []
26+
end
27+
28+
def call
29+
puts "[SEEDING DATABASE]: Started - This may take several minutes."
30+
seed_users
31+
seed_campaigns
32+
seed_properties
33+
ImpressionSeeder.run(ENV["MAX_IMPRESSIONS"].to_i)
34+
puts "[SEEDING DATABASE]: Completed"
35+
end
36+
37+
private
38+
39+
def seed_users
40+
@emails = User.all.pluck(:email).each_with_object({}) { |email, memo|
41+
memo[email] = true
5742
}
58-
end
43+
csv_path = Rails.root.join("tmp", "users.csv")
44+
@users << build_administrator
45+
@users.concat build_advertisers
46+
@users.concat build_publishers
47+
csv_created = create_csv(@users, csv_path)
48+
import_csv("users", csv_path) if csv_created
49+
end
50+
51+
def build_administrator
52+
admin_count = User.where("? = ANY (roles)", ENUMS::USER_ROLES::ADMINISTRATOR).count
53+
return unless admin_count.zero?
54+
return if @emails["admin@codefund.io"]
55+
puts "[SEEDING DATABASE]: Building administrator"
56+
@user_count += 1
57+
admin = user_attributes.merge(
58+
id: @user_id,
59+
company_name: "CodeFund",
60+
email: "admin@codefund.io",
61+
roles: "{#{ENUMS::USER_ROLES::ADMINISTRATOR}}",
62+
).values
63+
@user_id += 1
64+
admin
65+
end
5966

60-
if advertiser.images.search_metadata_name("CodeFund Large").search_metadata_format(ENUMS::IMAGE_FORMATS::LARGE).count == 0
61-
advertiser.images.attach io: File.open(Rails.root.join("app/assets/images/seeds/code-fund-260x200.png")),
62-
filename: "code-fund-100x100.png",
63-
content_type: "image/png",
64-
metadata: {
65-
identified: true,
66-
width: 260,
67-
height: 200,
68-
analyzed: true,
69-
name: "CodeFund Large",
70-
format: ENUMS::IMAGE_FORMATS::LARGE,
67+
def build_advertisers
68+
advertiser_count = User.where("? = ANY (roles)", ENUMS::USER_ROLES::ADVERTISER).count
69+
return [] if advertiser_count >= 100
70+
print "[SEEDING DATABASE]: Building advertisers "
71+
advertisers = (advertiser_count..99).map {
72+
@user_count += 1
73+
print "." if @user_count % 10 == 0
74+
advertiser = user_attributes.merge(id: @user_id, roles: "{#{ENUMS::USER_ROLES::ADVERTISER}}").values
75+
@user_id += 1
76+
advertiser
7177
}
72-
end
78+
puts
79+
advertisers
80+
end
7381

74-
if advertiser.creatives.count == 0
75-
5.times do
76-
creative = Creative.create(
77-
user: advertiser,
78-
name: Faker::SiliconValley.company,
79-
headline: Faker::SiliconValley.invention,
80-
body: Faker::SiliconValley.motto,
81-
)
82-
advertiser.images.each do |image|
83-
CreativeImage.create creative: creative, image: image
82+
def build_publishers
83+
publisher_count = User.where("? = ANY (roles)", ENUMS::USER_ROLES::PUBLISHER).count
84+
return [] if publisher_count >= 1000
85+
print "[SEEDING DATABASE]: Building publishers "
86+
publishers = (publisher_count..999).map {
87+
@user_count += 1
88+
print "." if @user_count % 10 == 0
89+
publisher = user_attributes.merge(id: @user_id, roles: "{#{ENUMS::USER_ROLES::PUBLISHER}}").values
90+
@publishers << @user_id
91+
@user_id += 1
92+
publisher
93+
}
94+
puts
95+
publishers
96+
end
97+
98+
def seed_campaigns
99+
return if Campaign.count >= 1000
100+
print "[SEEDING DATABASE]: Seeding campaigns "
101+
User.where("? = ANY (roles)", ENUMS::USER_ROLES::ADVERTISER).each do |advertiser|
102+
print "."
103+
add_small_image(advertiser)
104+
add_large_image(advertiser)
105+
generate_creatives(advertiser)
106+
generate_campaigns(advertiser)
84107
end
108+
puts
85109
end
86-
end
87110

88-
if advertiser.campaigns.count == 0
89-
10.times do
90-
start_date = rand(3).months.from_now.to_date
91-
end_date = start_date.advance(months: 6)
92-
total_budget = ([*500..5000].sample / 100) * 100
93-
daily_budget = total_budget / (end_date - start_date).to_i
94-
countries = ENUMS::DEVELOPED_MARKET_COUNTRIES.keys
95-
countries += ENUMS::EMERGING_MARKET_COUNTRIES.keys if rand(3).zero?
96-
countries += ENUMS::COUNTRIES.keys.sample(5) if rand(5).zero?
97-
keywords = ENUMS::KEYWORDS.values.sample(25)
98-
Campaign.create(
99-
user: advertiser,
100-
creative: advertiser.creatives.sample,
101-
status: ENUMS::CAMPAIGN_STATUSES.values.sample,
102-
name: Faker::SiliconValley.invention,
103-
url: Faker::SiliconValley.url,
104-
start_date: start_date,
105-
end_date: end_date,
106-
us_hours_only: rand(2).zero?,
107-
weekdays_only: rand(2).zero?,
108-
total_budget: total_budget,
109-
daily_budget: daily_budget,
110-
ecpm: 3,
111-
countries: countries,
112-
keywords: keywords,
113-
negative_keywords: ENUMS::KEYWORDS.values.sample(5) - keywords,
114-
)
111+
def add_small_image(advertiser)
112+
advertiser.images.attach io: File.open(Rails.root.join("app/assets/images/seeds/code-fund-100x100.png")),
113+
filename: "code-fund-100x100.png",
114+
content_type: "image/png",
115+
metadata: {
116+
identified: true,
117+
width: 100,
118+
height: 100,
119+
analyzed: true,
120+
name: "CodeFund Small",
121+
format: ENUMS::IMAGE_FORMATS::SMALL,
122+
}
123+
end
124+
125+
def add_large_image(advertiser)
126+
advertiser.images.attach io: File.open(Rails.root.join("app/assets/images/seeds/code-fund-260x200.png")),
127+
filename: "code-fund-100x100.png",
128+
content_type: "image/png",
129+
metadata: {
130+
identified: true,
131+
width: 260,
132+
height: 200,
133+
analyzed: true,
134+
name: "CodeFund Large",
135+
format: ENUMS::IMAGE_FORMATS::LARGE,
136+
}
137+
end
138+
139+
def generate_creatives(advertiser)
140+
5.times do
141+
creative = Creative.create(
142+
user: advertiser,
143+
name: Faker::SiliconValley.company,
144+
headline: Faker::SiliconValley.invention,
145+
body: Faker::SiliconValley.motto,
146+
)
147+
advertiser.images.each do |image|
148+
CreativeImage.create creative: creative, image: image
149+
end
150+
end
151+
end
152+
153+
def generate_campaigns(advertiser)
154+
10.times do
155+
start_date = rand(3).months.from_now.to_date
156+
end_date = start_date.advance(months: 6)
157+
total_budget = ([*500..5000].sample / 100) * 100
158+
daily_budget = total_budget / (end_date - start_date).to_i
159+
countries = ENUMS::DEVELOPED_MARKET_COUNTRIES.keys
160+
countries += ENUMS::EMERGING_MARKET_COUNTRIES.keys if rand(3).zero?
161+
countries += ENUMS::COUNTRIES.keys.sample(5) if rand(5).zero?
162+
keywords = ENUMS::KEYWORDS.values.sample(25)
163+
Campaign.create(
164+
user: advertiser,
165+
creative: advertiser.creatives.sample,
166+
status: ENUMS::CAMPAIGN_STATUSES.values.sample,
167+
name: Faker::SiliconValley.invention,
168+
url: Faker::SiliconValley.url,
169+
start_date: start_date,
170+
end_date: end_date,
171+
us_hours_only: rand(2).zero?,
172+
weekdays_only: rand(2).zero?,
173+
total_budget: total_budget,
174+
daily_budget: daily_budget,
175+
ecpm: 3,
176+
countries: countries,
177+
keywords: keywords,
178+
negative_keywords: ENUMS::KEYWORDS.values.sample(5) - keywords,
179+
)
180+
end
115181
end
116-
end
117182

118-
if publisher.properties.count == 0
119-
10.times do
120-
Property.create(
121-
user: publisher,
122-
property_type: ENUMS::PROPERTY_TYPES.values.sample,
123-
status: ENUMS::PROPERTY_STATUSES.values.sample,
124-
name: Faker::SiliconValley.invention,
125-
url: Faker::SiliconValley.url,
126-
ad_template: ENUMS::AD_TEMPLATES.values.sample,
127-
ad_theme: ENUMS::AD_THEMES.values.sample,
128-
language: ENUMS::LANGUAGES::ENGLISH,
129-
keywords: ENUMS::KEYWORDS.values.sample(25),
130-
)
183+
def seed_properties
184+
return if Property.count >= 10_000
185+
print "[SEEDING DATABASE]: Building properties"
186+
csv_path = Rails.root.join("tmp", "properties.csv")
187+
@publishers = User.where("? = ANY (roles)", ENUMS::USER_ROLES::PUBLISHER).pluck(:id) unless @publishers.present?
188+
@publishers.each do |publisher|
189+
print "."
190+
10.times do
191+
@properties << {
192+
id: @property_id,
193+
user_id: publisher,
194+
property_type: ENUMS::PROPERTY_TYPES.values.sample,
195+
status: ENUMS::PROPERTY_STATUSES.values.sample,
196+
name: Faker::SiliconValley.invention,
197+
description: nil,
198+
url: Faker::SiliconValley.url,
199+
ad_template: ENUMS::AD_TEMPLATES.values.sample,
200+
ad_theme: ENUMS::AD_THEMES.values.sample,
201+
language: ENUMS::LANGUAGES::ENGLISH,
202+
keywords: "{#{ENUMS::KEYWORDS.values.sample(25).join(",")}}",
203+
prohibited_advertisers: nil,
204+
prohibit_fallback_campaigns: false,
205+
created_at: Time.now,
206+
updated_at: Time.now,
207+
}.values
208+
@property_id += 1
209+
end
210+
end
211+
puts
212+
csv_created = create_csv(@properties, csv_path)
213+
import_csv("properties", csv_path) if csv_created
214+
end
215+
216+
def create_csv(list, csv_path)
217+
return false unless list.compact.present?
218+
puts "Creating #{csv_path}"
219+
CSV.open(csv_path, "wb") do |csv|
220+
list.each do |record|
221+
csv << record
222+
end
223+
end
224+
true
225+
end
226+
227+
def import_csv(table_name, csv_path)
228+
puts "Copying #{csv_path} to Postgres"
229+
ActiveRecord::Base.connection.execute "COPY \"#{table_name}\" FROM '#{csv_path}' CSV;"
230+
puts "Copy complete"
231+
rescue => e
232+
puts "Failed to copy #{csv_path} to Postgres! #{e}"
233+
ensure
234+
FileUtils.rm_f csv_path, verbose: true
235+
end
236+
237+
def user_attributes
238+
first_name = Faker::Name.first_name
239+
last_name = Faker::Name.last_name
240+
email = Faker::Internet.email("#{first_name} #{last_name}", "-")
241+
{
242+
id: 1,
243+
roles: [],
244+
first_name: first_name,
245+
last_name: last_name,
246+
company_name: Faker::SiliconValley.company,
247+
address_1: nil,
248+
address_2: nil,
249+
city: nil,
250+
region: nil,
251+
postal_code: nil,
252+
country: nil,
253+
api_access: true,
254+
api_key: nil,
255+
paypal_email: nil,
256+
email: email,
257+
encrypted_password: User.new(password: "secret").encrypted_password,
258+
reset_password_token: nil,
259+
reset_password_sent_at: nil,
260+
remember_created_at: nil,
261+
sign_in_count: 1,
262+
current_sign_in_at: nil,
263+
last_sign_in_at: nil,
264+
current_sign_in_ip: nil,
265+
last_sign_in_ip: nil,
266+
confirmation_token: Devise.friendly_token,
267+
confirmed_at: 1.day.ago,
268+
confirmation_sent_at: 2.days.ago,
269+
unconfirmed_email: nil,
270+
failed_attempts: 0,
271+
unlock_token: nil,
272+
locked_at: nil,
273+
created_at: 3.days.ago,
274+
updated_at: 3.days.ago,
275+
}
131276
end
132277
end
133278

134-
require_relative "./seeds_impressions" if ENV["IMPRESSIONS"]
279+
Seeder.run

0 commit comments

Comments
 (0)