namespace :migrate do
desc "migrate to 1.0"
task prep_for_1_0: :environment do
# Convert existing orgs.target_url to the orgs.links JSON arrays
Rake::Task['migrate:org_target_url_to_links'].execute
end
desc "migrate to 0.4"
task to_04: :environment do
# Default all plans.visibility to the value specified in application.rb
Rake::Task['migrate:init_plan_visibility'].execute
# Move old plans.data_contact to plans.data_contact_email if value is an email
Rake::Task['migrate:plan_data_contacts'].execute
# Move users.orcid_id to the user_identifiers table
Rake::Task['migrate:move_orcids'].execute
# Move users.shibboleth_id to the user_identifiers table
Rake::Task['migrate:move_shibs'].execute
end
desc "TODO"
task permissions: :environment do
User.update_user_permissions
end
desc "perform entire data migration"
task setup: :environment do
Rake::Task['db:drop'].execute
Rake::Task['db:create'].execute
Rake::Task['db:schema:load'].execute
Rake::Task['db:data:load'].execute
Rake::Task['db:migrate'].execute
Rake::Task['migrate:seed'].execute
Rake::Task['migrate:permissions'].execute
end
desc "perform all post-migration tasks"
task cleanup: :environment do
Rake::Task['migrate:fix_languages'].execute
Rake::Task['migrate:single_published_template'].execute
end
desc "seed database with default values for new data structures"
task seed: :environment do
# seed roles to database
roles = {
'add_organisations' => {
name: 'add_organisations'
},
'change_org_affiliation' => {
name: 'change_org_affiliation'
},
'grant_permissions' => {
name: 'grant_permissions'
},
'modify_templates' => {
name: 'modify_templates'
},
'modify_guidance' => {
name: 'modify_guidance'
},
'use_api' => {
name: 'use_api'
},
'change_org_details' => {
name: 'change_org_details'
},
'grant_api_to_orgs' => {
name: 'grant_api_to_orgs'
}
}
roles.each do |role, details|
if Role.where(name: details[:name]).empty?
role = Role.new
role.name = details[:name]
role.save!
end
end
# seed token permission types to database
token_permission_types = {
'guidances' => {
description: "allows a user access to the guidances api endpoint"
},
'plans' => {
description: "allows a user access to the plans api endpoint"
},
'templates' => {
description: "allows a user access to the templates api endpoint"
},
'statistics' => {
description: "allows a user access to the statistics api endpoint"
}
}
token_permission_types.each do |title,settings|
if TokenPermissionType.where(token_type: title).empty?
token_permission_type = TokenPermissionType.new
token_permission_type.token_type = title
token_permission_type.text_description = settings[:description]
token_permission_type.save!
end
end
# seed languages to database
languages = {
'English(GB)' => {
abbreviation: 'en_GB',
description: '',
name: 'English (GB)',
default_language: true
},
'English(US)' => {
abbreviation: 'en_US',
description: '',
name: 'English (US)',
default_language: false
},
'FR' => {
abbreviation: 'fr',
description: '',
name: 'Français',
default_language: false
},
'DE' => {
abbreviation: 'de',
description: '',
name: 'Deutsch',
default_language: false
},
'Español' => {
abbreviation: 'es',
description: '',
name: 'Español',
default_language: false
}
}
languages.each do |l, details|
if Language.where(name: details[:name]).empty?
language = Language.new
language.abbreviation = details[:abbreviation]
language.description = details[:description]
language.name = details[:name]
language.default_language = details[:default_language]
language.save!
end
end
# seed regions to database
regions = {
'UK' => {
abbreviation: 'uk',
description: 'default region',
name: 'UK',
},
'DE' => {
abbreviation: 'de',
description: '',
name: 'DE',
},
'Horizon2020' => {
abbreviation: 'horizon',
description: 'European super region',
name: 'Horizon2020',
}
}
regions.each do |l, details|
if Region.where(name: details[:name]).empty?
region = Region.new
region.abbreviation = details[:abbreviation]
region.description = details[:description]
region.name = details[:name]
region.save!
end
end
end
desc "replaces languages in incorrect formats and seeds all correct formats"
task fix_languages: :environment do
languages = [
{ abbreviation: 'en_GB',
old_abbreviation: 'en-UK',
description: '',
name: 'English (GB)',
default_language: true},
{ abbreviation: 'en_US',
old_abbreviation: 'en-US',
description: '',
name: 'English (US)',
default_language: false},
{ abbreviation: 'fr',
old_abbreviation: 'fr',
description: '',
name: 'Français',
default_language: false},
{ abbreviation: 'de',
old_abbreviation: 'de',
description: '',
name: 'Deutsch',
default_language: false},
{ abbreviation: 'es',
old_abbreviation: 'es',
description: '',
name: 'Español',
default_language: false}
]
languages.each do |lang_data|
# if the old abbreviation exists, remove and replace the data
lang = Language.find_by(abbreviation: lang_data[:old_abbreviation])
if lang.present?
lang.abbreviation = lang_data[:abbreviation]
lang.description = lang_data[:description]
lang.name = lang_data[:name]
lang.default_language = lang_data[:default_language]
lang.save!
else
# if nothing batching either abbreviation exists, replace with new abbreviation
lang = Language.find_by(abbreviation: lang_data[:abbreviation])
if lang.blank?
lang = Language.new
lang.abbreviation = lang_data[:abbreviation]
lang.description = lang_data[:description]
lang.name = lang_data[:name]
lang.default_language = lang_data[:default_language]
lang.save!
end
end
end
end
desc "enforce single published version for templates"
task single_published_template: :environment do
# for each group of versions of a template
Template.all.pluck(:dmptemplate_id).uniq.each do |dmptemplate_id|
published = false
Template.where(dmptemplate_id: dmptemplate_id).order(version: :desc).each do |template|
# leave the first published template we find alone
if !published && template.published
published = true
elsif published && template.published
template.published = false
template.save!
end
end
end
end
# Tasks required to migrate to 0.4.x
# -----------------------------------------------
desc "Initialize plans.visibility to the default specified in application.rb"
task init_plan_visibility: :environment do
default = Rails.configuration.default_plan_visibility.to_sym
Plan.all.each{ |p| p.update_attributes(visibility: default) unless p.visibility == default }
end
desc "Move old plans.data_contact to data_contact_email and data_contact_phone"
task plan_data_contacts: :environment do
email_regex = /([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})/i
phone_regex = /\+?[0-9\-\(\)]{7,}/i
Plan.where('data_contact IS NOT NULL').each do |p|
email = p.data_contact[email_regex]
phone = p.data_contact[phone_regex]
# Remove the email, phone and any prefixes from the oriignal contact
contact = p.data_contact
contact = contact.gsub(email, '') unless email.nil?
contact = contact.gsub(phone, '') unless phone.nil?
contact = contact.gsub(/([Ee]mail|[Pp]hone|[Mm]obile|[Cc]ell|[Oo]ffice|[Hh]ome|[Ww]ork|[Tt]|[Ee]):?/, '')
contact = contact.gsub(' , ', '').strip
contact = contact[0..(contact.length - 2)] if contact.ends_with?(',')
contact = nil if contact == ','
p.update_attributes(data_contact_email: email, data_contact_phone: phone,
data_contact: contact)
end
end
desc "Move old ORCID from users table to user_identifiers"
task move_orcids: :environment do
users = User.includes(:user_identifiers).where('users.orcid_id IS NOT NULL')
# If we have users with orcid ids
if users.length > 0
# If orcid isn't defined in the identifier_schemes table add it
if IdentifierScheme.find_by(name: 'orcid').nil?
IdentifierScheme.create!(name: 'orcid',
description: 'ORCID',
active: true,
logo_url: 'http://orcid.org/sites/default/files/images/orcid_16x16.png',
user_landing_url: 'https://orcid.org')
end
scheme = IdentifierScheme.find_by(name: 'orcid')
unless scheme.nil?
users.each do |u|
if u.orcid_id.gsub('orcid.org/', '').match(/^[\d-]+/)
schemes = u.user_identifiers.collect{|i| i.identifier_scheme_id}
unless schemes.include?(scheme.id)
UserIdentifier.create(user: u, identifier_scheme: scheme,
identifier: u.orcid_id.gsub('orcid.org/', ''))
end
end
end
end
end
end
desc "Move old Shibboleth Ids from users table to user_identifiers"
task move_shibs: :environment do
if Rails.configuration.shibboleth_enabled
users = User.includes(:user_identifiers).where('users.shibboleth_id IS NOT NULL')
# If we have users with orcid ids
if users.length > 0
# If orcid isn't defined in the identifier_schemes table add it
if IdentifierScheme.find_by(name: 'shibboleth').nil?
IdentifierScheme.create!(name: 'shibboleth',
description: "Your institution credentials",
active: true)
end
scheme = IdentifierScheme.find_by(name: 'shibboleth')
unless scheme.nil?
users.each do |u|
schemes = u.user_identifiers.collect{|i| i.identifier_scheme_id}
unless schemes.include?(scheme.id)
# TODO: Add logic to move shib identifiers over
# UserIdentifier.create(user: u, identifier_scheme: scheme,
# identifier: u.orcid_id.gsub('orcid.org/', ''))
end
end
end
end
end
end
desc "remove duplicate annotations caused by bug"
task remove_duplicate_annotations: :environment do
questions = Question.joins(:annotations).group("questions.id").having("count(annotations.id) > count(DISTINCT annotations.text)")
questions.each do |q|
# store already de-duplicated id's so we dont remove them in later iterations
removed = []
q.annotations.each do |a|
removed << a.id
conflicts = Annotation.where(question_id: a.question_id, text: a.text).where.not(id: removed)
conflicts.each {|c| c.destroy }
end
end
end
desc "convert orgs.target_url to JSON array"
task org_target_url_to_links: :environment do
Org.all.each do |org|
if org.target_url.present?
org.links = [{link: org.target_url, text: ''}]
org.target_url = nil
# Running with validations off because Dragonfly will fail if it cannot find the
# org logos which live on the deployed instance
org.save!(validate: false)
end
end
end
end