mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-14 21:24:54 +08:00
17bcaeb2c2
Also tweak a numbers a bit since experiment is another factor now.
1269 lines
44 KiB
Ruby
1269 lines
44 KiB
Ruby
require "#{Rails.root}/app/utilities/users_generator"
|
|
require "#{Rails.root}/app/utilities/renaming_util"
|
|
require "#{Rails.root}/test/helpers/fake_test_helper"
|
|
include UsersGenerator
|
|
include RenamingUtil
|
|
include FakeTestHelper
|
|
|
|
namespace :db do
|
|
|
|
NR_ORGANIZATIONS = 4
|
|
NR_USERS = 100
|
|
NR_SAMPLE_TYPES = 20
|
|
NR_SAMPLE_GROUPS = 20
|
|
NR_CUSTOM_FIELDS = 20
|
|
NR_SAMPLES = 100
|
|
NR_PROTOCOLS = 20
|
|
NR_PROTOCOL_KEYWORDS = 20
|
|
NR_PROJECTS = 3
|
|
NR_EXPERIMENTS = 2
|
|
NR_MODULE_GROUPS = 4
|
|
NR_MODULES = 4
|
|
NR_STEPS = 3
|
|
NR_RESULTS = 4
|
|
NR_REPORTS = 4
|
|
NR_COMMENTS = 10
|
|
RATIO_USER_ORGANIZATIONS = 0.5
|
|
NR_MAX_USER_ORGANIZATIONS = 20
|
|
RATIO_CUSTOM_FIELDS = 0.7
|
|
RATIO_SAMPLE_CUSTOM_FIELDS = 0.6
|
|
RATIO_PROTOCOL_KEYWORDS = 0.3
|
|
THRESHOLD_PROTOCOL_IN_MODULE_LINKED = 0.5
|
|
THRESHOLD_PROTOCOL_PUBLIC = 0.6
|
|
THRESHOLD_PROTOCOL_ARCHIVED = 0.2
|
|
NR_MAX_USER_PROJECTS = 15
|
|
RATIO_USER_PROJECTS = 0.5
|
|
RATIO_COMMENTS = 0.7
|
|
NR_MAX_USER_MODULES = 15
|
|
RATIO_USER_MODULES = 0.5
|
|
NR_MAX_SAMPLE_MODULES = 10
|
|
RATIO_SAMPLE_MODULES = 0.7
|
|
RATIO_MODULE_MODULE_GROUPS = 0.8
|
|
RATIO_EDGES = 0.7
|
|
RATIO_STEP_COMPLETED = 0.5
|
|
NR_MAX_STEP_ATTACHMENTS = 2
|
|
RATIO_STEP_ATTACHMENTS = 0.2
|
|
NR_MAX_CHECKLIST_ITEMS = 20
|
|
RATIO_CHECKLIST_ITEM = 0.2
|
|
RATIO_CHECKLIST_ITEM_CHECKED = 0.5
|
|
RATIO_RESULT_ARCHIVED = 0.2
|
|
RATIO_REPORT_ELEMENTS = 0.75
|
|
|
|
THRESHOLD_ARCHIVED = 0.2
|
|
THRESHOLD_RESTORED = 0.9
|
|
|
|
MIN_FILE_SIZE = 0.01
|
|
MAX_FILE_SIZE = 0.1
|
|
|
|
desc "Drops the database, sets it up and inserts fake data for " +
|
|
"the current RAILS_ENV. WARNING: THIS WILL ERASE ALL " +
|
|
"CURRENT DATA IN THE DATABASE."
|
|
task :fake => :environment do
|
|
Rake::Task["db:drop"].reenable
|
|
Rake::Task["db:drop"].invoke
|
|
Rake::Task["db:setup"].reenable
|
|
Rake::Task["db:setup"].invoke
|
|
Rake::Task["db:fake:generate"].reenable
|
|
Rake::Task["db:fake:generate"].invoke
|
|
end
|
|
|
|
namespace :fake do
|
|
desc "Generates fake data & inserts it into database for the " +
|
|
"current RAILS_ENV."
|
|
task :generate => :environment do
|
|
require 'rgl/base'
|
|
require 'rgl/adjacency'
|
|
require 'rgl/topsort'
|
|
|
|
puts "Verbose? (Y/n)"
|
|
res = $stdin.gets.to_s.downcase.strip
|
|
unless res.in?(["", "y", "n"]) then
|
|
puts "Invalid parameter, exiting"
|
|
return
|
|
end
|
|
verbose = res.in?(["", "y"])
|
|
|
|
puts "Simple seeding? (Y/n)"
|
|
res = $stdin.gets.to_s.downcase.strip
|
|
unless res.in?(["", "y", "n"]) then
|
|
puts "Invalid parameter, exiting"
|
|
return
|
|
end
|
|
simple = res.in?(["", "y"])
|
|
|
|
if simple
|
|
puts "Choose the size of generated dataset(T - tiny, " +
|
|
"s - small, m - medium, l - large, h -huge)"
|
|
res = $stdin.gets.to_s.downcase.strip
|
|
unless res.in?(["", "t", "s", "m", "l", "h"]) then
|
|
puts "Invalid parameter, exiting"
|
|
return
|
|
end
|
|
|
|
case res
|
|
when "", "t"
|
|
factor = 0.5
|
|
when "s"
|
|
factor = 1
|
|
when "m"
|
|
factor = 5
|
|
when "l"
|
|
factor = 20
|
|
when "h"
|
|
factor = 100
|
|
end
|
|
|
|
nr_org = NR_ORGANIZATIONS * factor
|
|
nr_users = NR_USERS * factor
|
|
nr_sample_types = NR_SAMPLE_TYPES * factor
|
|
nr_sample_groups = NR_SAMPLE_GROUPS * factor
|
|
nr_custom_fields = NR_CUSTOM_FIELDS * factor
|
|
nr_samples = NR_SAMPLES * factor
|
|
nr_protocols = NR_PROTOCOLS * factor
|
|
nr_protocol_keywords = NR_PROTOCOL_KEYWORDS * factor
|
|
nr_projects = NR_PROJECTS * factor
|
|
nr_experiments = NR_EXPERIMENTS * factor
|
|
nr_module_groups = NR_MODULE_GROUPS * factor
|
|
nr_modules = NR_MODULES * factor
|
|
nr_steps = NR_STEPS * factor
|
|
nr_results = NR_RESULTS * factor
|
|
nr_reports = NR_REPORTS * factor
|
|
nr_comments = NR_COMMENTS * factor
|
|
else
|
|
puts "Type in the number of seeded organizations"
|
|
nr_org = $stdin.gets.to_i
|
|
puts "Type in the number of seeded users"
|
|
nr_users = $stdin.gets.to_i
|
|
puts "Type in the number of seeded sample types " +
|
|
"for each organization"
|
|
nr_sample_types = $stdin.gets.to_i
|
|
puts "Type in the number of seeded sample groups for " +
|
|
"each organization"
|
|
nr_sample_groups = $stdin.gets.to_i
|
|
puts "Type in the max. number of seeded custom fields " +
|
|
"for each organization"
|
|
nr_custom_fields = $stdin.gets.to_i
|
|
puts "Type in the number of seeded samples for each organization"
|
|
nr_samples = $stdin.gets.to_i
|
|
puts "Type in the number of seeded protocols for each organization"
|
|
nr_protocols = $stdin.gets.to_i
|
|
puts "Type in the number of seeded protocol keywords for each organization"
|
|
nr_protocol_keywords = $stdin.gets.to_i
|
|
puts "Type in the number of seeded projects for each organization"
|
|
nr_projects = $stdin.gets.to_i
|
|
puts "Type in the number of seeded experiments for each project"
|
|
nr_experiments = $stdin.gets.to_i
|
|
puts "Type in the number of seeded workflows for each experiment"
|
|
nr_module_groups = $stdin.gets.to_i
|
|
puts "Type in the number of seeded modules for each experiment"
|
|
nr_modules = $stdin.gets.to_i
|
|
puts "Type in the number of seeded steps for each module"
|
|
nr_steps = $stdin.gets.to_i
|
|
puts "Type in the number of seeded results for each module"
|
|
nr_results = $stdin.gets.to_i
|
|
puts "Type in the number of seeded reports for each project"
|
|
nr_reports = $stdin.gets.to_i
|
|
puts "Type in the max. number of seeded comments for each " +
|
|
"commentable item"
|
|
nr_comments = $stdin.gets.to_i
|
|
end
|
|
|
|
begin
|
|
ActiveRecord::Base.transaction do
|
|
|
|
puts "Generating fake organizations..."
|
|
taken_org_names = []
|
|
for _ in 1..nr_org
|
|
begin
|
|
name = Faker::University.name
|
|
end while name.in? taken_org_names
|
|
taken_org_names << name
|
|
|
|
Organization.create(
|
|
name: name,
|
|
description: rand >= 0.7 ? Faker::Lorem.sentence : nil
|
|
)
|
|
end
|
|
|
|
all_organizations = Organization.all
|
|
|
|
puts "Generating fake users..."
|
|
taken_emails = []
|
|
for _ in 1..nr_users
|
|
begin
|
|
if rand >= 0.8
|
|
name = generate_got_name
|
|
else
|
|
name = Faker::Name.name
|
|
end
|
|
email_name = name.downcase.remove(".").split(" ").join(".")
|
|
password = Faker::Internet.password(10, 20)
|
|
email = Faker::Internet.free_email(email_name)
|
|
end while email.in? taken_emails
|
|
taken_emails << email
|
|
|
|
user = create_user(
|
|
name,
|
|
email,
|
|
password,
|
|
true,
|
|
nil,
|
|
[]
|
|
)
|
|
user.update(
|
|
confirmed_at: Faker::Date.backward(30),
|
|
)
|
|
if verbose then
|
|
puts " Generated user #{name} (email: #{email}, " +
|
|
"password: #{password})"
|
|
end
|
|
|
|
# Randomly assign user to organizations
|
|
taken_org_ids = []
|
|
for _ in 1..[NR_MAX_USER_ORGANIZATIONS, all_organizations.count].min
|
|
if rand <= RATIO_USER_ORGANIZATIONS then
|
|
begin
|
|
org = pluck_random(all_organizations)
|
|
end while org.id.in? taken_org_ids
|
|
taken_org_ids << org.id
|
|
|
|
UserOrganization.create(
|
|
user: user,
|
|
organization: org,
|
|
role: rand(0..2)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
puts "Generating fake sample types..."
|
|
all_organizations.find_each do |org|
|
|
for _ in 1..nr_sample_types
|
|
SampleType.create(
|
|
name: Faker::Commerce.department(4),
|
|
organization: org
|
|
)
|
|
end
|
|
end
|
|
|
|
puts "Generating fake sample groups..."
|
|
all_organizations.find_each do |org|
|
|
for _ in 1..nr_sample_groups
|
|
SampleGroup.create(
|
|
name: Faker::Commerce.color,
|
|
organization: org,
|
|
color: generate_color
|
|
)
|
|
end
|
|
end
|
|
|
|
puts "Generating fake custom fields..."
|
|
all_organizations.find_each do |org|
|
|
for _ in 1..nr_custom_fields
|
|
if rand <= RATIO_CUSTOM_FIELDS then
|
|
CustomField.create(
|
|
name: Faker::Team.state,
|
|
organization: org,
|
|
user: pluck_random(org.users)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
puts "Generating fake samples..."
|
|
all_organizations.find_each do |org|
|
|
for _ in 1..nr_samples
|
|
sample = Sample.create(
|
|
name: Faker::Book.title,
|
|
organization: org,
|
|
user: pluck_random(org.users),
|
|
sample_type: pluck_random(org.sample_types),
|
|
sample_group: pluck_random(org.sample_groups)
|
|
)
|
|
|
|
# Add some custom fields to sample
|
|
org.custom_fields.find_each do |cf|
|
|
if rand <= RATIO_SAMPLE_CUSTOM_FIELDS then
|
|
SampleCustomField.create(
|
|
sample: sample,
|
|
custom_field: cf,
|
|
value: Faker::Team.state
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
puts "Generating fake protocol keywords"
|
|
all_organizations.find_each do |org|
|
|
taken_kw_names = []
|
|
for _ in 1..nr_protocol_keywords
|
|
begin
|
|
name = Faker::Book.genre
|
|
end while name.in? taken_kw_names
|
|
taken_kw_names << name
|
|
ProtocolKeyword.create(
|
|
organization: org,
|
|
name: name
|
|
)
|
|
end
|
|
end
|
|
|
|
puts "Generating fake repository protocols..."
|
|
all_organizations.find_each do |org|
|
|
for _ in 1..nr_protocols
|
|
protocol = generate_fake_protocol(org, nil, nr_steps, nr_comments)
|
|
|
|
if verbose then
|
|
puts " Generated protocol #{protocol.name}"
|
|
end
|
|
end
|
|
end
|
|
|
|
puts "Generating fake projects..."
|
|
all_organizations.find_each do |org|
|
|
taken_project_names = []
|
|
for _ in 1..nr_projects
|
|
begin
|
|
name = Faker::Company.name[0..29]
|
|
end while name.in? taken_project_names
|
|
taken_project_names << name
|
|
|
|
author = pluck_random(org.users)
|
|
created_at = Faker::Time.backward(500)
|
|
last_modified_by = pluck_random(org.users)
|
|
archived_by = pluck_random(org.users)
|
|
archived_on = Faker::Time.between(created_at, DateTime.now)
|
|
restored_by = pluck_random(org.users)
|
|
restored_on = Faker::Time.between(archived_on, DateTime.now)
|
|
status = random_status
|
|
|
|
project = Project.create(
|
|
visibility: rand(0..1),
|
|
name: name,
|
|
due_date: nil,
|
|
organization: org,
|
|
created_by: author,
|
|
created_at: created_at,
|
|
last_modified_by: last_modified_by,
|
|
archived: status == :archived,
|
|
archived_by: status.in?([:archived, :restored]) ?
|
|
archived_by : nil,
|
|
archived_on: status.in?([:archived, :restored]) ?
|
|
archived_on : nil,
|
|
restored_by: status == :restored ? restored_by : nil,
|
|
restored_on: status == :restored ? restored_on : nil
|
|
)
|
|
# Automatically assign project author onto project
|
|
UserProject.create(
|
|
user: author,
|
|
project: project,
|
|
role: 0,
|
|
created_at: created_at
|
|
)
|
|
|
|
# Activities
|
|
Activity.create(
|
|
type_of: :create_project,
|
|
user: author,
|
|
project: project,
|
|
message: I18n.t(
|
|
"activities.create_project",
|
|
user: author.full_name,
|
|
project: project.name
|
|
),
|
|
created_at: created_at
|
|
)
|
|
if status.in?([:archived, :restored]) then
|
|
Activity.create(
|
|
type_of: :archive_project,
|
|
user: archived_by,
|
|
project: project,
|
|
message: I18n.t(
|
|
"activities.archive_project",
|
|
user: archived_by.full_name,
|
|
project: project.name
|
|
),
|
|
created_at: archived_on
|
|
)
|
|
end
|
|
if status == :restored then
|
|
Activity.create(
|
|
type_of: :restore_project,
|
|
user: restored_by,
|
|
project: project,
|
|
message: I18n.t(
|
|
"activities.restore_project",
|
|
user: restored_by.full_name,
|
|
project: project.name
|
|
),
|
|
created_at: restored_on
|
|
)
|
|
end
|
|
|
|
# Assign users onto the project
|
|
taken_user_ids = []
|
|
for _ in 2..[NR_MAX_USER_PROJECTS, org.users.count].min
|
|
if rand <= RATIO_USER_PROJECTS
|
|
begin
|
|
user = pluck_random(org.users)
|
|
end while user.id.in? taken_user_ids
|
|
taken_user_ids << user.id
|
|
|
|
assigned_on = Faker::Time.backward(500)
|
|
assigned_by = pluck_random(project.users)
|
|
up = UserProject.create(
|
|
user: user,
|
|
project: project,
|
|
role: rand(0..3),
|
|
created_at: assigned_on,
|
|
assigned_by: assigned_by
|
|
)
|
|
Activity.create(
|
|
type_of: :assign_user_to_project,
|
|
user: assigned_by,
|
|
project: project,
|
|
message: I18n.t(
|
|
"activities.assign_user_to_project",
|
|
assigned_user: user.full_name,
|
|
role: up.role_str,
|
|
project: project.name,
|
|
assigned_by_user: assigned_by.full_name
|
|
),
|
|
created_at: assigned_on
|
|
)
|
|
end
|
|
end
|
|
|
|
# Add some comments
|
|
for _ in 1..nr_comments
|
|
if rand <= RATIO_COMMENTS
|
|
project.comments << Comment.create(
|
|
user: pluck_random(project.users),
|
|
message: Faker::Hipster.sentence,
|
|
created_at: Faker::Time.backward(500)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
puts "Generating fake experiments..."
|
|
Project.find_each do |project|
|
|
for _ in 1..nr_experiments
|
|
status = random_status
|
|
created_at = Faker::Time.backward(500)
|
|
archived_by = pluck_random(project.users)
|
|
archived_on = Faker::Time.between(created_at, DateTime.now)
|
|
restored_by = pluck_random(project.users)
|
|
restored_on = Faker::Time.between(archived_on, DateTime.now)
|
|
|
|
Experiment.create(
|
|
name: Faker::Hacker.noun,
|
|
description: Faker::Hipster.sentence,
|
|
project: project,
|
|
created_at: created_at,
|
|
created_by: pluck_random(project.users),
|
|
archived: status,
|
|
archived_on: status.in?([:archived, :restored]) ?
|
|
archived_on : nil,
|
|
archived_by: status.in?([:archived, :restored]) ?
|
|
archived_by : nil,
|
|
restored_on: status == :restored ? restored_on : nil,
|
|
restored_by: status == :restored ? restored_by : nil
|
|
)
|
|
end
|
|
end
|
|
|
|
puts "Generating fake workflows..."
|
|
Experiment.find_each do |experiment|
|
|
for _ in 1..nr_module_groups
|
|
MyModuleGroup.create(
|
|
name: Faker::Hacker.noun,
|
|
experiment: experiment
|
|
)
|
|
end
|
|
end
|
|
|
|
puts "Generating fake modules..."
|
|
total_experiment = Experiment.count
|
|
Experiment.find_each.with_index do |experiment, i|
|
|
if verbose then
|
|
puts " Generating modules for experiment #{experiment.name} " +
|
|
"(#{i + 1} of #{total_experiment})..."
|
|
end
|
|
project = experiment.project
|
|
taken_pos = []
|
|
for _ in 1..nr_modules
|
|
begin
|
|
x = rand(0..nr_modules)
|
|
y = rand(0..nr_modules)
|
|
end while [x, y].in? taken_pos
|
|
taken_pos << [x, y]
|
|
|
|
status = random_status
|
|
author = pluck_random(org.users)
|
|
created_at = Faker::Time.backward(500)
|
|
archived_by = pluck_random(org.users)
|
|
archived_on = Faker::Time.between(created_at, DateTime.now)
|
|
restored_by = pluck_random(org.users)
|
|
restored_on = Faker::Time.between(archived_on, DateTime.now)
|
|
|
|
my_module = MyModule.create(
|
|
name: Faker::Hacker.verb,
|
|
created_by: author,
|
|
created_at: created_at,
|
|
due_date: rand <= 0.5 ?
|
|
Faker::Time.forward(500) : nil,
|
|
description: rand <= 0.5 ?
|
|
Faker::Hacker.say_something_smart : nil,
|
|
x: x,
|
|
y: y,
|
|
experiment: experiment,
|
|
my_module_group: status == :archived ?
|
|
nil :
|
|
(rand <= RATIO_MODULE_MODULE_GROUPS ?
|
|
pluck_random(project.my_module_groups) : nil
|
|
),
|
|
archived: status == :archived,
|
|
archived_on: status.in?([:archived, :restored]) ?
|
|
archived_on : nil,
|
|
archived_by: status.in?([:archived, :restored]) ?
|
|
archived_by : nil,
|
|
restored_on: status == :restored ? restored_on : nil,
|
|
restored_by: status == :restored ? restored_by : nil
|
|
)
|
|
|
|
# Activities
|
|
Activity.create(
|
|
type_of: :create_module,
|
|
user: author,
|
|
project: my_module.project,
|
|
my_module: my_module,
|
|
message: I18n.t(
|
|
"activities.create_module",
|
|
user: author.full_name,
|
|
module: my_module.name
|
|
),
|
|
created_at: created_at
|
|
)
|
|
if status.in?([:archived, :restored]) then
|
|
Activity.create(
|
|
type_of: :archive_module,
|
|
user: archived_by,
|
|
project: my_module.project,
|
|
my_module: my_module,
|
|
message: I18n.t(
|
|
"activities.archive_module",
|
|
user: archived_by.full_name,
|
|
module: my_module.name
|
|
),
|
|
created_at: archived_on
|
|
)
|
|
end
|
|
if status == :restored then
|
|
Activity.create(
|
|
type_of: :restore_module,
|
|
user: restored_by,
|
|
project: my_module.project,
|
|
my_module: my_module,
|
|
message: I18n.t(
|
|
"activities.restore_module",
|
|
user: restored_by.full_name,
|
|
module: my_module.name
|
|
),
|
|
created_at: restored_on
|
|
)
|
|
end
|
|
|
|
if verbose then
|
|
puts " Generated module #{my_module.name}"
|
|
end
|
|
|
|
# Assign some users onto module
|
|
taken_user_ids = []
|
|
for _ in 1..[NR_MAX_USER_MODULES, project.users.count].min
|
|
if rand <= RATIO_USER_MODULES then
|
|
begin
|
|
user = pluck_random(project.users)
|
|
end while user.id.in? taken_user_ids
|
|
taken_user_ids << user.id
|
|
|
|
assigned_on = Faker::Time.backward(500)
|
|
assigned_by = pluck_random(my_module.project.users)
|
|
UserMyModule.create(
|
|
user: user,
|
|
my_module: my_module,
|
|
assigned_by: pluck_random(project.users),
|
|
created_at: assigned_on
|
|
)
|
|
Activity.create(
|
|
type_of: :assign_user_to_module,
|
|
user: assigned_by,
|
|
project: my_module.project,
|
|
my_module: my_module,
|
|
message: I18n.t(
|
|
"activities.assign_user_to_module",
|
|
assigned_user: user.full_name,
|
|
module: my_module.name,
|
|
assigned_by_user: assigned_by.full_name
|
|
),
|
|
created_at: assigned_on
|
|
)
|
|
end
|
|
end
|
|
|
|
# Assign some samples onto module
|
|
taken_sample_ids = []
|
|
for _ in 1..[
|
|
NR_MAX_SAMPLE_MODULES,
|
|
project.organization.samples.count
|
|
].min
|
|
if rand <= RATIO_SAMPLE_MODULES then
|
|
begin
|
|
sample = pluck_random(project.organization.samples)
|
|
end while sample.id.in? taken_sample_ids
|
|
taken_sample_ids << sample.id
|
|
|
|
SampleMyModule.create(
|
|
sample: sample,
|
|
my_module: my_module
|
|
)
|
|
end
|
|
end
|
|
|
|
# Add some comments
|
|
for _ in 1..nr_comments
|
|
if rand <= RATIO_COMMENTS
|
|
my_module.comments << Comment.create(
|
|
user: pluck_random(my_module.project.users),
|
|
message: Faker::Hipster.sentence,
|
|
created_at: Faker::Time.backward(500)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
# Generate some connections between modules
|
|
project.my_module_groups.find_each do |my_module_group|
|
|
if my_module_group.my_modules.empty? or
|
|
my_module_group.my_modules.count == 1
|
|
# If any module group doesn't contain
|
|
# any modules (or has only 1 module), remove it
|
|
my_module_group.destroy
|
|
else
|
|
# Make connections between project modules,
|
|
# keeping in mind not to generate cycles
|
|
n = my_module_group.my_modules.count
|
|
max_edges = (n - 1) * n / 2
|
|
|
|
dg = RGL::DirectedAdjacencyGraph.new
|
|
for _ in 1..max_edges
|
|
if rand <= RATIO_EDGES
|
|
begin
|
|
m1 = pluck_random(my_module_group.my_modules)
|
|
m2 = pluck_random(my_module_group.my_modules)
|
|
end while (
|
|
m1 == m2 or
|
|
dg.has_edge?(m1.id, m2.id)
|
|
)
|
|
|
|
# Only add edge if it won't make graph cyclic
|
|
dg.add_edge(m1.id, m2.id)
|
|
if dg.acyclic?
|
|
Connection.create(
|
|
input_id: m1.id,
|
|
output_id: m2.id
|
|
)
|
|
else
|
|
dg.remove_edge(m1.id, m2.id)
|
|
end
|
|
end
|
|
end
|
|
|
|
# Set order number for each module in group
|
|
topsort = dg.topsort_iterator.to_a
|
|
my_module_group.my_modules.each do |mm|
|
|
if topsort.include? mm.id
|
|
mm.workflow_order = topsort.find_index(mm.id)
|
|
mm.save!
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
puts "Generating fake module protocols..."
|
|
Experiment.find_each do |experiment|
|
|
experiment.my_modules.find_each do |my_module|
|
|
generate_fake_protocol(experiment.project.organization, my_module, nr_steps, nr_comments)
|
|
end
|
|
end
|
|
|
|
puts "Generating fake module results..."
|
|
Experiment.find_each do |experiment|
|
|
experiment.my_modules.find_each do |my_module|
|
|
for _ in 1..nr_results
|
|
user = pluck_random(my_module.users)
|
|
created_at = Faker::Time.backward(500)
|
|
archived_on = Faker::Time.between(created_at, DateTime.now)
|
|
restored_on = Faker::Time.between(archived_on, DateTime.now)
|
|
status = random_status
|
|
|
|
result = Result.new(
|
|
name: Faker::Hacker.abbreviation[0..49],
|
|
my_module: my_module,
|
|
user: user,
|
|
created_at: created_at,
|
|
archived: status == :archived,
|
|
archived_by: status.in?([:archived, :restored]) ?
|
|
user : nil,
|
|
archived_on: status.in?([:archived, :restored]) ?
|
|
archived_on : nil,
|
|
restored_by: status == :restored ? user : nil,
|
|
restored_on: status == :restored ? restored_on : nil
|
|
)
|
|
|
|
type = [:text, :asset, :table][rand(0..2)]
|
|
case type
|
|
when :text
|
|
result.result_text = ResultText.new(
|
|
text: Faker::Hipster.paragraph,
|
|
)
|
|
str = "activities.add_text_result"
|
|
str2 = "activities.archive_text_result"
|
|
when :asset
|
|
result.asset = Asset.new(
|
|
file: generate_file(rand(MIN_FILE_SIZE..MAX_FILE_SIZE)),
|
|
created_by: result.user
|
|
)
|
|
str = "activities.add_asset_result"
|
|
str2 = "activities.archive_asset_result"
|
|
when :table
|
|
result.table = Table.new(
|
|
contents: generate_table_contents(rand(30), rand(150)),
|
|
created_by: result.user
|
|
)
|
|
str = "activities.add_table_result"
|
|
str2 = "activities.archive_table_result"
|
|
end
|
|
|
|
result.save
|
|
|
|
# Add activities
|
|
Activity.create(
|
|
type_of: :add_result,
|
|
project: project,
|
|
my_module: my_module,
|
|
user: user,
|
|
created_at: created_at,
|
|
message: I18n.t(
|
|
str,
|
|
user: user.full_name,
|
|
result: result.name
|
|
)
|
|
)
|
|
if status.in?([:archived, :restored]) then
|
|
Activity.create(
|
|
type_of: :archive_result,
|
|
user: user,
|
|
project: project,
|
|
my_module: my_module,
|
|
message: I18n.t(
|
|
str2,
|
|
user: user.full_name,
|
|
result: result.name
|
|
),
|
|
created_at: archived_on
|
|
)
|
|
end
|
|
# Currently, there is no way to restore archived results
|
|
|
|
# Add some comments
|
|
for _ in 1..nr_comments
|
|
if rand <= RATIO_COMMENTS
|
|
comment_user = pluck_random(result.my_module.project.users)
|
|
comment_created_at = Faker::Time.backward(500)
|
|
result.comments << Comment.create(
|
|
user: comment_user,
|
|
message: Faker::Hipster.sentence,
|
|
created_at: comment_created_at
|
|
)
|
|
Activity.create(
|
|
type_of: :add_comment_to_result,
|
|
project: project,
|
|
my_module: my_module,
|
|
user: comment_user,
|
|
created_at: comment_created_at,
|
|
message: I18n.t(
|
|
"activities.add_comment_to_result",
|
|
user: user.full_name,
|
|
result: result.name
|
|
)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
puts "Generating fake reports..."
|
|
Experiment.find_each do |experiment|
|
|
project = experiment.project
|
|
for _ in 1..nr_reports
|
|
taken_project_names = []
|
|
begin
|
|
name = Faker::Company.bs
|
|
user = pluck_random(project.users)
|
|
end while [user, name].in? taken_project_names
|
|
taken_project_names << [user, name]
|
|
|
|
report = Report.create(
|
|
name: name,
|
|
description: Faker::Hipster.sentence,
|
|
project: project,
|
|
user: user
|
|
)
|
|
|
|
# Generate the oh-so-many report elements
|
|
ReportElement.create(
|
|
sort_order: 0,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :project_header
|
|
)
|
|
experiment.my_modules.each do |my_module|
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
re_my_module = ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :my_module,
|
|
my_module: my_module
|
|
)
|
|
|
|
my_module.protocol.completed_steps.each do |step|
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
re_step = ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :step,
|
|
step: step,
|
|
parent: re_my_module
|
|
)
|
|
|
|
step.checklists.each do |checklist|
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :step_checklist,
|
|
checklist: checklist,
|
|
parent: re_step
|
|
)
|
|
end
|
|
end
|
|
step.assets.each do |asset|
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :step_asset,
|
|
asset: asset,
|
|
parent: re_step
|
|
)
|
|
end
|
|
end
|
|
step.tables.each do |table|
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :step_table,
|
|
table: table,
|
|
parent: re_step
|
|
)
|
|
end
|
|
end
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :step_comments,
|
|
step: step,
|
|
parent: re_step
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
my_module.results.each do |result|
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
if result.is_asset
|
|
type_of = :result_asset
|
|
elsif result.is_table
|
|
type_of = :result_table
|
|
else
|
|
type_of = :result_text
|
|
end
|
|
re_result = ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: type_of,
|
|
result: result,
|
|
parent: re_my_module
|
|
)
|
|
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :result_comments,
|
|
result: result,
|
|
parent: re_result
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :my_module_activity,
|
|
my_module: my_module,
|
|
parent: re_my_module
|
|
)
|
|
end
|
|
|
|
if rand <= RATIO_REPORT_ELEMENTS then
|
|
ReportElement.create(
|
|
sort_order: rand <= 0.5 ? 0 : 1,
|
|
position: 0,
|
|
report: report,
|
|
type_of: :my_module_samples,
|
|
my_module: my_module,
|
|
parent: re_my_module
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
# Shuffle the report
|
|
shuffle_report_elements(
|
|
report.report_elements.where(parent: nil)
|
|
)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
# Now, at the end, add additional "private" organization
|
|
# to each user
|
|
User.find_each do |user|
|
|
create_private_user_organization(user, DEFAULT_PRIVATE_ORG_NAME)
|
|
end
|
|
|
|
# Calculate space taken by each organization; this must
|
|
# be done in a separate transaction because the estimated
|
|
# asset sizes are calculated in after_commit, which is done
|
|
# after the first transaction is completed
|
|
ActiveRecord::Base.transaction do
|
|
puts "Calculating organization sizes..."
|
|
Organization.find_each do |org|
|
|
org.calculate_space_taken
|
|
org.save
|
|
end
|
|
end
|
|
rescue ActiveRecord::ActiveRecordError,
|
|
ArgumentError, ActiveRecord::RecordNotSaved => e
|
|
puts "Error seeding fake data, transaction reverted"
|
|
puts "Output: #{e.inspect}"
|
|
puts e.backtrace.join("\n")
|
|
end
|
|
end
|
|
end
|
|
|
|
def generate_fake_protocol(
|
|
organization,
|
|
my_module,
|
|
nr_steps,
|
|
nr_comments
|
|
)
|
|
protocol = nil
|
|
if my_module.present?
|
|
protocol = my_module.protocol
|
|
users = my_module.users
|
|
author = pluck_random(users)
|
|
if rand <= THRESHOLD_PROTOCOL_IN_MODULE_LINKED &&
|
|
(parent = pluck_random(
|
|
organization.protocols.where(protocol_type: [
|
|
Protocol.protocol_types[:in_repository_private],
|
|
Protocol.protocol_types[:in_repository_public]
|
|
]))
|
|
).present?
|
|
protocol.protocol_type = :linked
|
|
protocol.added_by = author
|
|
protocol.parent = parent
|
|
protocol.parent_updated_at = parent.updated_at
|
|
else
|
|
protocol.protocol_type = :unlinked
|
|
end
|
|
protocol.my_module = my_module
|
|
else
|
|
protocol = Protocol.new
|
|
users = organization.users
|
|
author = pluck_random(users)
|
|
val = rand
|
|
if val > THRESHOLD_PROTOCOL_ARCHIVED
|
|
if val > THRESHOLD_PROTOCOL_PUBLIC
|
|
protocol.protocol_type = :in_repository_public
|
|
protocol.published_on = Faker::Time.backward(500)
|
|
else
|
|
protocol.protocol_type = :in_repository_private
|
|
end
|
|
else
|
|
protocol.protocol_type = :in_repository_archived
|
|
protocol.archived_by = author
|
|
protocol.archived_on = Faker::Time.backward(500)
|
|
end
|
|
protocol.added_by = author
|
|
protocol.authors = Faker::Book.author
|
|
protocol.description = Faker::Lorem.paragraph(2)
|
|
end
|
|
protocol.name = Faker::Hacker.ingverb
|
|
protocol.organization = organization
|
|
|
|
if protocol.invalid? then
|
|
rename_record(protocol, :name)
|
|
end
|
|
|
|
protocol.save!
|
|
|
|
organization.protocol_keywords.find_each do |kw|
|
|
if rand <= RATIO_PROTOCOL_KEYWORDS
|
|
ProtocolProtocolKeyword.create(
|
|
protocol: protocol,
|
|
protocol_keyword: kw
|
|
)
|
|
end
|
|
end
|
|
|
|
protocol.reload
|
|
if protocol.linked?
|
|
# For linked protocols, simply copy their parents' contents
|
|
protocol.load_from_repository(protocol.parent, author)
|
|
else
|
|
# Generate fake protocol data
|
|
for i in 1..nr_steps
|
|
created_at = Faker::Time.backward(500)
|
|
completed = protocol.in_repository? ? false : (rand <= RATIO_STEP_COMPLETED)
|
|
completed_on = completed ?
|
|
Faker::Time.between(created_at, DateTime.now) : nil
|
|
|
|
step = Step.create(
|
|
created_at: created_at,
|
|
name: Faker::Hacker.ingverb,
|
|
description: Faker::Hacker.say_something_smart,
|
|
position: i - 1,
|
|
completed: completed,
|
|
user: pluck_random(users),
|
|
protocol: protocol,
|
|
completed_on: completed_on
|
|
)
|
|
if protocol.in_module?
|
|
Activity.create(
|
|
type_of: :create_step,
|
|
project: my_module.project,
|
|
my_module: my_module,
|
|
user: step.user,
|
|
created_at: created_at,
|
|
message: I18n.t(
|
|
"activities.create_step",
|
|
user: step.user.full_name,
|
|
step: i,
|
|
step_name: step.name
|
|
)
|
|
)
|
|
end
|
|
if completed then
|
|
Activity.create(
|
|
type_of: :complete_step,
|
|
project: my_module.project,
|
|
my_module: my_module,
|
|
user: step.user,
|
|
created_at: completed_on,
|
|
message: I18n.t(
|
|
"activities.complete_step",
|
|
user: step.user.full_name,
|
|
step: i,
|
|
step_name: step.name,
|
|
completed: i,
|
|
all: i
|
|
)
|
|
)
|
|
end
|
|
|
|
# Add checklists
|
|
for _ in 1..NR_MAX_STEP_ATTACHMENTS
|
|
if rand <= RATIO_STEP_ATTACHMENTS then
|
|
checklist = Checklist.create(
|
|
name: Faker::Hacker.noun,
|
|
step: step,
|
|
created_by: step.user,
|
|
)
|
|
|
|
# Add checklist items
|
|
for j in 1..NR_MAX_CHECKLIST_ITEMS
|
|
if rand <= RATIO_CHECKLIST_ITEM then
|
|
checked = protocol.in_repository? ? false : (rand <= RATIO_CHECKLIST_ITEM_CHECKED)
|
|
checked_on = Faker::Time.backward(500)
|
|
ci = ChecklistItem.create(
|
|
created_at: checked_on,
|
|
text: Faker::Hipster.sentence,
|
|
checklist: checklist,
|
|
checked: checked,
|
|
created_by: step.user
|
|
)
|
|
if checked then
|
|
Activity.create(
|
|
type_of: :check_step_checklist_item,
|
|
project: my_module.project,
|
|
my_module: my_module,
|
|
user: step.user,
|
|
created_at: checked_on,
|
|
message: I18n.t(
|
|
"activities.check_step_checklist_item",
|
|
user: step.user.full_name,
|
|
checkbox: ci.text,
|
|
completed: j,
|
|
all: j,
|
|
step: i,
|
|
step_name: step.name
|
|
)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# Add assets
|
|
for _ in 1..NR_MAX_STEP_ATTACHMENTS
|
|
if rand <= RATIO_STEP_ATTACHMENTS then
|
|
asset = Asset.create(
|
|
file: generate_file(rand(MIN_FILE_SIZE..MAX_FILE_SIZE)),
|
|
created_by: step.user
|
|
)
|
|
StepAsset.create(
|
|
step: step,
|
|
asset: asset
|
|
)
|
|
end
|
|
end
|
|
|
|
# Add tables
|
|
for _ in 1..NR_MAX_STEP_ATTACHMENTS
|
|
if rand <= RATIO_STEP_ATTACHMENTS then
|
|
table = Table.create(
|
|
contents:
|
|
generate_table_contents(rand(30), rand(150)),
|
|
created_by: step.user
|
|
)
|
|
StepTable.create(
|
|
step: step,
|
|
table: table
|
|
)
|
|
end
|
|
end
|
|
|
|
# Add some comments (only on protocols on module)
|
|
if protocol.in_module? then
|
|
for _ in 1..nr_comments
|
|
if rand <= RATIO_COMMENTS
|
|
user = pluck_random(users)
|
|
created_at = Faker::Time.backward(500)
|
|
step.comments << Comment.create(
|
|
user: user,
|
|
message: Faker::Hipster.sentence,
|
|
created_at: created_at
|
|
)
|
|
Activity.create(
|
|
type_of: :add_comment_to_step,
|
|
project: my_module.project,
|
|
my_module: my_module,
|
|
user: user,
|
|
created_at: created_at,
|
|
message: I18n.t(
|
|
"activities.add_comment_to_step",
|
|
user: user.full_name,
|
|
step: i,
|
|
step_name: step.name
|
|
)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return protocol.reload
|
|
end
|
|
|
|
def shuffle_report_elements(report_elements)
|
|
if report_elements.blank? or report_elements.count == 0
|
|
return
|
|
end
|
|
|
|
header = report_elements.find_by(type_of: :project_header)
|
|
if header.present?
|
|
header.position = 0
|
|
header.save
|
|
i = 1
|
|
else
|
|
i = 0
|
|
end
|
|
|
|
ids_map = (i..(report_elements.count - 1)).to_a.shuffle
|
|
for i in i..(report_elements.count - 1)
|
|
re = report_elements[i]
|
|
re.position = ids_map[i]
|
|
re.save
|
|
end
|
|
|
|
# Recursively shuffle children
|
|
report_elements.each do |re2|
|
|
if re2.children.count > 0
|
|
shuffle_report_elements(re2.children)
|
|
end
|
|
end
|
|
end
|
|
|
|
# WARNING: This only works on PostgreSQL
|
|
def pluck_random(scope)
|
|
scope.order("RANDOM()").first
|
|
end
|
|
|
|
# Randomly determine whether project/module/result is active (0),
|
|
# archived (1), or already restored (2)
|
|
def random_status
|
|
val = rand
|
|
status = :active
|
|
if val > THRESHOLD_ARCHIVED
|
|
if val > THRESHOLD_RESTORED
|
|
status = :archived
|
|
end
|
|
else
|
|
status = :restored
|
|
end
|
|
status
|
|
end
|
|
end
|