Commit 652c2623 by Steven Zheng Committed by Steven Zheng

Create master command for course-generator tool

parent 373422dd
...@@ -106,11 +106,17 @@ vnc-passwords: ## Get the VNC passwords for the Chrome and Firefox Selenium cont ...@@ -106,11 +106,17 @@ vnc-passwords: ## Get the VNC passwords for the Chrome and Firefox Selenium cont
mysql-shell: ## Run a shell on the mysql container mysql-shell: ## Run a shell on the mysql container
docker-compose exec mysql bash docker-compose exec mysql bash
create-course-studio: ## Generates a course on studio using the configurations in test-course.json # Provisions studio, ecommerce, and marketing with course(s) in test-course.json
./course-generator/create-course-studio.sh ./course-generator/test-course.json # Modify test-course.json before running this make target to generate a custom course
create-test-course: ## NOTE: marketing course creation is not available for those outside edX
create-course-ecommerce: ## Generates a course on ecommerce using the configurations in test-course.json ./course-generator/create-courses.sh --studio --ecommerce --marketing course-generator/test-course.json
./course-generator/create-course-ecommerce.sh ./course-generator/test-course.json
# Run the course json builder script and use the outputted course json to provision studio, ecommerce, and marketing
# Modify the list of courses in build-course-json.sh beforehand to generate custom courses
build-courses: ## NOTE: marketing course creation is not available for those outside edX
./course-generator/build-course-json.sh course-generator/tmp-config.json
./course-generator/create-courses.sh --studio --ecommerce --marketing course-generator/tmp-config.json
rm course-generator/tmp-config.json
check-memory: check-memory:
@if [ `docker info --format '{{json .}}' | python -c "from __future__ import print_function; import sys, json; print(json.load(sys.stdin)['MemTotal'])"` -lt 2147483648 ]; then echo "\033[0;31mWarning, System Memory is set too low!!! Increase Docker memory to be at least 2 Gigs\033[0m"; fi || exit 0 @if [ `docker info --format '{{json .}}' | python -c "from __future__ import print_function; import sys, json; print(json.load(sys.stdin)['MemTotal'])"` -lt 2147483648 ]; then echo "\033[0;31mWarning, System Memory is set too low!!! Increase Docker memory to be at least 2 Gigs\033[0m"; fi || exit 0
# Script to build course configurations in proper json format that can be passed into provision-courses.sh
# See test-course.json for a master list of course configurations
# TODO: Link documentation for course-generator-tool
# USAGE: ./build-course-json.sh [course-config-file]
if [ "$#" -ne 1 ]; then
echo "Illegal number of parameters"
exit
fi
config_file="$1"
write_to_config() {
# Write (json) content to the config file
echo "$@" > $config_file
}
wrap_json() {
# Wrap the content in curly braces '{}'
echo "{"
echo "$@"
echo "}"
}
build_course_base() {
# Print the (key-value pairs) base requirements of the course json.
# $1 = organization
# $2 = number (setting this to null acts as a proxy for random during course provisioning)
# $3 = run
# $4 = user
# $5 = partner
#
# Output: '"organization":..., "number":...,'
base_values=("$@")
base_keys=(
"organization"
"number"
"run"
"user"
"partner"
)
last=`expr ${#base_keys[@]} - 1`
for ((i=0;i<${#base_keys[@]};++i)); do
echo "\"${base_keys[i]}\": ${base_values[i]}"
if [ $i -ne $last ]; then
echo ","
fi
done
}
build_course_fields() {
# Print the (key-value pairs) fields (studio settings) of the course json
# $1 = "display_name"
#
# Output: '"display_name":...,'
fields_values=("$@")
fields_keys=(
"display_name"
"mobile_available"
)
last=`expr ${#fields_keys[@]} - 1`
for ((i=0;i<${#fields_keys[@]};++i)); do
echo "\"${fields_keys[i]}\": ${fields_values[i]}"
if [ $i -ne $last ]; then
echo ","
fi
done
}
build_course_enrollment() {
# Print the (key-value pairs) enrollment data of the course json
# $1 = audit
# $2 = honor
# $3 = verified
# $4 = professional_education
# $5 = no_id_verification
# $6 = credit
# $7 = credit_provider
#
# Output:'"audit":..., "honor":...,'
enrollment_values=("$@")
enrollment_keys=(
"audit"
"honor"
"verified"
"professional_education"
"no_id_verification"
"credit"
"credit_provider"
)
last=`expr ${#enrollment_keys[@]} - 1`
for ((i=0;i<${#enrollment_keys[@]};++i)); do
echo "\"${enrollment_keys[i]}\": ${enrollment_values[i]}"
if [ $i -ne $last ]; then
echo ","
fi
done
}
#################################################
### DEFINE COURSE BUILDER FUNCTIONS HERE ###
#################################################
# Output should be a course json object
build_course_mode() {
# Builds properly formatted, wrapped json for single course with configurable enrollment settings
# $1 = display_name
# $2 = audit
# $3 = honor
# $4 = verified
# $5 = professional_education
# $6 = no_id_verification
# $7 = credit
# $8 = credit_provider
#
# Output: '{...course-settings...}'
wrap_json $(
# 1. Base settings
build_course_base "\"test-course-generator\"" null "\"1\"" "\"edx@example.com\"" "\"edx\""
echo ","
# 2. Fields settings ("fields" key is at the same level as base settings)
echo "\"fields\":"
wrap_json $(build_course_fields "$1" true)
echo ","
# 3. Enrollment Settings ("enrollment" key is at the same level as base settings)
echo "\"enrollment\":"
wrap_json $(build_course_enrollment "$2" "$3" "$4" "$5" "$6" "$7" "$8")
)
}
#################################################
################################
### DEFINE COURSES HERE ###
################################
# array of courses, where each element is course json object
courses=(
# Build audit course
"$(build_course_mode "\"audit course\"" true false false false false false null)"
# Build honor course
"$(build_course_mode "\"honor course\"" false true false false false false null)"
# Build verified course with audit seat
"$(build_course_mode "\"verified course with audit seat\"" true false true false false false null)"
# Build verified course with honor seat
"$(build_course_mode "\"verified course with honor seat\"" false true true false false false null)"
# Build professional course with required id verification
"$(build_course_mode "\"professional course id required\"" false false false true false false null)"
# Build professional course without required id verification
"$(build_course_mode "\"professional course id not required\"" false false false true true false null)"
# Build credit course with audit seat
"$(build_course_mode "\"credit course with audit seat\"" true false true false false true "\"test-credit-provider\"")"
# Build credit course with honor seat
"$(build_course_mode "\"credit course with honor seat\"" false true true false false true "\"test-credit-provider\"")"
)
################################
# Print courses in proper format
# '{"courses": [...list of course json objects...]}'
courses_json=$(wrap_json $(
echo "\"courses\":"
echo "["
last=`expr ${#courses[@]} - 1`
for ((i=0;i<${#courses[@]};++i)); do
echo "${courses[i]}"
if [ $i -ne $last ]; then
echo ","
fi
done
echo "]"
))
write_to_config "$courses_json"
# Pretty print json
cat $config_file | python -m json.tool > "tmp.json"
cat "tmp.json" > $config_file
rm "tmp.json"
# Script that generates in ecommerce the courses
if [ "$#" -ne 1 ]; then
echo "Must supply the course config file. E.g. create-course-ecommerce.sh test-course.json"
else
SETTINGS=`tr -d '\n' < "$1"`
docker exec -t edx.devstack.ecommerce bash -c "source /edx/app/ecommerce/ecommerce_env && python /edx/app/ecommerce/ecommerce/manage.py generate_courses '$SETTINGS'"
fi
# Script that generates in marketing the courses
if [ "$#" -ne 1 ]; then
echo "Must supply the course config file. E.g. create-course-marketing.sh test-course.json"
else
SETTINGS=`tr -d '\n' < "$1"`
docker exec -t edx.devstack.marketing bash -c "drush generate_courses '$SETTINGS'"
fi
# Script that generates in studio the courses
if [ "$#" -ne 1 ]; then
echo "Must supply the course config file. E.g. create-course-studio.sh test-course.json"
else
SETTINGS=`tr -d '\n' < "$1"`
docker-compose exec lms bash -c "source /edx/app/edxapp/edxapp_env && python /edx/app/edxapp/edx-platform/manage.py cms --settings=devstack_docker generate_courses '$SETTINGS'"
fi
# Script that provisions studio, ecommerce, marketing with courses
# USAGE: ./create-courses [--studio] [--ecommerce] [--marketing] course-config.json
studio=false
ecommerce=false
marketing=false
echo "Parsing options"
container_error=false
for arg in "$@"; do
if [ $arg == "--studio" ]; then
if [ ! "$(docker-compose exec lms bash -c 'echo "Course will be created for studio"; exit $?')" ]; then
echo "Issue with studio container"
container_error=true
else
studio=true
fi
elif [ $arg == "--ecommerce" ]; then
if [ ! "$(docker exec -t edx.devstack.ecommerce bash -c 'echo "Course will be created for ecommerce"; exit $?')" ]; then
echo "Issue with ecommerce container"
container_error=true
else
ecommerce=true
fi
elif [ $arg == "--marketing" ]; then
if [ ! "$(docker exec -t edx.devstack.marketing bash -c 'echo "Course will be created for marketing"; exit $?')" ]; then
echo "Issue with marketing container"
container_error=true
else
marketing=true
fi
fi
done
if $container_error; then
echo "Aborting course creation. Check your containers"
exit
fi
# Users can specify null course numbers in the course_config json as a proxy for random numbers
## This will allow users to rerun the command multiple times and avoid duplicate course ids
course_config_file="${@: -1}"
if [[ ! -f $course_config_file ]] ; then
echo "$course_config_file does not exist. Must provide a valid course config file."
exit
fi
course_json=""
while IFS='' read -r line || [[ -n "$line" ]]; do
course_json=$course_json${line/"\"number\": null"/"\"number\": \""$RANDOM"\""}
done < "${@: -1}"
if $studio ; then
echo "Creating courses on studio."
docker-compose exec lms bash -c "source /edx/app/edxapp/edxapp_env && python /edx/app/edxapp/edx-platform/manage.py cms --settings=devstack_docker generate_courses '$course_json'"
fi
if $ecommerce ; then
echo "Creating courses on ecommerce."
docker exec -t edx.devstack.ecommerce bash -c "source /edx/app/ecommerce/ecommerce_env && python /edx/app/ecommerce/ecommerce/manage.py generate_courses '$course_json'"
fi
if $marketing ; then
echo "Creating courses on marketing."
docker exec -t edx.devstack.marketing bash -c "drush generate_courses '$course_json'"
fi
{
"courses": [
{
"enrollment": {
"audit": false,
"honor": true,
"verified": true,
"professional_education": false,
"no_id_verification": false,
"credit": true,
"credit_provider": "test-credit-provider"
},
"fields": {
"display_name": "Test_Course",
"enable_proctored_exams": true,
"mobile_available": true,
"course_survey_required": true,
"discussion_sort_alpha": true,
"invitation_only": true,
"allow_anonymous": true,
"bypass_home": true,
"entrance_exam_enabled": true,
"show_timezone": true,
"allow_unsupported_xblocks": true,
"allow_public_wiki_access": true,
"allow_proctoring_opt_out": true,
"is_new": true,
"issue_badges": true,
"certificates_show_before_end": true,
"disable_progress_graph": true,
"no_grade": true,
"enable_ccx": true,
"allow_anonymous_to_peers": true,
"create_zendesk_tickets": true,
"hide_progress_tab": true,
"show_calculator": true,
"cert_html_view_enabled": true,
"enable_subsection_gating": true,
"enable_timed_exams": true,
"self_paced": true
},
"organization": "test-course-generator",
"number": null,
"run": "1",
"user": "edx@example.com",
"partner": "edx"
}
]
}
{
"courses": [
{
"enrollment": {
"audit": true,
"credit": false,
"credit_provider": null,
"honor": false,
"no_id_verification": false,
"professional_education": false,
"verified": false
},
"fields": {
"display_name": "audit course"
},
"number": null,
"organization": "test-course-generator",
"partner": "edx",
"run": "1",
"user": "edx@example.com"
},
{
"enrollment": {
"audit": false,
"credit": false,
"credit_provider": null,
"honor": true,
"no_id_verification": false,
"professional_education": false,
"verified": false
},
"fields": {
"display_name": "honor course"
},
"number": null,
"organization": "test-course-generator",
"partner": "edx",
"run": "1",
"user": "edx@example.com"
},
{
"enrollment": {
"audit": true,
"credit": false,
"credit_provider": null,
"honor": false,
"no_id_verification": false,
"professional_education": false,
"verified": true
},
"fields": {
"display_name": "verified course with audit seat"
},
"number": null,
"organization": "test-course-generator",
"partner": "edx",
"run": "1",
"user": "edx@example.com"
},
{
"enrollment": {
"audit": false,
"credit": false,
"credit_provider": null,
"honor": true,
"no_id_verification": false,
"professional_education": false,
"verified": true
},
"fields": {
"display_name": "verified course with honor seat"
},
"number": null,
"organization": "test-course-generator",
"partner": "edx",
"run": "1",
"user": "edx@example.com"
},
{
"enrollment": {
"audit": false,
"credit": false,
"credit_provider": null,
"honor": false,
"no_id_verification": false,
"professional_education": true,
"verified": false
},
"fields": {
"display_name": "professional course id required"
},
"number": null,
"organization": "test-course-generator",
"partner": "edx",
"run": "1",
"user": "edx@example.com"
},
{
"enrollment": {
"audit": false,
"credit": false,
"credit_provider": null,
"honor": false,
"no_id_verification": true,
"professional_education": true,
"verified": false
},
"fields": {
"display_name": "professional course id not required"
},
"number": null,
"organization": "test-course-generator",
"partner": "edx",
"run": "1",
"user": "edx@example.com"
},
{
"enrollment": {
"audit": true,
"credit": true,
"credit_provider": "test-credit-provider",
"honor": false,
"no_id_verification": false,
"professional_education": false,
"verified": true
},
"fields": {
"display_name": "credit course with audit seat"
},
"number": null,
"organization": "test-course-generator",
"partner": "edx",
"run": "1",
"user": "edx@example.com"
},
{
"enrollment": {
"audit": false,
"credit": true,
"credit_provider": "test-credit-provider",
"honor": true,
"no_id_verification": false,
"professional_education": false,
"verified": true
},
"fields": {
"display_name": "credit course with honor seat"
},
"number": null,
"organization": "test-course-generator",
"partner": "edx",
"run": "1",
"user": "edx@example.com"
}
]
}
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
"courses": [ "courses": [
{ {
"organization": "test-course-generator", "organization": "test-course-generator",
"number": "1", "number": null,
"run": "1", "run": "1",
"user": "edx@example.com", "user": "edx@example.com",
"partner": "edx", "partner": "edx",
"fields": { "fields": {
"display_name": "Test Course", "display_name": "Test_Course",
"enable_proctored_exams": null, "enable_proctored_exams": null,
"mobile_available": null, "mobile_available": null,
"discussion_link": null, "discussion_link": null,
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
"entrance_exam_minimum_score_pct": null, "entrance_exam_minimum_score_pct": null,
"max_student_enrollments_allowed": null, "max_student_enrollments_allowed": null,
"announcement": null, "announcement": null,
"invitation_only": true, "invitation_only": null,
"certificates_display_behavior": null, "certificates_display_behavior": null,
"allow_anonymous": null, "allow_anonymous": null,
"enrollment_start": null, "enrollment_start": null,
...@@ -30,14 +30,12 @@ ...@@ -30,14 +30,12 @@
"course_survey_name": null, "course_survey_name": null,
"cert_html_view_overrides": null, "cert_html_view_overrides": null,
"bypass_home": null, "bypass_home": null,
"has_children": null,
"entrance_exam_enabled": null, "entrance_exam_enabled": null,
"show_timezone": null, "show_timezone": null,
"minimum_grade_credit": null, "minimum_grade_credit": null,
"cert_name_long": null, "cert_name_long": null,
"cosmetic_display_price": null, "cosmetic_display_price": null,
"ccx_connector": null, "ccx_connector": null,
"textbooks": null,
"advertised_start": null, "advertised_start": null,
"certificate_available_date": null, "certificate_available_date": null,
"allow_unsupported_xblocks": null, "allow_unsupported_xblocks": null,
......
...@@ -12,6 +12,3 @@ up-marketing-sync: ## Bring up all services (including the marketing site) with ...@@ -12,6 +12,3 @@ up-marketing-sync: ## Bring up all services (including the marketing site) with
clean-marketing-sync: ## Remove the docker-sync containers for all services (including the marketing site) clean-marketing-sync: ## Remove the docker-sync containers for all services (including the marketing site)
docker-sync-stack clean -c docker-sync-marketing-site.yml docker-sync-stack clean -c docker-sync-marketing-site.yml
create-course-marketing: ## Generates a course on the marketing site using the configurations in test-course.json
./course-generator/create-course-marketing.sh ./course-generator/test-course.json
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment