Skip to content

Commit

Permalink
initial comit
Browse files Browse the repository at this point in the history
  • Loading branch information
thomashutcheson-msm committed Aug 13, 2019
1 parent d72d517 commit 7667e2f
Show file tree
Hide file tree
Showing 14 changed files with 1,538 additions and 52 deletions.
70 changes: 18 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,28 @@
# Notes on producing slides for SCORM package
# Notes on running the scorm.py script which produces a SCORM package

Create markdown file with slide source (test.md in this example).
#Prerequisites
# Notes on producing slides for SCORM package

Folder structure
Create markdown file with slide source (test.md in this example).

/source/test.md
/source/images/<image files to include>
Folder structure

Use pandoc to compile self-contained HTML slides with the slidy framework (requires connection to web to get slidy CSS).
/source/test.md
/source/images/<image files to include>

https://pandoc.org/MANUAL.html#producing-slide-shows-with-pandoc
Use pandoc to compile self-contained HTML slides with the slidy framework (requires connection to web to get slidy CSS).

## Create HTML slides:
pandoc -t slidy --self-contained test.md -o test.html
https://pandoc.org/MANUAL.html#producing-slide-shows-with-pandoc

(can also create PDF slides - requires pdfLaTeX)
pandoc -t beamer test.md -V theme:Warsaw -o test.pdf
## Create HTML slides:
pandoc -t slidy --self-contained test.md -o test.html

(can also create PDF slides - requires pdfLaTeX)
pandoc -t beamer test.md -V theme:Warsaw -o test.pdf

## Create a SCORM package
#Running the Python script
You just need to provide two arguments with the python script:
The first argument is the name you want to give your scorm package.
The second argument is the name of your created self-contained html file (created in the Prerequisites)

Course_1.zip is a valid scorm package.
File `imsmanifest.xml` is the definition of what goes in the package. The other XSD files are required boilerplate that we don't need to fiddle with.
Folder `Course_1/res/` is where we put the slides and any other files that are needed (in this example a PDF file).

Around line 28-32 there is a resource tag that defines what files are in the package and which one should be the start when the learning management system (LMS) launches the package (our LMS is Looop but there are plenty of others on the market).

```xml
<resource identifier="resource" type="webcontent" adlcp:scormtype="sco" href="res/test.html">
<file href="res/test.html"/>
<file href="res/GitCoreConcepts.pdf"/>
</resource>
```

Wrapping the contents of the Course_1 folder up as a zip (as it is in the folder here) is what produces a scorm package.

# Steps to script things up

## Set up a template scorm folder
this contains all the boilerplate XSDs and templates etc

## copy boilerplate into a tmp folder

## Use Jinja2 template for imsmanifest
We can use a Jinja2 template to make the resource file list and starting resource into variables
e.g. something like:

```xml
<resource identifier="resource" type="webcontent" adlcp:scormtype="sco" href="{{starting_resource}}">
{% for resource in resourcelist %}
<file {{ resource }} >
{% endfor %}
</resource>
```

## create imsmanifest from list of files the user provides and put that in tmp folder
## copy user's input files into `/res/` in the tmp folder
## zip up the tmp folder to produce a scorm package.


# scorm_package
#For help run -h or --help "python scorm.py -h" otherwise contact [email protected]
193 changes: 193 additions & 0 deletions SCORM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#!/usr/bin/python
import os
import sys
from distutils.dir_util import copy_tree
from jinja2 import Environment, FileSystemLoader, Template
import zipfile
import shutil
import argparse


def argumentParser():
"""
Creates a -h / --help flag that describes what the user is required to do, sets a requirement for two arguments to run the script, 1) scorm package name and 2) the name of a html file.
"""
parser = argparse.ArgumentParser(add_help=False)

parser.add_argument('-h', '--help', action='help', help='To run this script please provide two arguments: first argument should be your scorm package name, second argument should be your html file name. Note: Any current zipped folder in the run directory with the same scorm package name will be overwritten.')
parser.add_argument('package_name', action="store", help='Please provide your scorm package name as the first argument')
parser.add_argument('html_file_name', action="store", help='Please provide your html file name as the second argument')

return parser.parse_args()


def create_directories(dirName):
"""
Create directories
"""
# Create directory

try:
# Create target Directory
os.mkdir(dirName)
print("Directory " , dirName , " Created ")
except FileExistsError:
print("Directory " , dirName , " already exists")
exit(1)
subDirName = dirName+'/res'

# Create target directory & all intermediate directories if don't exists
try:
os.makedirs(subDirName)
print("Directory " , subDirName , " Created ")
except FileExistsError:
print("Directory " , subDirName , " already exists")
return subDirName


def copy_files(dirName, static):
"""
Copy xsd files from static folder to named directory
"""

fromDirectory = static
toDirectory = dirName
try:
copy_tree(fromDirectory, toDirectory)
print("Content Copied From " , fromDirectory ,"to", toDirectory, " Successfully ")
except FileExistsError:
print("Content Failed to Copy From " , fromDirectory ,"to", toDirectory, "")
exit(1)


