Skip to content

Commit af5ed85

Browse files
authored
Merge pull request #14 from relic-se/zipfile-upgrade
Improved zipfile extraction
2 parents 23211e6 + 0068454 commit af5ed85

File tree

4 files changed

+1894
-506
lines changed

4 files changed

+1894
-506
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.vscode
22
dist
33
.DS_Store
4+
__pycache__

code.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,16 @@
4646
pass
4747

4848
# program constants
49+
4950
APPLICATIONS_URL = "https://raw.githubusercontent.com/relic-se/Fruit_Jam_Library/refs/heads/main/database/applications.json"
5051
METADATA_URL = "https://raw.githubusercontent.com/{:s}/refs/heads/main/metadata.json"
5152
REPO_URL = "https://api.github.com/repos/{:s}"
5253
ICON_URL = "https://raw.githubusercontent.com/{:s}/{:s}/{:s}"
5354
RELEASE_URL = "https://api.github.com/repos/{:s}/releases/latest"
5455

56+
MAJOR_VERSION = int(os.uname().release.split(".")[0])
57+
VERSION_NAME = "CircuitPython {:d}.x".format(MAJOR_VERSION)
58+
5559
# file operations
5660

5761
def exists(path: str) -> bool:
@@ -82,12 +86,13 @@ def rmtree(dirpath: str) -> None:
8286
os.rmdir(dirpath)
8387

8488
def extractall(zf: ZipFile, destination: str, source: str = "") -> None:
85-
for srcpath in zf:
86-
if srcpath.startswith(source + "/"):
87-
destpath = destination + "/" + srcpath[len(source) + 1:]
89+
for srcinfo in zf.infolist():
90+
if not srcinfo.filename.endswith("/") and srcinfo.filename.startswith(source + "/"):
91+
destpath = destination + "/" + srcinfo.filename[len(source) + 1:]
8892
mkdir(destpath, True)
89-
with open(destpath, "wb") as f:
90-
f.write(zf.read(zf[srcpath]))
93+
with open(destpath, "wb") as destfile:
94+
with zf.open(srcinfo.filename) as srcfile:
95+
destfile.write(srcfile.read())
9196

9297
def is_app_installed(name: str) -> bool:
9398
return exists("/sd/apps/{:s}".format(name))
@@ -730,33 +735,36 @@ def download_application(full_name: str = None) -> bool:
730735
log("Installing application...")
731736
result = False
732737
try:
733-
with open(zip_path, "rb") as f:
734-
zf = ZipFile(f)
738+
with ZipFile(zip_path, "r") as zf:
735739

736740
# determine correct inner path based on CP version
737-
major_version = int(os.uname().release.split(".")[0])
738-
version_name = "CircuitPython {:d}.x".format(major_version)
739-
for dirpath in (repo_name + "/" + version_name, version_name, repo_name, ""):
740-
try:
741-
zf[(dirpath + "/code.py").strip("/")]
742-
except KeyError:
743-
pass
744-
else:
745-
break
741+
for dirpath in (repo_name + "/" + VERSION_NAME, VERSION_NAME, repo_name, "", None):
742+
if dirpath is not None:
743+
try:
744+
zf.getinfo((dirpath + "/code.py").strip("/"))
745+
except KeyError:
746+
pass
747+
else:
748+
break
749+
750+
if dirpath is None:
751+
# try searching for code.py
752+
for info in zf.infolist():
753+
if info.filename.split("/")[-1] == "code.py":
754+
dirpath = info.filename[:-len("code.py")].strip("/")
755+
break
746756

747757
# make sure we found code.py
748-
try:
749-
zf[(dirpath + "/code.py").strip("/")]
750-
except KeyError:
758+
if dirpath is None:
751759
log("Could not locate application files within release!")
752760
else:
753761
# extract files
754762
extractall(zf, path, dirpath)
755763
log("Successfully installed {:s}!".format(full_name))
756764
result = True
765+
757766
except BadZipFile as e:
758767
log("Unable to extract and install application! {:s}".format(str(e)))
759-
return False
760768

761769
# remove zip file
762770
os.remove(zip_path)

0 commit comments

Comments
 (0)