Skip to content

Commit 563d87d

Browse files
authored
Add fix for bad zip file and logging for build (devicons#1069)
1 parent 917a71a commit 563d87d

File tree

9 files changed

+154
-96
lines changed

9 files changed

+154
-96
lines changed

.github/scripts/build_assets/api_handler.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
import sys
33
import re
44
from typing import List
5+
from io import FileIO
56

67

78
# our base url which leads to devicon
89
base_url = "https://api.github.com/repos/devicons/devicon/"
910

10-
def get_merged_pull_reqs_since_last_release(token):
11+
def get_merged_pull_reqs_since_last_release(token, log_output: FileIO=sys.stdout):
1112
"""
1213
Get all the merged pull requests since the last release.
1314
"""
@@ -16,9 +17,8 @@ def get_merged_pull_reqs_since_last_release(token):
1617
found_last_release = False
1718
page = 1
1819

19-
print("Getting PRs since last release.")
2020
while not found_last_release:
21-
data = get_merged_pull_reqs(token, page)
21+
data = get_merged_pull_reqs(token, page, log_output)
2222
# assume we don't encounter it during the loop
2323
last_release_index = 101
2424

@@ -34,7 +34,7 @@ def get_merged_pull_reqs_since_last_release(token):
3434
return pull_reqs
3535

3636

37-
def get_merged_pull_reqs(token, page):
37+
def get_merged_pull_reqs(token, page, log_output: FileIO=sys.stdout):
3838
"""
3939
Get the merged pull requests based on page. There are
4040
100 results per page. See https://docs.github.com/en/rest/reference/pulls
@@ -53,7 +53,7 @@ def get_merged_pull_reqs(token, page):
5353
"page": page
5454
}
5555

56-
print(f"Querying the GitHub API for requests page #{page}")
56+
print(f"Querying the GitHub API for requests page #{page}", file=log_output)
5757
response = requests.get(url, headers=headers, params=params)
5858
if not response:
5959
print(f"Can't query the GitHub API. Status code is {response.status_code}. Message is {response.text}")

.github/scripts/build_assets/filehandler.py

+30-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import json
2-
from zipfile import ZipFile
2+
from zipfile import ZipFile, is_zipfile
33
from pathlib import Path
44
from typing import List, Union
55
import os
66
import re
7+
from io import FileIO
78

89

910
def find_new_icons_in_devicon_json(devicon_json_path: str, icomoon_json_path: str):
@@ -133,7 +134,7 @@ def is_alias(font_version: str, aliases: List[dict]):
133134
return False
134135

135136

136-
def extract_files(zip_path: str, extract_path: str, delete=True):
137+
def extract_files(zip_path: str, extract_path: str, logfile: FileIO, delete=True):
137138
"""
138139
Extract the style.css and font files from the devicon.zip
139140
folder. Must call the gulp task "get-icomoon-files"
@@ -144,32 +145,52 @@ def extract_files(zip_path: str, extract_path: str, delete=True):
144145
will put the extracted files.
145146
:param delete, whether the function should delete the zip file
146147
when it's done.
148+
:param logfile
147149
"""
148-
print("Extracting zipped files...")
149-
150+
print("Extracting zipped files...", file=logfile)
151+
fixBadZipfile(zip_path, logfile)
152+
print(f"it's zipped {is_zipfile(zip_path)}", file=logfile)
150153
icomoon_zip = ZipFile(zip_path)
151154
target_files = ('selection.json', 'fonts/', 'fonts/devicon.ttf',
152155
'fonts/devicon.woff', 'fonts/devicon.eot',
153156
'fonts/devicon.svg', "style.css")
154157
for file in target_files:
155158
icomoon_zip.extract(file, extract_path)
156159

157-
print("Files extracted")
160+
print("Files extracted", file=logfile)
158161

159162
if delete:
160-
print("Deleting devicon zip file...")
163+
print("Deleting devicon zip file...", file=logfile)
161164
icomoon_zip.close()
162165
os.remove(zip_path)
163166

164167

165-
def rename_extracted_files(extract_path: str):
168+
def fixBadZipfile(zippath: str, logfile: FileIO):
169+
"""
170+
Fix a bad zipfile (one that causes zipfile.ZipFile to throw a BadZipfile Error).
171+
Taken from https://stackoverflow.com/a/11385480/11683637.
172+
"""
173+
f = open(zippath, 'r+b')
174+
data = f.read()
175+
pos = data.find(b'\x50\x4b\x05\x06') # End of central directory signature
176+
if (pos > 0):
177+
# self._log("Trancating file at location " + str(pos + 22)+ ".")
178+
f.seek(pos + 22) # size of 'ZIP end of central directory record'
179+
f.truncate()
180+
else:
181+
print("Zipfile don't need to be fixed", file=logfile)
182+
183+
f.close()
184+
185+
186+
def rename_extracted_files(extract_path: str, logfile: FileIO):
166187
"""
167188
Rename the extracted files selection.json and style.css.
168189
:param extract_path, the location where the function
169190
can find the extracted files.
170191
:return: None.
171192
"""
172-
print("Renaming files")
193+
print("Renaming files", file=logfile)
173194
old_to_new_list = [
174195
{
175196
"old": Path(extract_path, "selection.json"),
@@ -184,7 +205,7 @@ def rename_extracted_files(extract_path: str):
184205
for dict_ in old_to_new_list:
185206
os.replace(dict_["old"], dict_["new"])
186207

187-
print("Files renamed")
208+
print("Files renamed", file=logfile)
188209

189210

190211
def create_screenshot_folder(dir, screenshot_name: str="screenshots/"):

.github/scripts/build_assets/selenium_runner/BuildSeleniumRunner.py

+15-11
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def upload_icomoon(self, icomoon_json_path: str):
2727
:param icomoon_json_path: a path to the iconmoon.json.
2828
:raises TimeoutException: happens when elements are not found.
2929
"""
30-
print("Uploading icomoon.json file...")
30+
print("Uploading icomoon.json file...", file=self.log_output)
3131

3232
# find the file input and enter the file path
3333
import_btn = self.driver.find_element_by_css_selector(
@@ -44,15 +44,15 @@ def upload_icomoon(self, icomoon_json_path: str):
4444
raise Exception("Cannot find the confirm button when uploading the icomoon.json" \
4545
"Ensure that the icomoon.json is in the correct format for Icomoon.io")
4646

47-
print("JSON file uploaded.")
47+
print("JSON file uploaded.", file=self.log_output)
4848

4949
def upload_svgs(self, svgs: List[str], screenshot_folder: str):
5050
"""
5151
Upload the SVGs provided in svgs. This will upload the
5252
:param svgs: a list of svg Paths that we'll upload to icomoon.
5353
:param screenshot_folder: the name of the screenshot_folder.
5454
"""
55-
print("Uploading SVGs...")
55+
print("Uploading SVGs...", file=self.log_output)
5656

5757
import_btn = self.driver.find_element_by_css_selector(
5858
SeleniumRunner.SET_IMPORT_BUTTON_CSS
@@ -63,7 +63,7 @@ def upload_svgs(self, svgs: List[str], screenshot_folder: str):
6363
err_messages = []
6464
for i in range(len(svgs)):
6565
import_btn.send_keys(svgs[i])
66-
print(f"Uploading {svgs[i]}")
66+
print(f"Uploading {svgs[i]}", file=self.log_output)
6767

6868
# see if there are stroke messages or replacing icon message
6969
# there should be none of the second kind
@@ -83,8 +83,9 @@ def upload_svgs(self, svgs: List[str], screenshot_folder: str):
8383
raise Exception(f"Unexpected alert found: {alert}")
8484

8585
self.edit_svg()
86-
print(f"Finished editing icon.")
86+
print(f"Finished editing icon.", file=self.log_output)
8787

88+
print("Finished uploading all files.", file=self.log_output)
8889
if err_messages != []:
8990
message = "BuildSeleniumRunner - Issues found when uploading SVGs:\n"
9091
raise Exception(message + '\n'.join(err_messages))
@@ -94,9 +95,9 @@ def upload_svgs(self, svgs: List[str], screenshot_folder: str):
9495
self.switch_toolbar_option(IcomoonOptionState.SELECT)
9596
self.select_all_icons_in_top_set()
9697
new_svgs_path = str(Path(screenshot_folder, "new_svgs.png").resolve())
97-
self.driver.save_screenshot(new_svgs_path);
98+
self.driver.save_screenshot(new_svgs_path)
9899

99-
print("Finished uploading the svgs...")
100+
print("Finished uploading the svgs...", file=self.log_output)
100101

101102
def take_icon_screenshot(self, screenshot_folder: str):
102103
"""
@@ -105,16 +106,19 @@ def take_icon_screenshot(self, screenshot_folder: str):
105106
:param screenshot_folder: the name of the screenshot_folder.
106107
"""
107108
# take pictures
108-
print("Taking screenshot of the new icons...")
109+
print("Taking screenshot of the new icons...", file=self.log_output)
109110
self.go_to_generate_font_page()
110111

111112
# take an overall screenshot of the icons that were just added
112113
# also include the glyph count
113114
new_icons_path = str(Path(screenshot_folder, "new_icons.png").resolve())
114115
main_content_xpath = "/html/body/div[4]/div[2]/div/div[1]"
115116
main_content = self.driver.find_element_by_xpath(main_content_xpath)
117+
118+
# wait a bit for all the icons to load before we take a pic
119+
time.sleep(SeleniumRunner.MED_WAIT_IN_SEC)
116120
main_content.screenshot(new_icons_path)
117-
print("Saved screenshot of the new icons...")
121+
print("Saved screenshot of the new icons...", file=self.log_output)
118122

119123
def go_to_generate_font_page(self):
120124
"""
@@ -137,7 +141,7 @@ def download_icomoon_fonts(self, zip_path: Path):
137141
what the icons look like.
138142
:param zip_path: the path to the zip file after it's downloaded.
139143
"""
140-
print("Downloading Font files...")
144+
print("Downloading Font files...", file=self.log_output)
141145
if self.current_page != IcomoonPage.SELECTION:
142146
self.go_to_page(IcomoonPage.SELECTION)
143147

@@ -149,7 +153,7 @@ def download_icomoon_fonts(self, zip_path: Path):
149153
)
150154
download_btn.click()
151155
if self.wait_for_zip(zip_path):
152-
print("Font files downloaded.")
156+
print("Font files downloaded.", file=self.log_output)
153157
else:
154158
raise TimeoutError(f"Couldn't find {zip_path} after download button was clicked.")
155159

.github/scripts/build_assets/selenium_runner/PeekSeleniumRunner.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def peek_svgs(self, svgs: List[str], screenshot_folder: str):
2828
:return an array of svgs with strokes as strings. These show which icon
2929
contains stroke.
3030
"""
31-
print("Peeking SVGs...")
31+
print("Peeking SVGs...", file=self.log_output)
3232

3333
import_btn = self.driver.find_element_by_css_selector(
3434
SeleniumRunner.GENERAL_IMPORT_BUTTON_CSS
@@ -37,13 +37,13 @@ def peek_svgs(self, svgs: List[str], screenshot_folder: str):
3737
svgs_with_strokes = []
3838
for i in range(len(svgs)):
3939
import_btn.send_keys(svgs[i])
40-
print(f"Uploaded {svgs[i]}")
40+
print(f"Uploaded {svgs[i]}", file=self.log_output)
4141

4242
alert = self.test_for_possible_alert(self.SHORT_WAIT_IN_SEC)
4343
if alert == None:
4444
pass # all good
4545
elif alert == IcomoonAlerts.STROKES_GET_IGNORED_WARNING:
46-
print(f"- This icon contains strokes: {svgs[i]}")
46+
print(f"- This icon contains strokes: {svgs[i]}", file=self.log_output)
4747
svg = Path(svgs[i])
4848
svgs_with_strokes.append(f"- {svg.name}")
4949
self.click_alert_button(self.ALERTS[alert]["buttons"]["DISMISS"])
@@ -57,9 +57,9 @@ def peek_svgs(self, svgs: List[str], screenshot_folder: str):
5757
new_svgs_path = str(Path(screenshot_folder, "new_svgs.png").resolve())
5858
icon_set_xpath = "/html/body/div[4]/div[1]/div[2]/div[1]"
5959
icon_set = self.driver.find_element_by_xpath(icon_set_xpath)
60-
icon_set.screenshot(new_svgs_path);
60+
icon_set.screenshot(new_svgs_path)
6161

62-
print("Finished peeking the svgs...")
62+
print("Finished peeking the svgs...", file=self.log_output)
6363
return svgs_with_strokes
6464

6565
def peek_icons(self, screenshot_folder: str, icon_info: dict):
@@ -68,7 +68,7 @@ def peek_icons(self, screenshot_folder: str, icon_info: dict):
6868
:param screenshot_folder: the name of the screenshot_folder.
6969
:param icon_info: a dictionary containing info on an icon. Taken from the devicon.json.
7070
"""
71-
print("Begin peeking at the icons...")
71+
print("Begin peeking at the icons...", file=self.log_output)
7272
# ensure all icons in the set is selected.
7373
self.select_all_icons_in_top_set()
7474
self.go_to_page(IcomoonPage.GENERATE_FONT)
@@ -119,4 +119,4 @@ def peek_icons(self, screenshot_folder: str, icon_info: dict):
119119

120120
i += 1
121121

122-
print("Finished peeking the icons...")
122+
print("Finished peeking the icons...", file=self.log_output)

0 commit comments

Comments
 (0)