Django сохраняет заархивированные каталоги как файлы или что здесь может происходить? - PullRequest
1 голос
/ 03 августа 2020

Я работаю с OpenEdX, у него есть система плагинов под названием XBlocks, которая в этом случае позволяет импортировать контент, созданный сторонними «студийными приложениями». Этот контент можно загрузить в виде zip-файла. затем он обрабатывается следующим кодом:

@XBlock.handler

    def studio_submit(self, request, _suffix):

        self.display_name = request.params["display_name"]

        self.width = request.params["width"]

        self.height = request.params["height"]

        self.has_score = request.params["has_score"]

        self.weight = request.params["weight"]

        self.icon_class = "problem" if self.has_score == "True" else "video"



        response = {"result": "success", "errors": []}

        if not hasattr(request.params["file"], "file"):

            # File not uploaded

            return self.json_response(response)



        package_file = request.params["file"].file

        self.update_package_meta(package_file)



        # First, save scorm file in the storage for mobile clients

        if default_storage.exists(self.package_path):

            logger.info('Removing previously uploaded "%s"', self.package_path)

            default_storage.delete(self.package_path)

        default_storage.save(self.package_path, File(package_file))

        logger.info('Scorm "%s" file stored at "%s"', package_file, self.package_path)



        # Then, extract zip file

        if default_storage.exists(self.extract_folder_base_path):

            logger.info(

                'Removing previously unzipped "%s"', self.extract_folder_base_path

            )

            recursive_delete(self.extract_folder_base_path)

        with zipfile.ZipFile(package_file, "r") as scorm_zipfile:

            for zipinfo in scorm_zipfile.infolist():

                default_storage.save(

                    os.path.join(self.extract_folder_path, zipinfo.filename),

                    scorm_zipfile.open(zipinfo.filename),

                )



        try:

            self.update_package_fields()

        except ScormError as e:

            response["errors"].append(e.args[0])



        return self.json_response(response)

, где код

                default_storage.save(

                    os.path.join(self.extract_folder_path, zipinfo.filename),

                    scorm_zipfile.open(zipinfo.filename),

                )

является источником следующей (Django) трассировки ошибки:

cms_1             |   File "/openedx/venv/lib/python3.5/site-packages/openedxscorm/scormxblock.py", line 193, in studio_submit
cms_1             |     scorm_zipfile.open(zipinfo.filename),
cms_1             |   File "/openedx/venv/lib/python3.5/site-packages/django/core/files/storage.py", line 52, in save
cms_1             |     return self._save(name, content)
cms_1             |   File "/openedx/venv/lib/python3.5/site-packages/django/core/files/storage.py", line 249, in _save
cms_1             |     raise IOError("%s exists and is not a directory." % directory)
cms_1             | OSError: /openedx/media/scorm/c154229b568d45128e1098b530267a35/a346b1db27aaa89b89b31e1c3e2a1af04482abad/assets exists and is not a directory.

Я тоже разместил проблему на github

исключение FileExistsError Возникает при попытке создать файл или каталог, который уже существует. Соответствует errno EEXIST.

Я действительно не понимаю, что происходит. Он основан на комке размером javascript в многослойных docker контейнерах, поэтому я не могу легко взломать и распечатать дополнительную информацию.

Единственное, что я обнаружил, это то, что некоторые папки в zip-файле написаны в том docker в виде файлов, а не каталогов в момент возникновения ошибки. Однако этого можно ожидать, и эти файлы могут быть переписаны или изменены в каталоги позже (?) На Linux (?).

Ошибка отображает папку assets

root@93f0d2b9667f:/openedx/media/scorm/5e085cbc04e24b3b911802f7cba44296/92b12100be7651c812a1d29a041153db5ba89239# ls -la
total 84
drwxr-xr-x 2 root root  4096 Aug  2 22:17 .
drwxr-xr-x 3 root root  4096 Aug  2 22:17 ..
-rw-r--r-- 1 root root  4398 Aug  2 22:17 adlcp_rootv1p2.xsd
-rw-r--r-- 1 root root     0 Aug  2 22:17 assets
-rw-r--r-- 1 root root     0 Aug  2 22:17 course
-rw-r--r-- 1 root root 14560 Aug  2 22:17 imscp_rootv1p1p2.xsd
-rw-r--r-- 1 root root  1847 Aug  2 22:17 imsmanifest.xml
-rw-r--r-- 1 root root 22196 Aug  2 22:17 imsmd_rootv1p2p1.xsd
-rw-r--r-- 1 root root  1213 Aug  2 22:17 ims_xml.xsd
-rw-r--r-- 1 root root  1662 Aug  2 22:17 index.html
-rw-r--r-- 1 root root     0 Aug  2 22:17 libraries
-rw-r--r-- 1 root root  1127 Aug  2 22:17 log_output.html
-rw-r--r-- 1 root root   481 Aug  2 22:17 main.html
-rw-r--r-- 1 root root   759 Aug  2 22:17 offline_API_wrapper.js
-rw-r--r-- 1 root root     0 Aug  2 22:17 player
-rw-r--r-- 1 root root  1032 Aug  2 22:17 popup.html
root@93f0d2b9667f:/openedx/media/scorm/5e085cbc04e24b3b911802f7cba44296/92b12100be7651c812a1d29a041153db5ba89239# cd assets
bash: cd: assets: Not a directory
...