def _get_asset_json(display_name, date, location, thumbnail_location, locked): """ Helper method for formatting the asset information to send to client. """ asset_url = StaticContent.get_url_path_from_location(location) external_url = settings.LMS_BASE + asset_url return { 'display_name': display_name, 'date_added': get_default_time_display(date), 'url': asset_url, 'external_url': external_url, 'portable_url': StaticContent.get_static_path_from_location(location), 'thumbnail': StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_location is not None else None, 'locked': locked, # Needed for Backbone delete/update. 'id': asset_url }
def asset_index(request, org, course, name): """ Display an editable asset library org, course, name: Attributes of the Location for the item to edit """ location = get_location_and_verify_access(request, org, course, name) upload_asset_callback_url = reverse('upload_asset', kwargs={ 'org': org, 'course': course, 'coursename': name }) course_module = modulestore().get_item(location) course_reference = StaticContent.compute_location(org, course, name) assets = contentstore().get_all_content_for_course(course_reference) # sort in reverse upload date order assets = sorted(assets, key=lambda asset: asset['uploadDate'], reverse=True) asset_display = [] for asset in assets: asset_id = asset['_id'] display_info = {} display_info['displayname'] = asset['displayname'] display_info['uploadDate'] = get_default_time_display( asset['uploadDate'].timetuple()) asset_location = StaticContent.compute_location( asset_id['org'], asset_id['course'], asset_id['name']) display_info['url'] = StaticContent.get_url_path_from_location( asset_location) # note, due to the schema change we may not have a 'thumbnail_location' # in the result set _thumbnail_location = asset.get('thumbnail_location', None) thumbnail_location = Location( _thumbnail_location) if _thumbnail_location is not None else None display_info['thumb_url'] = StaticContent.get_url_path_from_location( thumbnail_location) if thumbnail_location is not None else None asset_display.append(display_info) return render_to_response( 'asset_index.html', { 'active_tab': 'assets', 'context_course': course_module, 'assets': asset_display, 'upload_asset_callback_url': upload_asset_callback_url })
def asset_index(request, org, course, name): """ Display an editable asset library org, course, name: Attributes of the Location for the item to edit """ location = get_location_and_verify_access(request, org, course, name) upload_asset_callback_url = reverse('upload_asset', kwargs={ 'org': org, 'course': course, 'coursename': name }) course_module = modulestore().get_item(location) course_reference = StaticContent.compute_location(org, course, name) assets = contentstore().get_all_content_for_course(course_reference) # sort in reverse upload date order assets = sorted(assets, key=lambda asset: asset['uploadDate'], reverse=True) if request.META.get('HTTP_ACCEPT', "").startswith("application/json"): return JsonResponse(assets_to_json_dict(assets)) asset_display = [] for asset in assets: asset_id = asset['_id'] display_info = {} display_info['displayname'] = asset['displayname'] display_info['uploadDate'] = get_default_time_display(asset['uploadDate']) asset_location = StaticContent.compute_location(asset_id['org'], asset_id['course'], asset_id['name']) display_info['url'] = StaticContent.get_url_path_from_location(asset_location) display_info['portable_url'] = StaticContent.get_static_path_from_location(asset_location) # note, due to the schema change we may not have a 'thumbnail_location' in the result set _thumbnail_location = asset.get('thumbnail_location', None) thumbnail_location = Location(_thumbnail_location) if _thumbnail_location is not None else None display_info['thumb_url'] = StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_location is not None else None asset_display.append(display_info) return render_to_response('asset_index.html', { 'context_course': course_module, 'assets': asset_display, 'upload_asset_callback_url': upload_asset_callback_url, 'remove_asset_callback_url': reverse('remove_asset', kwargs={ 'org': org, 'course': course, 'name': name }) })
def setUp(self): """ Create user and login. """ settings.MODULESTORE['default']['OPTIONS']['fs_root'] = path( 'common/test/data') settings.MODULESTORE['direct']['OPTIONS']['fs_root'] = path( 'common/test/data') self.client = Client() self.contentstore = contentstore() # A locked asset self.loc_locked = Location('c4x', 'edX', 'toy', 'asset', 'sample_static.txt') self.url_locked = StaticContent.get_url_path_from_location( self.loc_locked) # An unlocked asset self.loc_unlocked = Location('c4x', 'edX', 'toy', 'asset', 'another_static.txt') self.url_unlocked = StaticContent.get_url_path_from_location( self.loc_unlocked) import_from_xml(modulestore('direct'), 'common/test/data/', ['toy'], static_content_store=self.contentstore, verbose=True) self.contentstore.set_attr(self.loc_locked, 'locked', True) # Create user self.usr = '******' self.pwd = 'foo' email = '*****@*****.**' self.user = User.objects.create_user(self.usr, email, self.pwd) self.user.is_active = True self.user.save() # Create staff user self.staff_usr = '******' self.staff_pwd = 'foo' staff_email = '*****@*****.**' self.staff_user = User.objects.create_user(self.staff_usr, staff_email, self.staff_pwd) self.staff_user.is_active = True self.staff_user.is_staff = True self.staff_user.save()
def _get_asset_json(display_name, date, location, thumbnail_location, locked): """ Helper method for formatting the asset information to send to client. """ asset_url = StaticContent.get_url_path_from_location(location) return { 'display_name': display_name, 'date_added': get_default_time_display(date), 'url': asset_url, 'portable_url': StaticContent.get_static_path_from_location(location), 'thumbnail': StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_location is not None else None, 'locked': locked, # Needed for Backbone delete/update. 'id': asset_url }
def course_image_url(course): """Returns the image url for the course.""" loc = StaticContent.compute_location(course.location.org, course.location.course, course.course_image) path = StaticContent.get_url_path_from_location(loc) return path
def course_image_url(course): """Returns the image url for the course.""" loc = course.location._replace(tag='c4x', category='asset', name=course.course_image) path = StaticContent.get_url_path_from_location(loc) return path
def verify_content_links(module, base_dir, static_content_store, link, remap_dict=None): if link.startswith('/static/'): # yes, then parse out the name path = link[len('/static/'):] static_pathname = base_dir / path if os.path.exists(static_pathname): try: content_loc = StaticContent.compute_location(module.location.org, module.location.course, path) filename = os.path.basename(path) mime_type = mimetypes.guess_type(filename)[0] with open(static_pathname, 'rb') as f: data = f.read() content = StaticContent(content_loc, filename, mime_type, data, import_path=path) # first let's save a thumbnail so we can get back a thumbnail location (thumbnail_content, thumbnail_location) = static_content_store.generate_thumbnail(content) if thumbnail_content is not None: content.thumbnail_location = thumbnail_location #then commit the content static_content_store.save(content) new_link = StaticContent.get_url_path_from_location(content_loc) if remap_dict is not None: remap_dict[link] = new_link return new_link except Exception, e: logging.exception('Skipping failed content load from {0}. Exception: {1}'.format(path, e))
def asset_index(request, org, course, name): """ Display an editable asset library org, course, name: Attributes of the Location for the item to edit """ location = get_location_and_verify_access(request, org, course, name) upload_asset_callback_url = reverse("upload_asset", kwargs={"org": org, "course": course, "coursename": name}) course_module = modulestore().get_item(location) course_reference = StaticContent.compute_location(org, course, name) assets = contentstore().get_all_content_for_course(course_reference) # sort in reverse upload date order assets = sorted(assets, key=lambda asset: asset["uploadDate"], reverse=True) asset_display = [] for asset in assets: asset_id = asset["_id"] display_info = {} display_info["displayname"] = asset["displayname"] display_info["uploadDate"] = get_default_time_display(asset["uploadDate"].timetuple()) asset_location = StaticContent.compute_location(asset_id["org"], asset_id["course"], asset_id["name"]) display_info["url"] = StaticContent.get_url_path_from_location(asset_location) # note, due to the schema change we may not have a 'thumbnail_location' in the result set _thumbnail_location = asset.get("thumbnail_location", None) thumbnail_location = Location(_thumbnail_location) if _thumbnail_location is not None else None display_info["thumb_url"] = ( StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_location is not None else None ) asset_display.append(display_info) return render_to_response( "asset_index.html", { "active_tab": "assets", "context_course": course_module, "assets": asset_display, "upload_asset_callback_url": upload_asset_callback_url, }, )
def _get_asset_json(display_name, date, location, thumbnail_location, locked): """ Helper method for formatting the asset information to send to client. """ asset_url = StaticContent.get_url_path_from_location(location) external_url = settings.LMS_BASE + asset_url return { 'display_name': display_name, 'date_added': strftime_localized(date, "%m %d, %Y %H:%M"), 'url': asset_url, 'external_url': external_url, 'portable_url': StaticContent.get_static_path_from_location(location), 'thumbnail': StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_location is not None else None, 'locked': locked, # Needed for Backbone delete/update. 'id': asset_url }
def course_image_url(course): """Try to look up the image url for the course. If it's not found, log an error and return the dead link""" if isinstance(modulestore(), XMLModuleStore): return '/static/' + course.data_dir + "/images/course_image.jpg" else: loc = course.location._replace(tag='c4x', category='asset', name='images_course_image.jpg') path = StaticContent.get_url_path_from_location(loc) return path
def course_image_url(course): """Try to look up the image url for the course. If it's not found, log an error and return the dead link""" if isinstance(modulestore(), XMLModuleStore): return '/static/' + course.data_dir + "/images/course_image.jpg" else: loc = course.location._replace(tag='c4x', category='asset', name='images_course_image.jpg') path = StaticContent.get_url_path_from_location(loc) return path
def course_image_url(course): """Try to look up the image url for the course. If it's not found, log an error and return the dead link""" if course.static_asset_path or modulestore().get_modulestore_type(course.location.course_id) == XML_MODULESTORE_TYPE: return '/static/' + (course.static_asset_path or getattr(course, 'data_dir', '')) + "/images/course_image.jpg" else: loc = course.location._replace(tag='c4x', category='asset', name=course.course_image) _path = StaticContent.get_url_path_from_location(loc) return _path
def setUp(self): """ Create user and login. """ settings.MODULESTORE['default']['OPTIONS']['fs_root'] = path('common/test/data') settings.MODULESTORE['direct']['OPTIONS']['fs_root'] = path('common/test/data') self.client = Client() self.contentstore = contentstore() # A locked asset self.loc_locked = Location('c4x', 'edX', 'toy', 'asset', 'sample_static.txt') self.url_locked = StaticContent.get_url_path_from_location(self.loc_locked) # An unlocked asset self.loc_unlocked = Location('c4x', 'edX', 'toy', 'asset', 'another_static.txt') self.url_unlocked = StaticContent.get_url_path_from_location(self.loc_unlocked) import_from_xml(modulestore('direct'), 'common/test/data/', ['toy'], static_content_store=self.contentstore, verbose=True) self.contentstore.set_attr(self.loc_locked, 'locked', True) # Create user self.usr = '******' self.pwd = 'foo' email = '*****@*****.**' self.user = User.objects.create_user(self.usr, email, self.pwd) self.user.is_active = True self.user.save() # Create staff user self.staff_usr = '******' self.staff_pwd = 'foo' staff_email = '*****@*****.**' self.staff_user = User.objects.create_user(self.staff_usr, staff_email, self.staff_pwd) self.staff_user.is_active = True self.staff_user.is_staff = True self.staff_user.save()
def course_image_url(course): """Try to look up the image url for the course. If it's not found, log an error and return the dead link""" if ( course.static_asset_path or modulestore().get_modulestore_type(course.location.course_id) == XML_MODULESTORE_TYPE ): return "/static/" + (course.static_asset_path or getattr(course, "data_dir", "")) + "/images/course_image.jpg" else: loc = StaticContent.compute_location(course.location.org, course.location.course, course.course_image) _path = StaticContent.get_url_path_from_location(loc) return _path
def verify_content_links(module, base_dir, static_content_store, link, remap_dict=None): if link.startswith('/static/'): # yes, then parse out the name path = link[len('/static/'):] static_pathname = base_dir / path if os.path.exists(static_pathname): try: content_loc = StaticContent.compute_location( module.location.org, module.location.course, path) filename = os.path.basename(path) mime_type = mimetypes.guess_type(filename)[0] with open(static_pathname, 'rb') as f: data = f.read() content = StaticContent(content_loc, filename, mime_type, data, import_path=path) # first let's save a thumbnail so we can get back a thumbnail # location (thumbnail_content, thumbnail_location ) = static_content_store.generate_thumbnail(content) if thumbnail_content is not None: content.thumbnail_location = thumbnail_location # then commit the content static_content_store.save(content) new_link = StaticContent.get_url_path_from_location( content_loc) if remap_dict is not None: remap_dict[link] = new_link return new_link except Exception, e: logging.exception( 'Skipping failed content load from {0}. Exception: {1}'. format(path, e))
def course_image_url(course): """Try to look up the image url for the course. If it's not found, log an error and return the dead link""" if course.static_asset_path or modulestore().get_modulestore_type(course.location.course_id) == XML_MODULESTORE_TYPE: # If we are a static course with the course_image attribute # set different than the default, return that path so that # courses can use custom course image paths, otherwise just # return the default static path. url = '/static/' + (course.static_asset_path or getattr(course, 'data_dir', '')) if hasattr(course, 'course_image') and course.course_image != course.fields['course_image'].default: url += '/' + course.course_image else: url += '/images/course_image.jpg' else: loc = StaticContent.compute_location(course.location.org, course.location.course, course.course_image) url = StaticContent.get_url_path_from_location(loc) return url
def course_image_url(course): """Try to look up the image url for the course. If it's not found, log an error and return the dead link""" if course.static_asset_path or modulestore().get_modulestore_type( course.location.course_id) == XML_MODULESTORE_TYPE: return '/static/' + (course.static_asset_path or getattr( course, 'data_dir', '')) + "/images/course_image.jpg" else: loc = course.location.replace(tag='c4x', category='asset', name=course.course_image) _path = StaticContent.get_url_path_from_location(loc) try: f = urllib2.urlopen(urllib2.Request(build_absolute_uri(_path))) return _path except: return '/static/images/columbia_logo.png'
def mobi_course_info(request, course, action=None): course_logo = course_image_url(course) imgurl = course_logo if action in ["homefalls", "all", "hot", "latest", "my", "search"]: try: course_mini_info = course.id.split('/') asset_location = StaticContent.compute_location(course_mini_info[0], course_mini_info[1], 'mobi-logo-img.jpg') imgurl = StaticContent.get_url_path_from_location(asset_location) except: print "=========================fail load mobi image===============================" print "We will load this info to log" return { "id": course.id.replace('/', '.'), "name": course.display_name_with_default, "logo": request.get_host() + course_image_url(course), "org": course.display_org_with_default, "course_number": course.display_number_with_default, "start_date": course.start.strftime("%Y-%m-%d"), "about": get_course_about_section(course, 'short_description'), "category": course.category, "imgurl": request.get_host() + imgurl }
def mobi_course_info(request, course, action=None): course_logo = course_image_url(course) imgurl = course_logo if action in ["homefalls", "all", "hot", "latest", "my", "search"]: try: course_mini_info = course.id.split('/') asset_location = StaticContent.compute_location(course_mini_info[0], course_mini_info[1], 'mobi-logo-img.jpg') imgurl = StaticContent.get_url_path_from_location(asset_location) except: print "=========================fail load mobi image===============================" print "We will load this info to log" return { "id": course.id.replace('/', '.'), "name": course.display_name_with_default, "logo": request.get_host() + course_image_url(course), "org": course.display_org_with_default, "course_number": course.display_number_with_default, "start_date": course.start.strftime("%Y-%m-%d"), "about": get_course_about_section(course, 'short_description'), "category": course.category, "imgurl": request.get_host() + imgurl }
def course_image_url(course): """Returns the image url for the course.""" loc = StaticContent.compute_location( course.location.org, course.location.course, course.course_image) path = StaticContent.get_url_path_from_location(loc) return path
def compute_action_imgurl(imgname): course_mini_info = course.id.split('/') asset_location = StaticContent.compute_location( course_mini_info[0], course_mini_info[1], imgname) return host + StaticContent.get_url_path_from_location(asset_location)
def upload_asset(request, org, course, coursename): ''' cdodge: this method allows for POST uploading of files into the course asset library, which will be supported by GridFS in MongoDB. ''' if request.method != 'POST': # (cdodge) @todo: Is there a way to do a - say - 'raise Http400'? return HttpResponseBadRequest() # construct a location from the passed in path location = get_location_and_verify_access(request, org, course, coursename) # Does the course actually exist?!? Get anything from it to prove its existance try: modulestore().get_item(location) except: # no return it as a Bad Request response logging.error('Could not find course' + location) return HttpResponseBadRequest() if 'file' not in request.FILES: return HttpResponseBadRequest() # compute a 'filename' which is similar to the location formatting, we're using the 'filename' # nomenclature since we're using a FileSystem paradigm here. We're just imposing # the Location string formatting expectations to keep things a bit more consistent filename = request.FILES['file'].name mime_type = request.FILES['file'].content_type filedata = request.FILES['file'].read() content_loc = StaticContent.compute_location(org, course, filename) content = StaticContent(content_loc, filename, mime_type, filedata) # first let's see if a thumbnail can be created (thumbnail_content, thumbnail_location) = contentstore().generate_thumbnail(content) # delete cached thumbnail even if one couldn't be created this time (else the old thumbnail will continue to show) del_cached_content(thumbnail_location) # now store thumbnail location only if we could create it if thumbnail_content is not None: content.thumbnail_location = thumbnail_location # then commit the content contentstore().save(content) del_cached_content(content.location) # readback the saved content - we need the database timestamp readback = contentstore().find(content.location) response_payload = { 'displayname': content.name, 'uploadDate': get_default_time_display(readback.last_modified_at), 'url': StaticContent.get_url_path_from_location(content.location), 'thumb_url': StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_content is not None else None, 'msg': 'Upload completed' } response = HttpResponse(json.dumps(response_payload)) response['asset_url'] = StaticContent.get_url_path_from_location( content.location) return response
def upload_asset(request, org, course, coursename): ''' This method allows for POST uploading of files into the course asset library, which will be supported by GridFS in MongoDB. ''' # construct a location from the passed in path location = get_location_and_verify_access(request, org, course, coursename) # Does the course actually exist?!? Get anything from it to prove its # existence try: modulestore().get_item(location) except: # no return it as a Bad Request response logging.error('Could not find course' + location) return HttpResponseBadRequest() if 'files[]' not in request.FILES: return HttpResponseBadRequest() # compute a 'filename' which is similar to the location formatting, we're # using the 'filename' nomenclature since we're using a FileSystem paradigm # here. We're just imposing the Location string formatting expectations to # keep things a bit more consistent upload_file = request.FILES['files[]'] filename = upload_file.name mime_type = upload_file.content_type content_loc = StaticContent.compute_location(org, course, filename) chunked = upload_file.multiple_chunks() sc_partial = partial(StaticContent, content_loc, filename, mime_type) if chunked: content = sc_partial(upload_file.chunks()) tempfile_path = upload_file.temporary_file_path() else: content = sc_partial(upload_file.read()) tempfile_path = None thumbnail_content = None thumbnail_location = None # first let's see if a thumbnail can be created (thumbnail_content, thumbnail_location) = contentstore().generate_thumbnail( content, tempfile_path=tempfile_path ) # delete cached thumbnail even if one couldn't be created this time (else # the old thumbnail will continue to show) del_cached_content(thumbnail_location) # now store thumbnail location only if we could create it if thumbnail_content is not None: content.thumbnail_location = thumbnail_location # then commit the content contentstore().save(content) del_cached_content(content.location) # readback the saved content - we need the database timestamp readback = contentstore().find(content.location) response_payload = { 'displayname': content.name, 'uploadDate': get_default_time_display(readback.last_modified_at), 'url': StaticContent.get_url_path_from_location(content.location), 'portable_url': StaticContent.get_static_path_from_location(content.location), 'thumb_url': StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_content is not None else None, 'msg': 'Upload completed' } response = JsonResponse(response_payload) return response
def upload_asset(request, org, course, coursename): """ cdodge: this method allows for POST uploading of files into the course asset library, which will be supported by GridFS in MongoDB. """ if request.method != "POST": # (cdodge) @todo: Is there a way to do a - say - 'raise Http400'? return HttpResponseBadRequest() # construct a location from the passed in path location = get_location_and_verify_access(request, org, course, coursename) # Does the course actually exist?!? Get anything from it to prove its existance try: modulestore().get_item(location) except: # no return it as a Bad Request response logging.error("Could not find course" + location) return HttpResponseBadRequest() # compute a 'filename' which is similar to the location formatting, we're using the 'filename' # nomenclature since we're using a FileSystem paradigm here. We're just imposing # the Location string formatting expectations to keep things a bit more consistent filename = request.FILES["file"].name mime_type = request.FILES["file"].content_type filedata = request.FILES["file"].read() content_loc = StaticContent.compute_location(org, course, filename) content = StaticContent(content_loc, filename, mime_type, filedata) # first let's see if a thumbnail can be created (thumbnail_content, thumbnail_location) = contentstore().generate_thumbnail(content) # delete cached thumbnail even if one couldn't be created this time (else the old thumbnail will continue to show) del_cached_content(thumbnail_location) # now store thumbnail location only if we could create it if thumbnail_content is not None: content.thumbnail_location = thumbnail_location # then commit the content contentstore().save(content) del_cached_content(content.location) # readback the saved content - we need the database timestamp readback = contentstore().find(content.location) response_payload = { "displayname": content.name, "uploadDate": get_default_time_display(readback.last_modified_at.timetuple()), "url": StaticContent.get_url_path_from_location(content.location), "thumb_url": StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_content is not None else None, "msg": "Upload completed", } response = HttpResponse(json.dumps(response_payload)) response["asset_url"] = StaticContent.get_url_path_from_location(content.location) return response
def course_image_url(course): """Returns the image url for the course.""" loc = course.location._replace(tag='c4x', category='asset', name=course.course_image) path = StaticContent.get_url_path_from_location(loc) return path
def compute_action_imgurl(imgname): course_mini_info = course.id.split('/') asset_location = StaticContent.compute_location(course_mini_info[0], course_mini_info[1], imgname) return host + StaticContent.get_url_path_from_location(asset_location)
def upload_asset(request, org, course, coursename): ''' This method allows for POST uploading of files into the course asset library, which will be supported by GridFS in MongoDB. ''' # construct a location from the passed in path location = get_location_and_verify_access(request, org, course, coursename) # Does the course actually exist?!? Get anything from it to prove its # existence try: modulestore().get_item(location) except: # no return it as a Bad Request response logging.error('Could not find course' + location) return HttpResponseBadRequest() if 'file' not in request.FILES: return HttpResponseBadRequest() # compute a 'filename' which is similar to the location formatting, we're # using the 'filename' nomenclature since we're using a FileSystem paradigm # here. We're just imposing the Location string formatting expectations to # keep things a bit more consistent upload_file = request.FILES['file'] filename = upload_file.name mime_type = upload_file.content_type content_loc = StaticContent.compute_location(org, course, filename) chunked = upload_file.multiple_chunks() sc_partial = partial(StaticContent, content_loc, filename, mime_type) if chunked: content = sc_partial(upload_file.chunks()) tempfile_path = upload_file.temporary_file_path() else: content = sc_partial(upload_file.read()) tempfile_path = None thumbnail_content = None thumbnail_location = None # first let's see if a thumbnail can be created (thumbnail_content, thumbnail_location) = contentstore().generate_thumbnail( content, tempfile_path=tempfile_path ) # delete cached thumbnail even if one couldn't be created this time (else # the old thumbnail will continue to show) del_cached_content(thumbnail_location) # now store thumbnail location only if we could create it if thumbnail_content is not None: content.thumbnail_location = thumbnail_location # then commit the content contentstore().save(content) del_cached_content(content.location) # readback the saved content - we need the database timestamp readback = contentstore().find(content.location) response_payload = { 'displayname': content.name, 'uploadDate': get_default_time_display(readback.last_modified_at), 'url': StaticContent.get_url_path_from_location(content.location), 'portable_url': StaticContent.get_static_path_from_location(content.location), 'thumb_url': StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_content is not None else None, 'msg': 'Upload completed' } response = JsonResponse(response_payload) return response