Commit 44805ca3 by Calen Pennington

Make discussion js work for cms as well as lms so that inline discussion xmodules load

parent c0ca7fe6
......@@ -23,12 +23,9 @@ import sys
import tempfile
import os.path
import os
import errno
import glob2
import lms.envs.common
import hashlib
from collections import defaultdict
from path import path
from xmodule.static_content import write_descriptor_styles, write_descriptor_js, write_module_js, write_module_styles
############################ FEATURE CONFIGURATION #############################
......@@ -194,67 +191,27 @@ STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'
# Load javascript and css from all of the available descriptors, and
# prep it for use in pipeline js
from xmodule.x_module import XModuleDescriptor
from xmodule.raw_module import RawDescriptor
from xmodule.error_module import ErrorDescriptor
js_file_dir = PROJECT_ROOT / "static" / "coffee" / "module"
css_file_dir = PROJECT_ROOT / "static" / "sass" / "module"
module_styles_path = css_file_dir / "_module-styles.scss"
for dir_ in (js_file_dir, css_file_dir):
try:
os.makedirs(dir_)
except OSError as exc:
if exc.errno == errno.EEXIST:
pass
else:
raise
js_fragments = set()
css_fragments = defaultdict(set)
for _, descriptor in XModuleDescriptor.load_classes() + [(None, RawDescriptor), (None, ErrorDescriptor)]:
descriptor_js = descriptor.get_javascript()
module_js = descriptor.module_class.get_javascript()
for filetype in ('coffee', 'js'):
for idx, fragment in enumerate(descriptor_js.get(filetype, []) + module_js.get(filetype, [])):
js_fragments.add((idx, filetype, fragment))
for class_ in (descriptor, descriptor.module_class):
fragments = class_.get_css()
for filetype in ('sass', 'scss', 'css'):
for idx, fragment in enumerate(fragments.get(filetype, [])):
css_fragments[idx, filetype, fragment].add(class_.__name__)
module_js_sources = []
for idx, filetype, fragment in sorted(js_fragments):
path = js_file_dir / "{idx}-{hash}.{type}".format(
idx=idx,
hash=hashlib.md5(fragment).hexdigest(),
type=filetype)
with open(path, 'w') as js_file:
js_file.write(fragment)
module_js_sources.append(path.replace(PROJECT_ROOT / "static/", ""))
css_imports = defaultdict(set)
for (idx, filetype, fragment), classes in sorted(css_fragments.items()):
fragment_name = "{idx}-{hash}.{type}".format(
idx=idx,
hash=hashlib.md5(fragment).hexdigest(),
type=filetype)
# Prepend _ so that sass just includes the files into a single file
with open(css_file_dir / '_' + fragment_name, 'w') as js_file:
js_file.write(fragment)
for class_ in classes:
css_imports[class_].add(fragment_name)
with open(module_styles_path, 'w') as module_styles:
for class_, fragment_names in css_imports.items():
imports = "\n".join('@import "{0}";'.format(name) for name in fragment_names)
module_styles.write(""".xmodule_{class_} {{ {imports} }}""".format(
class_=class_, imports=imports
))
from rooted_paths import rooted_glob, remove_root
write_descriptor_styles(PROJECT_ROOT / "static/sass/descriptor", [RawDescriptor, ErrorDescriptor])
write_module_styles(PROJECT_ROOT / "static/sass/module", [RawDescriptor, ErrorDescriptor])
descriptor_js = remove_root(
PROJECT_ROOT / 'static',
write_descriptor_js(
PROJECT_ROOT / "static/coffee/descriptor",
[RawDescriptor, ErrorDescriptor]
)
)
module_js = remove_root(
PROJECT_ROOT / 'static',
write_module_js(
PROJECT_ROOT / "static/coffee/module",
[RawDescriptor, ErrorDescriptor]
)
)
PIPELINE_CSS = {
'base-style': {
......@@ -267,23 +224,18 @@ PIPELINE_ALWAYS_RECOMPILE = ['sass/base-style.scss']
PIPELINE_JS = {
'main': {
'source_filenames': [
pth.replace(COMMON_ROOT / 'static/', '')
for pth
in glob2.glob(COMMON_ROOT / 'static/coffee/src/**/*.coffee')
] + [
pth.replace(PROJECT_ROOT / 'static/', '')
for pth
in glob2.glob(PROJECT_ROOT / 'static/coffee/src/**/*.coffee')
] + ['js/base.js'],
'source_filenames': sorted(
rooted_glob(COMMON_ROOT / 'static/', 'coffee/src/**/*.coffee') +
rooted_glob(PROJECT_ROOT / 'static/', 'coffee/src/**/*.coffee')
) + ['js/base.js'],
'output_filename': 'js/cms-application.js',
},
'module-js': {
'source_filenames': module_js_sources,
'source_filenames': descriptor_js + module_js,
'output_filename': 'js/cms-modules.js',
},
'spec': {
'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in glob2.glob(PROJECT_ROOT / 'static/coffee/spec/**/*.coffee')],
'source_filenames': sorted(rooted_glob(PROJECT_ROOT / 'static/', 'coffee/spec/**/*.coffee')),
'output_filename': 'js/cms-spec.js'
}
}
......
......@@ -8,3 +8,4 @@
@import 'section', 'unit', 'index';
@import 'module/module-styles.scss';
@import 'descriptor/module-styles.scss';
import glob2
def rooted_glob(root, glob):
"""
Returns the results of running `glob` rooted in the directory `root`.
All returned paths are relative to `root`.
Uses glob2 globbing
"""
return remove_root(root, glob2.glob('{root}/{glob}'.format(root=root, glob=glob)))
def remove_root(root, paths):
"""
Returns `paths` made relative to `root`
"""
return [pth.replace(root + '/', '') for pth in paths]
......@@ -17,7 +17,7 @@ class @Video
@embed()
else
window.onYouTubePlayerAPIReady = =>
$('.course-content .video').each ->
@el.each ->
$(this).data('video').embed()
youtubeId: (speed)->
......
"""
This module has utility functions for gathering up the static content
that is defined by XModules and XModuleDescriptors (javascript and css)
"""
import hashlib
import os
import errno
from collections import defaultdict
from .x_module import XModuleDescriptor
def write_module_styles(output_root, extra_descriptors):
return _write_styles(output_root, _list_modules(extra_descriptors))
def write_module_js(output_root, extra_descriptors):
return _write_js(output_root, _list_modules(extra_descriptors))
def write_descriptor_styles(output_root, extra_descriptors):
return _write_styles(output_root, _list_descriptors(extra_descriptors))
def write_descriptor_js(output_root, extra_descriptors):
return _write_js(output_root, _list_descriptors(extra_descriptors))
def _list_descriptors(extra_descriptors):
return [
desc for desc in [
desc for (_, desc) in XModuleDescriptor.load_classes()
] + extra_descriptors
]
def _list_modules(extra_descriptors):
return [
desc.module_class
for desc
in _list_descriptors(extra_descriptors)
]
def _ensure_dir(dir_):
try:
os.makedirs(dir_)
except OSError as exc:
if exc.errno == errno.EEXIST:
pass
else:
raise
def _write_styles(output_root, classes):
_ensure_dir(output_root)
css_fragments = defaultdict(set)
for class_ in classes:
class_css = class_.get_css()
for filetype in ('sass', 'scss', 'css'):
for idx, fragment in enumerate(class_css.get(filetype, [])):
css_fragments[idx, filetype, fragment].add(class_.__name__)
css_imports = defaultdict(set)
for (idx, filetype, fragment), classes in sorted(css_fragments.items()):
fragment_name = "{idx}-{hash}.{type}".format(
idx=idx,
hash=hashlib.md5(fragment).hexdigest(),
type=filetype)
# Prepend _ so that sass just includes the files into a single file
with open(output_root / '_' + fragment_name, 'w') as css_file:
css_file.write(fragment)
for class_ in classes:
css_imports[class_].add(fragment_name)
with open(output_root / '_module-styles.scss', 'w') as module_styles:
for class_, fragment_names in css_imports.items():
imports = "\n".join('@import "{0}";'.format(name) for name in fragment_names)
module_styles.write(""".xmodule_{class_} {{ {imports} }}""".format(
class_=class_, imports=imports
))
def _write_js(output_root, classes):
_ensure_dir(output_root)
js_fragments = set()
for class_ in classes:
module_js = class_.get_javascript()
for filetype in ('coffee', 'js'):
for idx, fragment in enumerate(module_js.get(filetype, [])):
js_fragments.add((idx, filetype, fragment))
module_js = []
for idx, filetype, fragment in sorted(js_fragments):
path = output_root / "{idx}-{hash}.{type}".format(
idx=idx,
hash=hashlib.md5(fragment).hexdigest(),
type=filetype)
with open(path, 'w') as js_file:
js_file.write(fragment)
module_js.append(path)
return module_js
......@@ -21,10 +21,7 @@ Longer TODO:
import sys
import os
import tempfile
import glob2
import errno
import hashlib
from collections import defaultdict
from xmodule.static_content import write_module_styles, write_module_js
import djcelery
from path import path
......@@ -412,6 +409,33 @@ MIDDLEWARE_CLASSES = (
STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'
from xmodule.hidden_module import HiddenDescriptor
from rooted_paths import rooted_glob, remove_root
write_module_styles(PROJECT_ROOT / 'static/sass/module', [HiddenDescriptor])
module_js = remove_root(
PROJECT_ROOT / 'static',
write_module_js(PROJECT_ROOT / 'static/coffee/module', [HiddenDescriptor])
)
courseware_js = (
[
'coffee/src/' + pth + '.coffee'
for pth in ['courseware', 'histogram', 'navigation', 'time']
] +
sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/modules/**/*.coffee'))
)
main_vendor_js = [
'js/vendor/jquery.min.js',
'js/vendor/jquery-ui.min.js',
'js/vendor/jquery.cookie.js',
'js/vendor/jquery.qtip.min.js',
'js/vendor/swfobject/swfobject.js',
]
discussion_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/discussion/**/*.coffee'))
PIPELINE_CSS = {
'application': {
'source_filenames': ['sass/application.scss'],
......@@ -428,99 +452,14 @@ PIPELINE_CSS = {
}
PIPELINE_ALWAYS_RECOMPILE = ['sass/application.scss', 'sass/ie.scss', 'sass/course.scss']
courseware_only_js = [
PROJECT_ROOT / 'static/coffee/src/' + pth + '.coffee'
for pth
in ['courseware', 'histogram', 'navigation', 'time']
]
courseware_only_js += [
pth for pth
in glob2.glob(PROJECT_ROOT / 'static/coffee/src/modules/**/*.coffee')
]
main_vendor_js = [
'js/vendor/jquery.min.js',
'js/vendor/jquery-ui.min.js',
'js/vendor/jquery.cookie.js',
'js/vendor/jquery.qtip.min.js',
'js/vendor/swfobject/swfobject.js',
]
discussion_js = sorted(glob2.glob(PROJECT_ROOT / 'static/coffee/src/discussion/**/*.coffee'))
# Load javascript from all of the available xmodules, and
# prep it for use in pipeline js
from xmodule.x_module import XModuleDescriptor
from xmodule.hidden_module import HiddenDescriptor
js_file_dir = PROJECT_ROOT / "static" / "coffee" / "module"
css_file_dir = PROJECT_ROOT / "static" / "sass" / "module"
module_styles_path = css_file_dir / "_module-styles.scss"
for dir_ in (js_file_dir, css_file_dir):
try:
os.makedirs(dir_)
except OSError as exc:
if exc.errno == errno.EEXIST:
pass
else:
raise
js_fragments = set()
css_fragments = defaultdict(set)
for _, descriptor in XModuleDescriptor.load_classes() + [(None, HiddenDescriptor)]:
module_js = descriptor.module_class.get_javascript()
for filetype in ('coffee', 'js'):
for idx, fragment in enumerate(module_js.get(filetype, [])):
js_fragments.add((idx, filetype, fragment))
module_css = descriptor.module_class.get_css()
for filetype in ('sass', 'scss', 'css'):
for idx, fragment in enumerate(module_css.get(filetype, [])):
css_fragments[idx, filetype, fragment].add(descriptor.module_class.__name__)
module_js_sources = []
for idx, filetype, fragment in sorted(js_fragments):
path = js_file_dir / "{idx}-{hash}.{type}".format(
idx=idx,
hash=hashlib.md5(fragment).hexdigest(),
type=filetype)
with open(path, 'w') as js_file:
js_file.write(fragment)
module_js_sources.append(path.replace(PROJECT_ROOT / "static/", ""))
css_imports = defaultdict(set)
for (idx, filetype, fragment), classes in sorted(css_fragments.items()):
fragment_name = "{idx}-{hash}.{type}".format(
idx=idx,
hash=hashlib.md5(fragment).hexdigest(),
type=filetype)
# Prepend _ so that sass just includes the files into a single file
with open(css_file_dir / '_' + fragment_name, 'w') as js_file:
js_file.write(fragment)
for class_ in classes:
css_imports[class_].add(fragment_name)
with open(module_styles_path, 'w') as module_styles:
for class_, fragment_names in css_imports.items():
imports = "\n".join('@import "{0}";'.format(name) for name in fragment_names)
module_styles.write(""".xmodule_{class_} {{ {imports} }}""".format(
class_=class_, imports=imports
))
PIPELINE_JS = {
'application': {
# Application will contain all paths not in courseware_only_js
'source_filenames': [
pth.replace(COMMON_ROOT / 'static/', '')
for pth
in sorted(glob2.glob(COMMON_ROOT / 'static/coffee/src/**/*.coffee'))
] + [
pth.replace(PROJECT_ROOT / 'static/', '')
for pth in sorted(glob2.glob(PROJECT_ROOT / 'static/coffee/src/**/*.coffee'))\
if pth not in courseware_only_js and pth not in discussion_js
] + [
'source_filenames': sorted(
set(rooted_glob(COMMON_ROOT / 'static', 'coffee/src/**/*.coffee') +
rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/**/*.coffee')) -
set(courseware_js + discussion_js)
) + [
'js/form.ext.js',
'js/my_courses_dropdown.js',
'js/toggle_login_modal.js',
......@@ -530,7 +469,7 @@ PIPELINE_JS = {
'output_filename': 'js/lms-application.js'
},
'courseware': {
'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in courseware_only_js],
'source_filenames': courseware_js,
'output_filename': 'js/lms-courseware.js'
},
'main_vendor': {
......@@ -538,15 +477,15 @@ PIPELINE_JS = {
'output_filename': 'js/lms-main_vendor.js',
},
'module-js': {
'source_filenames': module_js_sources,
'source_filenames': module_js,
'output_filename': 'js/lms-modules.js',
},
'spec': {
'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in glob2.glob(PROJECT_ROOT / 'static/coffee/spec/**/*.coffee')],
'source_filenames': sorted(rooted_glob(PROJECT_ROOT / 'static/', 'coffee/spec/**/*.coffee')),
'output_filename': 'js/lms-spec.js'
},
'discussion' : {
'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in discussion_js],
'discussion': {
'source_filenames': discussion_js,
'output_filename': 'js/discussion.js'
}
}
......
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