def copy_resources(subDirName, resfiles):
"""
Copy resource files from resource folder to named directory sub folder res
"""

fromDirectory = resfiles
toDirectory = subDirName
try:
copy_tree(fromDirectory, toDirectory)
print("Content Copied From " , fromDirectory ,"to", toDirectory, " Successfully ")
except FileExistsError:
print("Content Failed to Copy From " , fromDirectory ,"to", toDirectory, "")
exit(1)

def resourcelist(resource_content):
"""
Gets all the file paths for the content of the newly created sub-directory "/res"
which is used in jinj_template which edits the imsmanifest.xml file.
"""
all_resources = os.listdir (resource_content)
output = ["res/" + f for f in all_resources ]
return output

def jinja_template(dirName, htmlfile, all_resources, templatefile):
"""
Edits the imsmanifest.xml file, adds a list of the resource files to the xml.
"""

f = open(templatefile)

mytext = f.read()
template = Template(mytext)

output = template.render(starting_resource = htmlfile, resourcelist = all_resources, title=dirName)

outfile = open(dirName +'/imsmanifest.xml', 'w')
outfile.write(output)
outfile.close()

#----------------------------
#Zip folder to create scorm package
#------------------------------

def retrieve_file_paths(dirName):
"""
Retrieves the filepath for the directoy being zipped.
"""
# setup file paths variable
filePaths = []

# Read all directory, subdirectories and file lists
for root, directories, files in os.walk(dirName):
for filename in files:
# Create the full filepath by using os module.
filePath = os.path.join(root, filename)
filePaths.append(filePath)

# return all paths
return filePaths


def zip_directory(dirName):
"""
The zip_directory function zips the content of the created score_package folder.
"""

# Assign the name of the directory to zip
dir_name = dirName

# Call the function to retrieve all files and folders of the assigned directory

filePaths = retrieve_file_paths(dir_name)

# printing the list of all files to be zipped
print('The following list of files will be zipped:')
for fileName in filePaths:
print(fileName)

# writing files to a zipfile
zip_file = zipfile.ZipFile(dir_name+'.zip', 'w')
with zip_file:
# writing each file one by one
for file in filePaths:
zip_file.write(file)

print(dir_name+'.zip file is created successfully!')


def delete_directory(dirName):
"""
The delete_directory function deletes the created folder structure leaving the user with just the zipped scorm package.
"""

# delete directory
dirName = dirName

try:
# Delete target Directory
shutil.rmtree(dirName, ignore_errors=False, onerror=None)
print("Directory " , dirName , " Deleted ")
except FileExistsError:
print("Directory " , dirName , " Failed to Delete")


def main():

args = argumentParser()
dirName=args.package_name
htmlResource=args.html_file_name

subDirName = create_directories(dirName)

resource_content = dirName + '/res/'

copy_files(dirName = dirName, static ='static/')

copy_resources(subDirName = subDirName, resfiles = 'resources/')

resources = resourcelist(resource_content)

jinja_template(dirName = dirName, htmlfile = 'res/' + htmlResource,
all_resources =resources,
templatefile = "static/imsmanifest.xml")

zip_directory(dirName = dirName)

delete_directory(dirName = dirName)

# Call the main function
if __name__ == "__main__":
main()
45 changes: 45 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

##Steps taken to create the Python Script
-----------------------------------------
## Create a SCORM package

Course_1.zip is a valid scorm package.
File `imsmanifest.xml` is the definition of what goes in the package. The other XSD files are required boilerplate that we don't need to fiddle with.
Folder `Course_1/res/` is where we put the slides and any other files that are needed (in this example a PDF file).

Around line 28-32 there is a resource tag that defines what files are in the package and which one should be the start when the learning management system (LMS) launches the package (our LMS is Looop but there are plenty of others on the market).

```xml
<resource identifier="resource" type="webcontent" adlcp:scormtype="sco" href="res/test.html">
<file href="res/test.html"/>
<file href="res/GitCoreConcepts.pdf"/>
</resource>
```

Wrapping the contents of the Course_1 folder up as a zip (as it is in the folder here) is what produces a scorm package.

# Steps to script things up

## Set up a template scorm folder
this contains all the boilerplate XSDs and templates etc

## copy boilerplate into a tmp folder

## Use Jinja2 template for imsmanifest
We can use a Jinja2 template to make the resource file list and starting resource into variables
e.g. something like:

```xml
<resource identifier="resource" type="webcontent" adlcp:scormtype="sco" href="{{starting_resource}}">
{% for resource in resourcelist %}
<file {{ resource }} >
{% endfor %}
</resource>
```

## create imsmanifest from list of files the user provides and put that in tmp folder
## copy user's input files into `/res/` in the tmp folder
## zip up the tmp folder to produce a scorm package.


# scorm_package
Binary file added resources/GitCoreConcepts.pdf
Binary file not shown.
Loading

0 comments on commit 7667e2f

Please sign in to comment.