|
11 | 11 | from .utils import is_win |
12 | 12 | from .utils import get_7za_bin |
13 | 13 | from .utils import generate_temp_filename |
| 14 | +from .utils import generate_temp_path |
14 | 15 |
|
15 | 16 |
|
16 | 17 | class Archiver: |
@@ -48,6 +49,23 @@ def _safe_move(self, source, destination): |
48 | 49 | if os.path.exists(source): |
49 | 50 | shutil.move(source, destination) |
50 | 51 |
|
| 52 | + # shutil.copytree fails if dst exists |
| 53 | + def _copy_tree(self, src, dst, symlinks=False, ignore=None): |
| 54 | + logger.info("Copy %s to %s" % (src, dst)) |
| 55 | + if not os.path.exists(dst): |
| 56 | + os.makedirs(dst) |
| 57 | + for item in os.listdir(src): |
| 58 | + s = os.path.join(src, item) |
| 59 | + d = os.path.join(dst, item) |
| 60 | + if os.path.isdir(s): |
| 61 | + self._copy_tree(s, d, symlinks, ignore) |
| 62 | + else: |
| 63 | + if not os.path.exists(d) or os.stat(src).st_mtime - os.stat(dst).st_mtime > 1: |
| 64 | + try: |
| 65 | + shutil.copy2(s, d) |
| 66 | + except (Error) as why: |
| 67 | + logger.error('shutil.copy2 - %s' % why) |
| 68 | + |
51 | 69 | def _get_7za_executable(self): |
52 | 70 | """ |
53 | 71 | Returns absolute 7za executable path |
@@ -221,9 +239,15 @@ def unpack_packages(self, input_file, output_dir=None, password=None): |
221 | 239 | """ |
222 | 240 | if output_dir is None: |
223 | 241 | output_dir = self._get_output_dir() |
224 | | - logger.info('Extract in %s directory' % output_dir) |
| 242 | + temp_dir = generate_temp_path() |
| 243 | + logger.info('Extract in %s directory' % temp_dir) |
225 | 244 | self._run_executable( |
226 | 245 | 'x', |
227 | 246 | password=password, |
228 | 247 | input_file=input_file, |
229 | | - output_dir=output_dir) |
| 248 | + output_dir=temp_dir) |
| 249 | + logger.info('Copy from %s to %s' % (temp_dir, output_dir)) |
| 250 | + self._copy_tree(temp_dir, output_dir) |
| 251 | + logger.info('Remove %s' % temp_dir) |
| 252 | + self._safe_rmtree(temp_dir) |
| 253 | + |
0 commit comments