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