|
7 | 7 | import shutil |
8 | 8 | import subprocess |
9 | 9 | import sys |
| 10 | +import tempfile |
10 | 11 | import uuid |
11 | 12 | import zipfile |
12 | 13 |
|
@@ -503,10 +504,36 @@ def new_app(): |
503 | 504 | if source.endswith(".zip"): # install from the web (zip file) |
504 | 505 | res = requests.get(source) |
505 | 506 | mem_zip = io.BytesIO(res.content) |
506 | | - zfile = zipfile.ZipFile(mem_zip, "r") |
507 | | - zfile.extractall(target_dir) |
508 | | - zfile.close() |
509 | | - elif source.endswith(".git"): # clone from a git repo |
| 507 | + with zipfile.ZipFile(mem_zip, "r") as zfile: |
| 508 | + allfiles = zfile.infolist() |
| 509 | + if "__init__.py" in allfiles: |
| 510 | + # the app is at top level |
| 511 | + zfile.extractall(target_dir) |
| 512 | + zfile.close() |
| 513 | + else: |
| 514 | + # check for subfolders that contain __init__.py |
| 515 | + roots = list( |
| 516 | + set( |
| 517 | + path[:-12] |
| 518 | + for path in allfiles |
| 519 | + if path.count("/") == 1 |
| 520 | + and path.endswith("/__init__.py") |
| 521 | + ) |
| 522 | + ) |
| 523 | + # there can be only one |
| 524 | + if len(roots) != 1: |
| 525 | + abort(500) |
| 526 | + # extract only the subfolder |
| 527 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 528 | + zfile.extractall(tmpdir) |
| 529 | + zfile.close() |
| 530 | + shutil.copytree( |
| 531 | + os.path.join(tmpdir, roots[0]), |
| 532 | + target_dir, |
| 533 | + dirs_exist_ok=True, |
| 534 | + ) |
| 535 | + elif source.endswith(".git"): |
| 536 | + # clone from a git repo |
510 | 537 | process = subprocess.Popen( |
511 | 538 | ["git", "clone", source, form["name"]], cwd=FOLDER |
512 | 539 | ) |
|
0 commit comments