def collect_assets_from_text(text, course_id, include_content=False):
    """
    Yield dicts of asset content and path from static asset paths found in the given text.
    Make sure to have replaced the URLs with rewrite_absolute_static_urls first.
    If include_content is True, the result will include a contentstore
    StaticContent file object which wraps the actual binary content of the file.
    """
    # Replace static urls like '/static/foo.png'
    static_paths = []
    # Drag-and-drop-v2 has
    #     "/static/blah.png"
    # which must be changed to "/static/blah.png" for replace_static_urls to work:
    text2 = text.replace(""", '"')
    replace_static_urls(text=text2,
                        course_id=course_id,
                        static_paths_out=static_paths)
    for (path, uri) in static_paths:
        if path.startswith('/static/'):
            path = path[8:]
        info = {
            'path': path,
            'url': '/' + str(course_id.make_asset_key("asset", path)),
        }
        if include_content:
            content = get_asset_content_from_path(course_id, path)
            if content is None:
                log.error("Static asset not found: (%s, %s)", path, uri)
            else:
                info['content'] = content
        yield info
Пример #2
0
def test_multi_replace():
    course_source = '"/course/file.png"'

    assert replace_static_urls(STATIC_SOURCE, DATA_DIRECTORY) == \
        replace_static_urls(replace_static_urls(STATIC_SOURCE, DATA_DIRECTORY), DATA_DIRECTORY)
    assert replace_course_urls(course_source, COURSE_KEY) == \
        replace_course_urls(replace_course_urls(course_source, COURSE_KEY), COURSE_KEY)
Пример #3
0
    def replace_urls(self, text, static_replace_only=False):
        """
        Replaces all static/course/jump-to-id URLs in provided text/html.

        Args:
            text: String containing the URL to be replaced
            static_replace_only: If True, only static urls will be replaced
        """
        if self.lookup_asset_url:
            text = replace_static_urls(text,
                                       xblock=self.xblock(),
                                       lookup_asset_url=self.lookup_asset_url)
        else:
            text = replace_static_urls(
                text,
                data_directory=self.data_directory,
                course_id=self.course_id,
                static_asset_path=self.static_asset_path,
                static_paths_out=self.static_paths_out)
            if not static_replace_only:
                text = replace_course_urls(text, self.course_id)
                if self.jump_to_id_base_url:
                    text = replace_jump_to_id_urls(text, self.course_id,
                                                   self.jump_to_id_base_url)

        return text
Пример #4
0
def test_raw_static_check():
    """
    Make sure replace_static_urls leaves alone things that end in '.raw'
    """
    path = '"/static/foo.png?raw"'
    assert replace_static_urls(path, DATA_DIRECTORY) == path

    text = 'text <tag a="/static/js/capa/protex/protex.nocache.js?raw"/><div class="'
    assert replace_static_urls(path, text) == path
Пример #5
0
def test_data_dir_fallback(mock_storage, mock_modulestore, mock_settings):  # lint-amnesty, pylint: disable=unused-argument
    mock_modulestore.return_value = Mock(XMLModuleStore)
    mock_storage.url.side_effect = Exception

    mock_storage.exists.return_value = True
    assert replace_static_urls(STATIC_SOURCE,
                               DATA_DIRECTORY) == '"/static/data_dir/file.png"'

    mock_storage.exists.return_value = False
    assert replace_static_urls(STATIC_SOURCE,
                               DATA_DIRECTORY) == '"/static/data_dir/file.png"'
Пример #6
0
def test_static_paths_out(mock_modulestore, mock_storage):
    """
    Tests the side-effect of passing an array to collect static_paths_out.

    * if a static URL is changed, then its changed URL is returned.
    * if a static URL is unchanged, then the unchanged URL is returned.
    * xblock paths are not included in the static_paths_out array.
    """
    mock_storage.exists.return_value = False
    mock_modulestore.return_value = Mock(MongoModuleStore)

    static_url = '/static/LAlec04_controller.swf?csConfigFile=/static/LAlec04_config.xml&name1=value1&name2=value2'
    static_course_url = '/c4x/org/course/asset/LAlec04_controller.swf?csConfigFile=%2Fc4x%2Forg%2Fcourse%2Fasset%2FLAlec04_config.xml&name1=value1&name2=value2'  # lint-amnesty, pylint: disable=line-too-long
    raw_url = '/static/js/capa/protex/protex.nocache.js?raw'
    xblock_url = '/static/xblock/resources/babys_first.lil_xblock/public/images/pacifier.png'
    # xss-lint: disable=python-wrap-html
    pre_text = f'EMBED src ="{static_url}" xblock={xblock_url} text <tag a="{raw_url}"/><div class="'
    # xss-lint: disable=python-wrap-html
    post_text = f'EMBED src ="{static_course_url}" xblock={xblock_url} text <tag a="{raw_url}"/><div class="'  # lint-amnesty, pylint: disable=line-too-long
    static_paths = []
    assert replace_static_urls(pre_text,
                               DATA_DIRECTORY,
                               COURSE_KEY,
                               static_paths_out=static_paths) == post_text
    assert static_paths == [(static_url, static_course_url),
                            (raw_url, raw_url)]
Пример #7
0
def get_course_syllabus_section(course, section_key):
    """
    This returns the snippet of html to be rendered on the syllabus page,
    given the key for the section.

    Valid keys:
    - syllabus
    - guest_syllabus
    """

    # Many of these are stored as html files instead of some semantic
    # markup. This can change without effecting this interface when we find a
    # good format for defining so many snippets of text/html.

    if section_key in ['syllabus', 'guest_syllabus']:
        try:
            filesys = course.system.resources_fs
            # first look for a run-specific version
            dirs = [path("syllabus") / course.url_name, path("syllabus")]
            filepath = find_file(filesys, dirs, section_key + ".html")
            with filesys.open(filepath) as html_file:
                return replace_static_urls(
                    html_file.read().decode('utf-8'),
                    getattr(course, 'data_dir', None),
                    course_id=course.id,
                    static_asset_path=course.static_asset_path,
                )
        except ResourceNotFound:
            log.exception("Missing syllabus section %s in course %s",
                          section_key, str(course.location))
            return "! Syllabus missing !"

    raise KeyError("Invalid about key " + str(section_key))
Пример #8
0
    def test_relative_url_for_split_course(self):
        """
        Test relative path for split courses assets
        """
        with modulestore().default_store(ModuleStoreEnum.Type.split):
            module_store = modulestore()
            course_id = module_store.make_course_key('edX', 'toy', '2012_Fall')
            import_course_from_xml(module_store,
                                   self.user.id,
                                   TEST_DATA_DIR, ['toy'],
                                   static_content_store=contentstore(),
                                   target_id=course_id,
                                   create_if_not_present=True)
            course = module_store.get_course(course_id)

            filename = 'sample_static.html'
            html_src_attribute = '"/static/{}"'.format(filename)
            asset_url = replace_static_urls(html_src_attribute,
                                            course_id=course.id)
            url = asset_url.replace('"', '')
            base_url = url.replace(filename, '')

            self.assertIn("/{}".format(filename), url)
            resp = self.client.get(url)
            self.assertEqual(resp.status_code, 200)

            # simulation of html page where base_url is up-to asset's main directory
            # and relative_path is dom element with its src
            relative_path = 'just_a_test.jpg'
            # browser append relative_path with base_url
            absolute_path = base_url + relative_path

            self.assertIn("/{}".format(relative_path), absolute_path)
            resp = self.client.get(absolute_path)
            self.assertEqual(resp.status_code, 200)
Пример #9
0
def test_storage_url_exists(mock_storage):
    mock_storage.exists.return_value = True
    mock_storage.url.return_value = '/static/file.png'

    assert replace_static_urls(STATIC_SOURCE,
                               DATA_DIRECTORY) == '"/static/file.png"'
    mock_storage.exists.assert_called_once_with('file.png')
    mock_storage.url.assert_called_once_with('file.png')
Пример #10
0
def test_mongo_filestore(mock_get_excluded_extensions, mock_get_base_url,
                         mock_modulestore, mock_static_content):

    mock_modulestore.return_value = Mock(MongoModuleStore)
    mock_static_content.get_canonicalized_asset_path.return_value = "c4x://mock_url"
    mock_get_base_url.return_value = ''
    mock_get_excluded_extensions.return_value = ['foobar']

    # No namespace => no change to path
    assert replace_static_urls(STATIC_SOURCE,
                               DATA_DIRECTORY) == '"/static/data_dir/file.png"'

    # Namespace => content url
    assert '"' + mock_static_content.get_canonicalized_asset_path.return_value + '"' == \
        replace_static_urls(STATIC_SOURCE, DATA_DIRECTORY, course_id=COURSE_KEY)

    mock_static_content.get_canonicalized_asset_path.assert_called_once_with(
        COURSE_KEY, 'file.png', '', ['foobar'])
Пример #11
0
def remap_static_url(original_url, course):
    """Remap a URL in the ways the course requires."""
    # Ick: this should be possible without having to quote and unquote the URL...
    input_url = "'" + original_url + "'"
    output_url = replace_static_urls(
        input_url,
        getattr(course, 'data_dir', None),
        course_id=course.id,
        static_asset_path=course.static_asset_path)
    # strip off the quotes again...
    return output_url[1:-1]
Пример #12
0
def test_static_url_with_xblock_resource(mock_modulestore, mock_storage):
    """
    Make sure that for URLs with XBlock resource URL, which start with /static/,
    we don't rewrite them.
    """
    mock_storage.exists.return_value = False
    mock_modulestore.return_value = Mock(MongoModuleStore)

    pre_text = 'EMBED src ="/static/xblock/resources/babys_first.lil_xblock/public/images/pacifier.png"'
    post_text = pre_text
    assert replace_static_urls(pre_text, DATA_DIRECTORY,
                               COURSE_KEY) == post_text
def replace_static_urls(data_dir, block, view, frag, context, course_id=None, static_asset_path=''):  # pylint: disable=unused-argument
    """
    Updates the supplied module with a new get_html function that wraps
    the old get_html function and substitutes urls of the form /static/...
    with urls that are /static/<prefix>/...
    """
    return wrap_fragment(frag, static_replace.replace_static_urls(
        frag.content,
        data_dir,
        course_id,
        static_asset_path=static_asset_path
    ))
Пример #14
0
def test_static_url_with_query(mock_modulestore, mock_storage):
    """
    Make sure that for urls with query params:
     query params that contain "^/static/" are converted to full location urls
     query params that do not contain "^/static/" are left unchanged
    """
    mock_storage.exists.return_value = False
    mock_modulestore.return_value = Mock(MongoModuleStore)

    pre_text = 'EMBED src ="/static/LAlec04_controller.swf?csConfigFile=/static/LAlec04_config.xml&name1=value1&name2=value2"'  # lint-amnesty, pylint: disable=line-too-long
    post_text = 'EMBED src ="/c4x/org/course/asset/LAlec04_controller.swf?csConfigFile=%2Fc4x%2Forg%2Fcourse%2Fasset%2FLAlec04_config.xml&name1=value1&name2=value2"'  # lint-amnesty, pylint: disable=line-too-long
    assert replace_static_urls(pre_text, DATA_DIRECTORY,
                               COURSE_KEY) == post_text
Пример #15
0
def test_static_url_with_xblock_resource_on_cdn(mock_modulestore,
                                                mock_storage):
    """
    Make sure that for URLs with XBlock resource URL, which start with /static/,
    we don't rewrite them, even if these are served from an absolute URL like a CDN.
    """
    mock_storage.exists.return_value = False
    mock_modulestore.return_value = Mock(MongoModuleStore)

    pre_text = 'EMBED src ="https://example.com/static/xblock/resources/tehehe.xblock/public/images/woo.png"'
    post_text = pre_text
    assert replace_static_urls(pre_text, DATA_DIRECTORY,
                               COURSE_KEY) == post_text
Пример #16
0
 def _expand_static_url(self, url):
     """
     This is required to make URLs like '/static/dnd-test-image.png' work (note: that is the
     only portable URL format for static files that works across export/import and reruns).
     This method is unfortunately a bit hackish since XBlock does not provide a low-level API
     for this.
     """
     if hasattr(self.runtime, 'replace_urls'):
         url = self.runtime.replace_urls(u'"{}"'.format(url))[1:-1]
     elif hasattr(self.runtime, 'course_id'):
         # edX Studio uses a different runtime for 'studio_view' than 'student_view',
         # and the 'studio_view' runtime doesn't provide the replace_urls API.
         try:
             from common.djangoapps.static_replace import replace_static_urls  # pylint: disable=import-error
             url = replace_static_urls(
                 u'"{}"'.format(url),
                 None,
                 course_id=self.runtime.course_id)[1:-1]
         except ImportError:
             pass
     return url
Пример #17
0
 def test_replace_urls(self):
     html = '<a href="/static/id">'
     assert self.runtime.replace_urls(html) == \
         static_replace.replace_static_urls(html, course_id=self.runtime.course_id)