From 9778158e303871497718e2b6b1460801646c0e7f Mon Sep 17 00:00:00 2001 From: gabina Date: Mon, 6 Nov 2023 13:41:13 -0300 Subject: [PATCH 01/10] Put a quick fix for the copy_course_from_production command to parse update_logs keys as integers instead of strings --- setup/copy_course_from_production.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/setup/copy_course_from_production.rb b/setup/copy_course_from_production.rb index f632560cc9..854c7596f8 100644 --- a/setup/copy_course_from_production.rb +++ b/setup/copy_course_from_production.rb @@ -10,13 +10,14 @@ def make_copy_of(url) home_wiki = Wiki.get_or_create(language: course_data['home_wiki']['language'], project: course_data['home_wiki']['project']) copied_data['home_wiki_id'] = home_wiki.id copied_data['passcode'] = 'passcode' # set an arbitrary passcode + # Fix the update_logs in flags + if copied_data['flags'].key?('update_logs') + copied_data['flags']['update_logs'] = fix_update_logs_parsing(copied_data['flags']['update_logs']) + end # Create the course course = Course.create!( copied_data ) - - # Remove the update_logs, which cause problems due to conversion of integer keys to strings. - course.flags.delete('update_logs') course.save # Add the tracked wikis @@ -50,3 +51,13 @@ def make_copy_of(url) pp "http://localhost:3000/courses/#{course.slug}" end +# When parsing update_logs from flags, keys are set as strings instead of integers +# This causes problems, so we need to force the keys to be integers. +def fix_update_logs_parsing(update_logs) + fixed_update_logs = {} + update_logs.each do |key, value| + # Add the new log with same value but integer key + fixed_update_logs[key.to_i] = value + end + fixed_update_logs +end From ec400debed4f3e252bfd04f865ec8411010e4d00 Mon Sep 17 00:00:00 2001 From: gabina Date: Tue, 7 Nov 2023 00:09:05 -0300 Subject: [PATCH 02/10] Make fix_update_logs_parsing more idiomatic --- setup/copy_course_from_production.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/setup/copy_course_from_production.rb b/setup/copy_course_from_production.rb index 854c7596f8..b14f76e3df 100644 --- a/setup/copy_course_from_production.rb +++ b/setup/copy_course_from_production.rb @@ -54,10 +54,5 @@ def make_copy_of(url) # When parsing update_logs from flags, keys are set as strings instead of integers # This causes problems, so we need to force the keys to be integers. def fix_update_logs_parsing(update_logs) - fixed_update_logs = {} - update_logs.each do |key, value| - # Add the new log with same value but integer key - fixed_update_logs[key.to_i] = value - end - fixed_update_logs + update_logs.transform_keys(&:to_i) end From fa0fb2d0cd4c39295ac48b60f99d21c03f87e306 Mon Sep 17 00:00:00 2001 From: gabina Date: Tue, 7 Nov 2023 00:13:32 -0300 Subject: [PATCH 03/10] Add a first version for the copy course service, and basic specs for it --- app/services/copy_course.rb | 100 +++++++++++++++ spec/services/copy_course_spec.rb | 196 ++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 app/services/copy_course.rb create mode 100644 spec/services/copy_course_spec.rb diff --git a/app/services/copy_course.rb b/app/services/copy_course.rb new file mode 100644 index 0000000000..31ff911acb --- /dev/null +++ b/app/services/copy_course.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +#= Copy course from another server dashboard +class CopyCourse + def initialize(url:) + @url = url + end + + def make_copy + @course_data = retrieve_course_data + copy_main_course_data + add_tracked_wikis + @cat_data = retrieve_categories_data + copy_tracked_categories_data + @users_data = retrieve_users_data + copy_users_data + return { course: @course, error: nil } + rescue StandardError => e + return { course: nil, error: e.message } + rescue ActiveRecord::RecordInvalid => e + return { course: nil, error: "Error copying data to db: #{e.message}" } + end + + private + + def copy_main_course_data + # Extract the attributes we want to copy + params_to_copy = %w[school title term description start end subject slug timeline_start + timeline_end type flags] + copied_data = {} + params_to_copy.each { |p| copied_data[p] = @course_data[p] } + @home_wiki = Wiki.get_or_create(language: @course_data['home_wiki']['language'], + project: @course_data['home_wiki']['project']) + copied_data['home_wiki_id'] = @home_wiki.id + copied_data['passcode'] = 'passcode' # set an arbitrary passcode + if copied_data['flags'].key?('update_logs') + copied_data['flags']['update_logs'] = + fix_update_logs_parsing(copied_data['flags']['update_logs']) + end + # Create the course + @course = Course.create!(copied_data) + end + + # When parsing update_logs from flags, keys are set as strings instead of integers + # This causes problems, so we need to force the keys to be integers. + def fix_update_logs_parsing(update_logs) + update_logs.transform_keys(&:to_i) + end + + def add_tracked_wikis + @course_data['wikis'].each do |wiki_hash| + wiki = Wiki.get_or_create(language: wiki_hash['language'], project: wiki_hash['project']) + next if wiki.id == @home_wiki.id # home wiki was automatically added already + @course.wikis << wiki + end + end + + def copy_tracked_categories_data + @cat_data.each do |cat_hash| + wiki = Wiki.get_or_create(language: cat_hash['wiki']['language'], + project: cat_hash['wiki']['project']) + cat = Category.find_or_create_by!( + depth: cat_hash['depth'], + source: cat_hash['source'], + name: cat_hash['name'], + wiki: + ) + @course.categories << cat + end + end + + def copy_users_data + @users_data.each do |user_hash| + user = User.find_or_create_by!(username: user_hash['username']) + CoursesUsers.create!(user_id: user.id, role: user_hash['role'], course_id: @course.id) + end + end + + def get_request(path) + uri = URI(@url + path) + response = Net::HTTP.get_response(uri) + raise "Error getting data from #{uri}" unless response.is_a?(Net::HTTPSuccess) + response + end + + def retrieve_course_data + response = get_request('/course.json') + JSON.parse(response.body)['course'] + end + + def retrieve_categories_data + response = get_request('/categories.json') + JSON.parse(response.body)['course']['categories'] + end + + def retrieve_users_data + response = get_request('/users.json') + JSON.parse(response.body)['course']['users'] + end +end diff --git a/spec/services/copy_course_spec.rb b/spec/services/copy_course_spec.rb new file mode 100644 index 0000000000..049a2bfc0f --- /dev/null +++ b/spec/services/copy_course_spec.rb @@ -0,0 +1,196 @@ +# frozen_string_literal: true +require 'rails_helper' + +describe CopyCourse do + let(:url_base) { 'https://dashboard.wikiedu.org/courses/' } + let(:existent_prod_course_slug) do + 'University_of_South_Carolina/Invertebrate_Zoology_(Spring_2022)' + end + let(:course_url) { url_base + existent_prod_course_slug + '/course.json' } + let(:categories_url) { url_base + existent_prod_course_slug + '/categories.json' } + let(:users_url) { url_base + existent_prod_course_slug + '/users.json' } + let(:course_response_body) do + '{ + "course": { + "id": 15907, + "slug": "University_of_South_Carolina/Invertebrate_Zoology_(Spring_2022)", + "school": "University of South Carolina", + "title": "Invertebrate Zoology", + "term": "Spring 2022", + "start": "2022-01-11T00:00:00.000Z", + "end": "2022-04-30T23:59:59.000Z", + "type": "ClassroomProgramCourse", + "home_wiki": { + "id": 1, + "language": "en", + "project": "wikipedia" + }, + "flags": { + "update_logs": { + "28763": { + "start_time": "2022-05-26T16:13:42.177+00:00", + "end_time": "2022-05-26T16:13:46.648+00:00", + "sentry_tag_uuid": "4c0a1b87-da5a-4e82-8f40-3d560690cdb2", + "error_count": 0 + } + } + }, + "wikis": [ + { + "language": "en", + "project": "wikipedia" + } + ] + } + }' + end + let(:categories_response_body) do + '{ + "course": { + "categories": [ + { + "name": "Category 0", + "depth": 0, + "source": "Source 0", + "wiki": { + "id": 1, + "language": "en", + "project": "wikipedia" + } + } + ] + } + }' + end + let(:users_response_body) do + '{ + "course": { + "users": [ + { + "role": 1, + "id": 28451264, + "username": "Joshua Stone" + }, + { + "role": 4, + "id": 22694295, + "username": "Helaine (Wiki Ed)" + }, + { + "role": 0, + "id": 28515697, + "username": "CharlieJ385" + }, + { + "role": 0, + "id": 28515751, + "username": "Diqi Yan" + } + ] + } + }' + end + let(:subject) do + service = described_class.new(url: url_base + existent_prod_course_slug) + service.make_copy + end + + describe '#make_copy' do + it 'returns an error if /course.json request fails' do + stub_request(:get, course_url) + .to_return(status: 404, body: '', headers: {}) + + result = subject + expect(result[:error]).to eq("Error getting data from #{course_url}") + expect(result[:course]).to be_nil + end + + it 'returns an error if /categories.json request fails' do + # Stub the response to the course request + stub_request(:get, course_url) + .to_return(status: 200, body: course_response_body, headers: {}) + # Stub the response to the categories request + stub_request(:get, categories_url) + .to_return(status: 404, body: '', headers: {}) + + result = subject + expect(result[:error]).to eq("Error getting data from #{categories_url}") + expect(result[:course]).to be_nil + end + + it 'returns an error if /users.json request fails' do + # Stub the response to the course request + stub_request(:get, course_url) + .to_return(status: 200, body: course_response_body, headers: {}) + + # Stub the response to the categories request + stub_request(:get, categories_url) + .to_return(status: 200, body: categories_response_body, headers: {}) + + # Stub the response to the users request + stub_request(:get, users_url) + .to_return(status: 404, body: '', headers: {}) + + result = subject + expect(result[:error]).to eq("Error getting data from #{users_url}") + expect(result[:course]).to be_nil + end + + it 'course, categories, and users are created if no error' do + # Stub the response to the course request + stub_request(:get, course_url) + .to_return(status: 200, body: course_response_body, headers: {}) + + # Stub the response to the categories request + stub_request(:get, categories_url) + .to_return(status: 200, body: categories_response_body, headers: {}) + + # Stub the response to the users request + stub_request(:get, users_url) + .to_return(status: 200, body: users_response_body, headers: {}) + result = subject + + # No error was returned + expect(result[:error]).to be_nil + # Course returned is not nil + expect(result[:course]).not_to be_nil + + # The course was created + expect(Course.exists?(slug: existent_prod_course_slug)).to eq(true) + + # Course users were created + course = Course.find_by(slug: existent_prod_course_slug) + + expect(course.instructors.length).to eq(1) + expect(course.instructors.first.username).to eq('Joshua Stone') + + expect(course.staff.length).to eq(1) + expect(course.staff.first.username).to eq('Helaine (Wiki Ed)') + + expect(course.students.length).to eq(2) + expect(course.students.first.username).to eq('CharlieJ385') + expect(course.students.second.username).to eq('Diqi Yan') + + # Wiki exists + expect(Wiki.exists?(language: 'en', project: 'wikipedia')).to eq(true) + + # Category was created + expect(Category.exists?(name: 'Category 0', depth: 0, source: 'Source 0', + wiki: 1)).to eq(true) + + # Category course was created + expect(course.categories.length).to eq(1) + + # Users were created + expect(User.exists?(username: 'Joshua Stone')).to eq(true) + expect(User.exists?(username: 'Helaine (Wiki Ed)')).to eq(true) + expect(User.exists?(username: 'CharlieJ385')).to eq(true) + expect(User.exists?(username: 'Diqi Yan')).to eq(true) + + # Update logs were correctly created + course.flags['update_logs'].each do |key, _value| + expect(key).to be_a(Integer) + end + end + end +end From c5d444e9a9f0c5b802f5386bfac97be3063896fd Mon Sep 17 00:00:00 2001 From: gabina Date: Tue, 7 Nov 2023 02:59:41 -0300 Subject: [PATCH 04/10] Create an admin view that executes the make_copy method from the new copy course service --- app/controllers/copy_course_controller.rb | 22 ++++++ app/views/admin/index.html.haml | 14 ++-- app/views/copy_course/index.html.haml | 16 +++++ app/views/shared/_flash.html.haml | 2 +- config/routes.rb | 4 ++ .../copy_course_controller_spec.rb | 67 +++++++++++++++++++ 6 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 app/controllers/copy_course_controller.rb create mode 100644 app/views/copy_course/index.html.haml create mode 100644 spec/controllers/copy_course_controller_spec.rb diff --git a/app/controllers/copy_course_controller.rb b/app/controllers/copy_course_controller.rb new file mode 100644 index 0000000000..11d49c1c8c --- /dev/null +++ b/app/controllers/copy_course_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +#= Controller for Copy Course tool +class CopyCourseController < ApplicationController + respond_to :html + before_action :require_admin_permissions + def index; end + + def copy + service = CopyCourse.new(url: params[:url]) + response = service.make_copy + if response[:error].present? + redirect_to(copy_course_path, + flash: { error: "Course not created: #{response[:error]}" }) + else + course = response[:course] + redirect_to copy_course_path, + notice: "Course #{course.title} was created."\ + " Go to course" + end + end +end diff --git a/app/views/admin/index.html.haml b/app/views/admin/index.html.haml index 6a83875d18..d0064dfff1 100644 --- a/app/views/admin/index.html.haml +++ b/app/views/admin/index.html.haml @@ -13,22 +13,24 @@ .container %h2 Useful links %ul + %li + %a{href: '/faq/new'} Add new FAQ %li %a{href: '/article_finder'} Article Finder %li - %a{href: '/usage'} Usage - %li - %a{href: '/sidekiq'} Job queue + %a{href: '/copy_course'} Copy Course from Another Dashboard Server %li %a{href: 'https://dashboard-testing.wikiedu.org/rails/mailers'} Email templates - %li - %a{href: '/faq/new'} Add new FAQ %li %a{href: '/faq_topics'} FAQ Topics + %li + %a{href: '/feedback_form_responses'} Feedback Form Responses + %li + %a{href: '/sidekiq'} Job queue %li %a{href: '/unsubmitted_courses'} Unsubmitted Courses %li - %a{href: '/feedback_form_responses'} Feedback Form Responses + %a{href: '/usage'} Usage %li %a{href: '/update_username'} Update username \ No newline at end of file diff --git a/app/views/copy_course/index.html.haml b/app/views/copy_course/index.html.haml new file mode 100644 index 0000000000..a366777a2f --- /dev/null +++ b/app/views/copy_course/index.html.haml @@ -0,0 +1,16 @@ +- content_for :before_title, 'Admin - ' + +.container.dashboard + %header + %h1 + = 'Copy course from another Dashboard server' + +%section + .container + %hr + +.container + = form_tag copy_course_path, class: 'explore-courses', method: :post do + = text_field_tag(:url, '', placeholder: 'Copy course URL here...') + %button{type: 'submit'} + %i.icon.icon-check \ No newline at end of file diff --git a/app/views/shared/_flash.html.haml b/app/views/shared/_flash.html.haml index 890a5cd7cb..ef707cceac 100644 --- a/app/views/shared/_flash.html.haml +++ b/app/views/shared/_flash.html.haml @@ -1,5 +1,5 @@ - if flash[:notice] - .notification= flash[:notice] + .notification= flash[:notice].html_safe - unless ENV['sitenotice'].blank? .notification.sitenotice= raw ENV['sitenotice'].dup.force_encoding("UTF-8") diff --git a/config/routes.rb b/config/routes.rb index c705fdf84c..c06c0a970e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -101,6 +101,10 @@ get '/update_username' => 'update_username#index' post '/update_username' => 'update_username#update' + # Copy course from another dashboard server + get 'copy_course' => 'copy_course#index' + post 'copy_course' => 'copy_course#copy' + # Self-enrollment: joining a course by entering a passcode or visiting a url get 'courses/:course_id/enroll/(:passcode)' => 'self_enrollment#enroll_self', constraints: { course_id: /.*/ } diff --git a/spec/controllers/copy_course_controller_spec.rb b/spec/controllers/copy_course_controller_spec.rb new file mode 100644 index 0000000000..d3ab669c8f --- /dev/null +++ b/spec/controllers/copy_course_controller_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe CopyCourseController, type: :request do + describe '#index' do + let(:user) { create(:user) } + let(:admin) { create(:admin) } + + context 'when the user is an admin' do + before do + allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(admin) + end + + it 'shows the feature to copy the course' do + get '/copy_course' + expect(response.status).to eq(200) + end + end + + context 'when the user is not an admin' do + before do + allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(user) + end + + it 'returns a 401 error' do + get '/copy_course' + expect(response.status).to eq(401) + end + end + end + + describe '#copy' do + let(:admin) { create(:admin) } + let(:subject) { post '/copy_course', params: { url: 'someurl.com' } } + + context 'when the copy fails for some reason' do + before do + allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(admin) + response = { course: nil, error: 'An interesting error happened' } + allow_any_instance_of(CopyCourse).to receive(:make_copy).and_return(response) + end + + it 'renders the error' do + subject + expect(response).to redirect_to(copy_course_path) + expect(flash[:error]).to eq('Course not created: An interesting error happened') + end + end + + context 'when the copy is successful' do + before do + allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(admin) + response = { course: create(:basic_course), error: nil } + allow_any_instance_of(CopyCourse).to receive(:make_copy).and_return(response) + end + + it 'renders the success message' do + subject + expect(response).to redirect_to(copy_course_path) + expect(flash[:notice]).to eq('Course Black life matters was created.'\ + ' Go to course') + end + end + end +end From 8402f5529b623057135c31e40936d91f43fc2f49 Mon Sep 17 00:00:00 2001 From: gabina Date: Tue, 7 Nov 2023 12:35:38 -0300 Subject: [PATCH 05/10] Remove inline variable in spec --- spec/controllers/copy_course_controller_spec.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/spec/controllers/copy_course_controller_spec.rb b/spec/controllers/copy_course_controller_spec.rb index d3ab669c8f..a7f8f1f091 100644 --- a/spec/controllers/copy_course_controller_spec.rb +++ b/spec/controllers/copy_course_controller_spec.rb @@ -13,7 +13,7 @@ end it 'shows the feature to copy the course' do - get '/copy_course' + get copy_course_path expect(response.status).to eq(200) end end @@ -24,7 +24,7 @@ end it 'returns a 401 error' do - get '/copy_course' + get copy_course_path expect(response.status).to eq(401) end end @@ -32,13 +32,14 @@ describe '#copy' do let(:admin) { create(:admin) } - let(:subject) { post '/copy_course', params: { url: 'someurl.com' } } + let(:subject) { post copy_course_path, params: { url: 'someurl.com' } } context 'when the copy fails for some reason' do before do allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(admin) - response = { course: nil, error: 'An interesting error happened' } - allow_any_instance_of(CopyCourse).to receive(:make_copy).and_return(response) + allow_any_instance_of(CopyCourse).to receive(:make_copy).and_return( + { course: nil, error: 'An interesting error happened' } + ) end it 'renders the error' do @@ -51,8 +52,9 @@ context 'when the copy is successful' do before do allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(admin) - response = { course: create(:basic_course), error: nil } - allow_any_instance_of(CopyCourse).to receive(:make_copy).and_return(response) + allow_any_instance_of(CopyCourse).to receive(:make_copy).and_return( + { course: create(:basic_course), error: nil } + ) end it 'renders the success message' do From 0be03bb1a451d3feb2ce1193bfe71febb4df248d Mon Sep 17 00:00:00 2001 From: gabina Date: Tue, 7 Nov 2023 12:41:25 -0300 Subject: [PATCH 06/10] Order admin links alphabetically --- app/views/admin/index.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/index.html.haml b/app/views/admin/index.html.haml index d0064dfff1..8774470505 100644 --- a/app/views/admin/index.html.haml +++ b/app/views/admin/index.html.haml @@ -29,8 +29,8 @@ %a{href: '/sidekiq'} Job queue %li %a{href: '/unsubmitted_courses'} Unsubmitted Courses - %li - %a{href: '/usage'} Usage %li %a{href: '/update_username'} Update username + %li + %a{href: '/usage'} Usage \ No newline at end of file From 2bfd96635cd19493c2888df1628124db02531a0a Mon Sep 17 00:00:00 2001 From: gabina Date: Tue, 7 Nov 2023 12:42:37 -0300 Subject: [PATCH 07/10] Merge rescue statements in one --- app/services/copy_course.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/services/copy_course.rb b/app/services/copy_course.rb index 31ff911acb..1ec93c54bb 100644 --- a/app/services/copy_course.rb +++ b/app/services/copy_course.rb @@ -15,10 +15,8 @@ def make_copy @users_data = retrieve_users_data copy_users_data return { course: @course, error: nil } - rescue StandardError => e + rescue ActiveRecord::RecordInvalid, StandardError => e return { course: nil, error: e.message } - rescue ActiveRecord::RecordInvalid => e - return { course: nil, error: "Error copying data to db: #{e.message}" } end private From 048de6856118b649e1f5d97e595e75c18fdaf3fa Mon Sep 17 00:00:00 2001 From: gabina Date: Tue, 7 Nov 2023 18:17:07 -0300 Subject: [PATCH 08/10] Remove extra capitalization and dashboard word --- app/services/copy_course.rb | 2 +- app/views/admin/index.html.haml | 2 +- app/views/copy_course/index.html.haml | 2 +- config/routes.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/copy_course.rb b/app/services/copy_course.rb index 1ec93c54bb..9e19768a5b 100644 --- a/app/services/copy_course.rb +++ b/app/services/copy_course.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -#= Copy course from another server dashboard +#= Copy course from another server class CopyCourse def initialize(url:) @url = url diff --git a/app/views/admin/index.html.haml b/app/views/admin/index.html.haml index 8774470505..d354bcae16 100644 --- a/app/views/admin/index.html.haml +++ b/app/views/admin/index.html.haml @@ -18,7 +18,7 @@ %li %a{href: '/article_finder'} Article Finder %li - %a{href: '/copy_course'} Copy Course from Another Dashboard Server + %a{href: '/copy_course'} Copy course from another server %li %a{href: 'https://dashboard-testing.wikiedu.org/rails/mailers'} Email templates %li diff --git a/app/views/copy_course/index.html.haml b/app/views/copy_course/index.html.haml index a366777a2f..b1792de505 100644 --- a/app/views/copy_course/index.html.haml +++ b/app/views/copy_course/index.html.haml @@ -3,7 +3,7 @@ .container.dashboard %header %h1 - = 'Copy course from another Dashboard server' + = 'Copy course from another server' %section .container diff --git a/config/routes.rb b/config/routes.rb index c06c0a970e..d3c3d15447 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -101,7 +101,7 @@ get '/update_username' => 'update_username#index' post '/update_username' => 'update_username#update' - # Copy course from another dashboard server + # Copy course from another server get 'copy_course' => 'copy_course#index' post 'copy_course' => 'copy_course#copy' From 65188dad85135cd0f29871dc2195194f4d13eb81 Mon Sep 17 00:00:00 2001 From: gabina Date: Tue, 7 Nov 2023 18:32:30 -0300 Subject: [PATCH 09/10] Set a random passcode instead of a fixed one --- app/services/copy_course.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/copy_course.rb b/app/services/copy_course.rb index 9e19768a5b..a347027bf6 100644 --- a/app/services/copy_course.rb +++ b/app/services/copy_course.rb @@ -30,7 +30,7 @@ def copy_main_course_data @home_wiki = Wiki.get_or_create(language: @course_data['home_wiki']['language'], project: @course_data['home_wiki']['project']) copied_data['home_wiki_id'] = @home_wiki.id - copied_data['passcode'] = 'passcode' # set an arbitrary passcode + copied_data['passcode'] = GeneratePasscode.call # set a random passcode if copied_data['flags'].key?('update_logs') copied_data['flags']['update_logs'] = fix_update_logs_parsing(copied_data['flags']['update_logs']) From fff45d60a71334b38b007bfaab1c18b73c09c91d Mon Sep 17 00:00:00 2001 From: gabina Date: Tue, 7 Nov 2023 18:33:37 -0300 Subject: [PATCH 10/10] Remove old command to copy courses --- setup/copy_course_from_production.rb | 58 ---------------------------- 1 file changed, 58 deletions(-) delete mode 100644 setup/copy_course_from_production.rb diff --git a/setup/copy_course_from_production.rb b/setup/copy_course_from_production.rb deleted file mode 100644 index b14f76e3df..0000000000 --- a/setup/copy_course_from_production.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'net/http' - -def make_copy_of(url) - # Get the main course data - course_data = JSON.parse(Net::HTTP.get URI(url + '/course.json'))['course'] - # Extract the attributes we want to copy - params_to_copy = %w[school title term description start end subject slug timeline_start timeline_end type flags] - copied_data = {} - params_to_copy.each { |p| copied_data[p] = course_data[p] } - home_wiki = Wiki.get_or_create(language: course_data['home_wiki']['language'], project: course_data['home_wiki']['project']) - copied_data['home_wiki_id'] = home_wiki.id - copied_data['passcode'] = 'passcode' # set an arbitrary passcode - # Fix the update_logs in flags - if copied_data['flags'].key?('update_logs') - copied_data['flags']['update_logs'] = fix_update_logs_parsing(copied_data['flags']['update_logs']) - end - # Create the course - course = Course.create!( - copied_data - ) - course.save - - # Add the tracked wikis - course_data['wikis'].each do |wiki_hash| - wiki = Wiki.get_or_create(language: wiki_hash['language'], project: wiki_hash['project']) - next if wiki.id == home_wiki.id # home wiki was automatically added already - course.wikis << wiki - end - - # Add the tracked categories - cat_data = JSON.parse(Net::HTTP.get URI(url + '/categories.json'))['course']['categories'] - cat_data.each do |cat_hash| - wiki = Wiki.get_or_create(language: cat_hash['wiki']['language'], project: cat_hash['wiki']['project']) - cat = Category.find_or_create_by!( - depth: cat_hash['depth'], - source: cat_hash['source'], - name: cat_hash['name'], - wiki: wiki - ) - course.categories << cat - end - - # Get the user list - user_data = JSON.parse(Net::HTTP.get URI(url + '/users.json'))['course']['users'] - # Add the users to the course - user_data.each do |user_hash| - user = User.find_or_create_by!(username: user_hash['username']) - CoursesUsers.create!(user_id: user.id, role: user_hash['role'], course_id: course.id) - end - pp 'Course created!' - pp "http://localhost:3000/courses/#{course.slug}" -end - -# When parsing update_logs from flags, keys are set as strings instead of integers -# This causes problems, so we need to force the keys to be integers. -def fix_update_logs_parsing(update_logs) - update_logs.transform_keys(&:to_i) -end