Change file timestamps if necessary because ZIP does not support timestamps before 1980. Fixes #1360.

This commit is contained in:
grossmj 2018-08-25 18:10:40 +07:00
parent 814526ba26
commit 38b72079b2
3 changed files with 24 additions and 3 deletions

View File

@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
import json
import asyncio
import aiohttp
@ -23,6 +24,7 @@ import zipfile
import tempfile
import zipstream
from datetime import datetime
import logging
log = logging.getLogger(__name__)
@ -77,6 +79,7 @@ def export_project(project, temporary_dir, include_images=False, keep_compute_id
# ignore the .gns3 file
if file.endswith(".gns3"):
continue
_patch_mtime(path)
zstream.write(path, os.path.relpath(path, project._path), compress_type=zipfile.ZIP_DEFLATED)
# Export files from remote computes
@ -99,12 +102,29 @@ def export_project(project, temporary_dir, include_images=False, keep_compute_id
f.write(data)
response.close()
f.close()
_patch_mtime(temp_path)
zstream.write(temp_path, arcname=compute_file["path"], compress_type=zipfile.ZIP_DEFLATED)
downloaded_files.add(compute_file['path'])
return zstream
def _patch_mtime(path):
"""
Patch the file mtime because ZIP does not support timestamps before 1980
:param path: file path
"""
if sys.platform.startswith("win"):
# only UNIX type platforms
return
st = os.stat(path)
file_date = datetime.fromtimestamp(st.st_mtime)
if file_date.year < 1980:
new_mtime = file_date.replace(year=1980).timestamp()
os.utime(path, (st.st_atime, new_mtime))
def _is_exportable(path):
"""
:returns: True if file should not be included in the final archive
@ -228,6 +248,7 @@ def _export_local_image(image, zstream):
if os.path.exists(path):
arcname = os.path.join("images", directory, os.path.basename(image))
_patch_mtime(path)
zstream.write(path, arcname)
return

View File

@ -101,7 +101,7 @@ class Snapshot:
with tempfile.TemporaryDirectory() as tmpdir:
zipstream = yield from export_project(self._project, tmpdir, keep_compute_id=True, allow_all_nodes=True)
yield from wait_run_in_executor(self._create_snapshot_file, zipstream)
except OSError as e:
except (ValueError, OSError, RuntimeError) as e:
raise aiohttp.web.HTTPConflict(text="Could not create snapshot file '{}': {}".format(self.path, e))
@asyncio.coroutine

View File

@ -304,8 +304,8 @@ class ProjectHandler:
yield from response.write_eof()
# Will be raise if you have no space left or permission issue on your temporary directory
# RuntimeError: something was wrong during the zip process
except (OSError, RuntimeError) as e:
raise aiohttp.web.HTTPNotFound(text="Can't export project: {}".format(str(e)))
except (ValueError, OSError, RuntimeError) as e:
raise aiohttp.web.HTTPNotFound(text="Cannot export project: {}".format(str(e)))
@Route.post(
r"/projects/{project_id}/import",