Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions contentcuration/contentcuration/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def write_file_to_storage(fobj, check_valid = False, name=None):
name = name or fobj._name or ""
filename, ext = os.path.splitext(name)
hashed_filename = checksum.hexdigest()
full_filename = "{}{}".format(hashed_filename, ext)
full_filename = "{}{}".format(hashed_filename, ext.lower())
fobj.seek(0)

if check_valid and hashed_filename != filename:
Expand All @@ -54,7 +54,7 @@ def write_raw_content_to_storage(contents, ext=None):
checksum = hashlib.md5()
checksum.update(contents)
filename = checksum.hexdigest()
full_filename = "{}.{}".format(filename, ext)
full_filename = "{}.{}".format(filename, ext.lower())

# Get location of file
file_path = models.generate_file_on_disk_name(filename, full_filename)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ def handle(self, *args, **options):
logging.warning("Exited early due to {message}.".format(message=e.message))
self.stdout.write("You can find your database in {path}".format(path=e.db_path))

def create_kolibri_license_object(license):
def create_kolibri_license_object(ccnode):
use_license_description = ccnode.license.license_name != licenses.SPECIAL_PERMISSIONS
return kolibrimodels.License.objects.get_or_create(
license_name=license.license_name
license_name=ccnode.license.license_name,
license_description=ccnode.license.license_description if use_license_description else ccnode.license_description
)


Expand Down Expand Up @@ -129,10 +131,10 @@ def queue_get_return_none_when_empty():
kolibrinode = create_bare_contentnode(node)

if node.kind.kind == content_kinds.EXERCISE:
exercise_data = process_assessment_metadata(ccnode, kolibrinode)
if node.changed or not node.files.filter(preset_id=format_presets.EXERCISE).exists():
create_perseus_exercise(node, kolibrinode)
if node.kind.kind != content_kinds.TOPIC:
create_associated_file_objects(kolibrinode, node)
create_perseus_exercise(node, kolibrinode, exercise_data)
create_associated_file_objects(kolibrinode, node)
map_tags_to_node(kolibrinode, node)

def create_bare_contentnode(ccnode):
Expand All @@ -141,7 +143,7 @@ def create_bare_contentnode(ccnode):

kolibri_license = None
if ccnode.license is not None:
kolibri_license = create_kolibri_license_object(ccnode.license)[0]
kolibri_license = create_kolibri_license_object(ccnode)[0]

kolibrinode, is_new = kolibrimodels.ContentNode.objects.update_or_create(
pk=ccnode.node_id,
Expand Down Expand Up @@ -197,12 +199,11 @@ def create_associated_file_objects(kolibrinode, ccnode):
thumbnail=preset.thumbnail,
)

def create_perseus_exercise(ccnode, kolibrinode):
def create_perseus_exercise(ccnode, kolibrinode, exercise_data):
logging.debug("Creating Perseus Exercise for Node {}".format(ccnode.title))
filename="{0}.{ext}".format(ccnode.title, ext=file_formats.PERSEUS)
with tempfile.NamedTemporaryFile(suffix="zip", delete=False) as tempf:
data = process_assessment_metadata(ccnode, kolibrinode)
create_perseus_zip(ccnode, data, tempf)
create_perseus_zip(ccnode, exercise_data, tempf)
file_size = tempf.tell()
tempf.flush()

Expand Down
60 changes: 32 additions & 28 deletions contentcuration/contentcuration/static/js/bundle_modules/base.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,66 @@
var attachfastclick = require("fastclick");
var attachfastclick = require('fastclick');

var $ = require("jquery");
var get_cookie = require("utils/get_cookie");
var $ = require('jquery');
var get_cookie = require('utils/get_cookie');
global.$ = $;
global.jQuery = $;
require("handlebars/helpers");
require('handlebars/helpers');

require("../../less/styles.less");
require("bootstrap/dist/js/npm.js");
require("../../js/utils/jquery-ui");
// require("../../../../../node_modules/jquery-ui/ui/widgets/sortable");
require('../../less/styles.less');
require('bootstrap/dist/js/npm.js');
require('../../js/utils/jquery-ui');

var csrftoken = get_cookie("csrftoken") || "";
// Promise polyfill
if(!global.Promise) {
global.Promise = require('promise-polyfill');
}

var csrftoken = get_cookie('csrftoken') || '';

function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

function sameOrigin(url) {
// test that a given url is a same-origin URL
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url === origin || url.slice(0, origin.length + 1) === origin + '/') ||
return (url === origin || url.slice(0, origin.length + 1) === origin + '/') ||
(url === sr_origin || url.slice(0, sr_origin.length + 1) === sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}

$.ajaxSetup({
cache: false,
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
cache: false,
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
// Send the token to same-origin, relative URLs only.
// Send the token only if the method warrants CSRF protection
// Using the CSRFToken value acquired earlier
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
xhr.setRequestHeader('X-CSRFToken', csrftoken);
}
}
});

$.extend( $.expr[ ":" ], {
data: $.expr.createPseudo ?
$.extend( $.expr[ ':' ], {
data: $.expr.createPseudo ?
$.expr.createPseudo(function( dataName ) {
return function( elem ) {
return !!$.data( elem, dataName );
};
return function( elem ) {
return !!$.data( elem, dataName );
};
}) :
// support: jQuery <1.8
function( elem, i, match ) {
return !!$.data( elem, match[ 3 ] );
return !!$.data( elem, match[ 3 ] );
}
});

$(function() {
attachfastclick(document.body);
attachfastclick(document.body);
});
6 changes: 3 additions & 3 deletions contentcuration/contentcuration/view/internal_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from django.views.decorators.csrf import csrf_exempt
from django.template.loader import render_to_string
from contentcuration.api import write_file_to_storage
from contentcuration.models import Exercise, AssessmentItem, Channel, License, FileFormat, File, FormatPreset, ContentKind, ContentNode, ContentTag, Invitation, Language, generate_file_on_disk_name
from contentcuration.models import Exercise, AssessmentItem, Channel, License, FileFormat, File, FormatPreset, ContentKind, ContentNode, ContentTag, Invitation, Language, generate_file_on_disk_name, generate_storage_url
from contentcuration import ricecooker_versions as rc
from le_utils.constants import content_kinds
from django.db.models.functions import Concat
Expand Down Expand Up @@ -305,7 +305,7 @@ def map_files_to_node(node, data):
if file_data.get('language'):
language = Language.objects.get(pk=file_data['language'])

file_path=generate_file_on_disk_name(file_hash[0], file_data['filename'])
file_path=generate_storage_url(file_data['filename'])
if not os.path.isfile(file_path):
raise IOError('{} not found'.format(file_path))

Expand All @@ -326,7 +326,7 @@ def map_files_to_assessment_item(question, data):
""" Generate files that reference the content node's assessment items """
for file_data in data:
file_hash = file_data['filename'].split(".")
file_path = generate_file_on_disk_name(file_hash[0], file_data['filename'])
file_path = generate_storage_url(file_data['filename'])
if not os.path.isfile(file_path):
raise IOError('{} not found'.format(file_path))

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"mathquill": "^0.10.1-a",
"minifyify": "^7.0.3",
"node-lessify": "https://github.com/DXCanas/node-lessify.git",
"promise-polyfill": "^6.0.2",
"summernote": "^0.8.2",
"to-markdown": "^3.0.3",
"underscore": "^1.8.3",
Expand Down
5 changes: 3 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ django-registration==2.1.2
django-hashedfilenamestorage==1.0.0
djangorestframework-bulk==0.2.1
django-email-extras==0.3.3
https://storage.googleapis.com/le-downloads/kolibri/kolibri-0.2.0b1.dev218-py2.py3-none-any.whl
https://storage.googleapis.com/le-downloads/kolibri/kolibri-0.4.0b1.dev20-py2.py3-none-any.whl
validators
le-utils==0.0.9rc23
gunicorn==19.6.0
Expand All @@ -26,4 +26,5 @@ metaphone==0.6
porter2stemmer==1.0
django-postmark==0.1.6
google-cloud-error-reporting==0.24.0
ddtrace==0.8.0
ddtrace==0.8.0
jsonfield==2.0.1