Skip to content

Commit 0c4be8c

Browse files
authored
Merge pull request #396 from devicons/develop
Release v2.8.0
2 parents ac557d6 + 4c397cf commit 0c4be8c

179 files changed

Lines changed: 1789 additions & 497 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/ISSUE_TEMPLATE/icon-request.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: Icon request
33
about: Requesting a new icon or changes to an existing icon
44
title: 'Icon request: [NAME]'
5-
labels: 'request: icon'
5+
labels: 'request:icon'
66
assignees: ''
77

88
---

.github/scripts/build_assets/SeleniumRunner.py

Lines changed: 89 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -89,70 +89,54 @@ def upload_icomoon(self, icomoon_json_path: str):
8989
:raises TimeoutException: happens when elements are not found.
9090
"""
9191
print("Uploading icomoon.json file...")
92-
try:
93-
self.click_hamburger_input()
94-
95-
# find the file input and enter the file path
96-
import_btn = self.driver.find_element(By.XPATH, "(//li[@class='file'])[1]//input")
97-
import_btn.send_keys(icomoon_json_path)
98-
except SeleniumTimeoutException as e:
99-
print(e.stacktrace)
100-
print("Selenium timed out. Couldn't find import button.")
101-
self.close()
102-
raise e
103-
except Exception as e:
104-
self.close()
105-
raise e
92+
self.click_hamburger_input()
93+
94+
# find the file input and enter the file path
95+
import_btn = self.driver.find_element(By.XPATH, "(//li[@class='file'])[1]//input")
96+
import_btn.send_keys(icomoon_json_path)
10697

10798
try:
10899
confirm_btn = WebDriverWait(self.driver, SeleniumRunner.MED_WAIT_IN_SEC).until(
109100
ec.element_to_be_clickable((By.XPATH, "//div[@class='overlay']//button[text()='Yes']"))
110101
)
111102
confirm_btn.click()
112103
except SeleniumTimeoutException as e:
113-
print(e.stacktrace)
114-
print("Cannot find the confirm button when uploading the icomoon.json",
115-
"Ensure that the icomoon.json is in the correct format for Icomoon.io",
116-
sep='\n')
117-
self.close()
104+
raise Exception("Cannot find the confirm button when uploading the icomoon.json" \
105+
"Ensure that the icomoon.json is in the correct format for Icomoon.io")
118106

119107
print("JSON file uploaded.")
120108

121-
def upload_svgs(self, svgs: List[str]):
109+
def upload_svgs(self, svgs: List[str], screenshot_folder: str=""):
122110
"""
123111
Upload the SVGs provided in folder_info
124112
:param svgs: a list of svg Paths that we'll upload to icomoon.
113+
:param screenshot_folder: the name of the screenshot_folder. If
114+
the value is provided, it means the user want to take a screenshot
115+
of each icon.
125116
"""
126-
try:
127-
print("Uploading SVGs...")
117+
print("Uploading SVGs...")
128118

129-
edit_mode_btn = self.driver.find_element_by_css_selector(
130-
"div.btnBar button i.icon-edit"
131-
)
132-
edit_mode_btn.click()
133-
134-
self.click_hamburger_input()
135-
136-
for svg in svgs:
137-
import_btn = self.driver.find_element_by_css_selector(
138-
"li.file input[type=file]"
139-
)
140-
import_btn.send_keys(svg)
141-
print(f"Uploaded {svg}")
142-
self.test_for_possible_alert(self.SHORT_WAIT_IN_SEC, "Dismiss")
143-
self.remove_color_from_icon()
144-
145-
# take a screenshot of the icons that were just added
146-
self.driver.save_screenshot("new_icons.png");
147-
self.click_hamburger_input()
148-
select_all_button = WebDriverWait(self.driver, self.LONG_WAIT_IN_SEC).until(
149-
ec.element_to_be_clickable((By.XPATH, "//button[text()='Select All']"))
119+
edit_mode_btn = self.driver.find_element_by_css_selector(
120+
"div.btnBar button i.icon-edit"
121+
)
122+
edit_mode_btn.click()
123+
124+
self.click_hamburger_input()
125+
126+
for i in range(len(svgs)):
127+
import_btn = self.driver.find_element_by_css_selector(
128+
"li.file input[type=file]"
150129
)
151-
select_all_button.click()
152-
print("Finished uploading the svgs...")
153-
except Exception as e:
154-
self.close()
155-
raise e
130+
import_btn.send_keys(svgs[i])
131+
print(f"Uploaded {svgs[i]}")
132+
self.test_for_possible_alert(self.SHORT_WAIT_IN_SEC, "Dismiss")
133+
self.click_on_just_added_icon(screenshot_folder, i)
134+
135+
# take a screenshot of the icons that were just added
136+
new_icons_path = str(Path(screenshot_folder, "new_icons.png").resolve())
137+
self.driver.save_screenshot(new_icons_path);
138+
139+
print("Finished uploading the svgs...")
156140

157141
def click_hamburger_input(self):
158142
"""
@@ -161,20 +145,16 @@ def click_hamburger_input(self):
161145
input two times before the menu appears.
162146
:return: None.
163147
"""
164-
try:
165-
hamburger_input = self.driver.find_element_by_xpath(
166-
"(//i[@class='icon-menu'])[2]"
167-
)
148+
hamburger_input = self.driver.find_element_by_xpath(
149+
"(//i[@class='icon-menu'])[2]"
150+
)
168151

169-
menu_appear_callback = ec.element_to_be_clickable(
170-
(By.CSS_SELECTOR, "h1 ul.menuList2")
171-
)
152+
menu_appear_callback = ec.element_to_be_clickable(
153+
(By.CSS_SELECTOR, "h1 ul.menuList2")
154+
)
172155

173-
while not menu_appear_callback(self.driver):
174-
hamburger_input.click()
175-
except Exception as e:
176-
self.close()
177-
raise e
156+
while not menu_appear_callback(self.driver):
157+
hamburger_input.click()
178158

179159
def test_for_possible_alert(self, wait_period: float, btn_text: str):
180160
"""
@@ -191,22 +171,37 @@ def test_for_possible_alert(self, wait_period: float, btn_text: str):
191171
)
192172
dismiss_btn.click()
193173
except SeleniumTimeoutException:
194-
pass
174+
pass # nothing found => everything is good
175+
176+
def click_on_just_added_icon(self, screenshot_folder: str, index: int):
177+
"""
178+
Click on the most recently added icon so we can remove the colors
179+
and take a snapshot if needed.
180+
"""
181+
recently_uploaded_icon = WebDriverWait(self.driver, self.LONG_WAIT_IN_SEC).until(
182+
ec.element_to_be_clickable((By.XPATH, "//div[@id='set0']//mi-box[1]//div"))
183+
)
184+
recently_uploaded_icon.click()
185+
186+
self.remove_color_from_icon()
187+
188+
if screenshot_folder:
189+
screenshot_path = str(Path(screenshot_folder, f"screenshot_{index}.png").resolve())
190+
self.driver.save_screenshot(screenshot_path)
191+
print("Took screenshot and saved it at " + screenshot_path)
192+
193+
close_btn = self.driver \
194+
.find_element_by_css_selector("div.overlayWindow i.icon-close")
195+
close_btn.click()
195196

196197
def remove_color_from_icon(self):
197198
"""
198199
Remove the color from the most recent uploaded icon.
199-
:return: None.
200+
This is because some SVG have colors in them and we don't want to
201+
force contributors to remove them in case people want the colored SVGs.
202+
The color removal is also necessary so that the Icomoon-generated
203+
icons fit within one font symbol/ligiature.
200204
"""
201-
try:
202-
recently_uploaded_icon = WebDriverWait(self.driver, self.LONG_WAIT_IN_SEC).until(
203-
ec.element_to_be_clickable((By.XPATH, "//div[@id='set0']//mi-box[1]//div"))
204-
)
205-
recently_uploaded_icon.click()
206-
except Exception as e:
207-
self.close()
208-
raise e
209-
210205
try:
211206
color_tab = WebDriverWait(self.driver, self.SHORT_WAIT_IN_SEC).until(
212207
ec.element_to_be_clickable((By.CSS_SELECTOR, "div.overlayWindow i.icon-droplet"))
@@ -217,42 +212,35 @@ def remove_color_from_icon(self):
217212
.find_element_by_css_selector("div.overlayWindow i.icon-droplet-cross")
218213
remove_color_btn.click()
219214
except SeleniumTimeoutException:
220-
pass
221-
except Exception as e:
222-
self.close()
223-
raise e
224-
225-
try:
226-
close_btn = self.driver \
227-
.find_element_by_css_selector("div.overlayWindow i.icon-close")
228-
close_btn.click()
229-
except Exception as e:
230-
self.close()
231-
raise e
215+
pass # do nothing cause sometimes, the color tab doesn't appear in the site
232216

233217
def download_icomoon_fonts(self, zip_path: Path):
234218
"""
235219
Download the icomoon.zip from icomoon.io.
236220
:param zip_path: the path to the zip file after it's downloaded.
237221
"""
238-
try:
239-
print("Downloading Font files...")
240-
self.driver.find_element_by_css_selector(
241-
"a[href='#/select/font']"
242-
).click()
243-
244-
self.test_for_possible_alert(self.MED_WAIT_IN_SEC, "Continue")
245-
download_btn = WebDriverWait(self.driver, SeleniumRunner.LONG_WAIT_IN_SEC).until(
246-
ec.presence_of_element_located((By.CSS_SELECTOR, "button.btn4 span"))
247-
)
248-
download_btn.click()
249-
if self.wait_for_zip(zip_path):
250-
print("Font files downloaded.")
251-
else:
252-
raise TimeoutError(f"Couldn't find {zip_path} after download button was clicked.")
253-
except Exception as e:
254-
self.close()
255-
raise e
222+
# select all the svgs so that the newly added svg are part of the collection
223+
self.click_hamburger_input()
224+
select_all_button = WebDriverWait(self.driver, self.LONG_WAIT_IN_SEC).until(
225+
ec.element_to_be_clickable((By.XPATH, "//button[text()='Select All']"))
226+
)
227+
select_all_button.click()
228+
229+
print("Downloading Font files...")
230+
font_tab = self.driver.find_element_by_css_selector(
231+
"a[href='#/select/font']"
232+
)
233+
font_tab.click()
234+
235+
self.test_for_possible_alert(self.MED_WAIT_IN_SEC, "Continue")
236+
download_btn = WebDriverWait(self.driver, SeleniumRunner.LONG_WAIT_IN_SEC).until(
237+
ec.presence_of_element_located((By.CSS_SELECTOR, "button.btn4 span"))
238+
)
239+
download_btn.click()
240+
if self.wait_for_zip(zip_path):
241+
print("Font files downloaded.")
242+
else:
243+
raise TimeoutError(f"Couldn't find {zip_path} after download button was clicked.")
256244

257245
def wait_for_zip(self, zip_path: Path) -> bool:
258246
"""

.github/scripts/build_assets/util.py renamed to .github/scripts/build_assets/arg_getters.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from pathlib import Path
21
from argparse import ArgumentParser
32
from build_assets.PathResolverAction import PathResolverAction
43

5-
def get_commandline_args():
4+
5+
def get_selenium_runner_args(peek_mode=False):
66
parser = ArgumentParser(description="Upload svgs to Icomoon to create icon files.")
77

88
parser.add_argument("--headless",
@@ -26,8 +26,11 @@ def get_commandline_args():
2626
action=PathResolverAction)
2727

2828
parser.add_argument("download_path",
29-
help="The path where you'd like to download the Icomoon files to",
29+
help="The download destination of the Icomoon files",
3030
action=PathResolverAction)
3131

32+
if peek_mode:
33+
parser.add_argument("--pr_title",
34+
help="The title of the PR that we are peeking at")
3235

3336
return parser.parse_args()

.github/scripts/build_assets/filehandler.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,24 @@ def rename_extracted_files(extract_path: str):
145145
os.replace(dict_["old"], dict_["new"])
146146

147147
print("Files renamed")
148+
149+
150+
def create_screenshot_folder(dir, screenshot_name: str="screenshots/"):
151+
"""
152+
Create a screenshots folder in the dir.
153+
:param dir, the dir where we want to create the folder.
154+
:param screenshot_name, the name of the screenshot folder.
155+
:raise Exception if the dir provided is not a directory.
156+
:return the string name of the screenshot folder.
157+
"""
158+
folder = Path(dir).resolve()
159+
if not folder.is_dir():
160+
raise Exception(f"This is not a dir: {str(folder)}. \ndir must be a valid directory")
161+
162+
screenshot_folder = Path(folder, screenshot_name)
163+
try:
164+
os.mkdir(screenshot_folder)
165+
except FileExistsError:
166+
print(f"{screenshot_folder} already exist. Script will do nothing.")
167+
finally:
168+
return str(screenshot_folder)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import json
2+
import os
3+
4+
5+
if __name__ == "__main__":
6+
img_urls_list = json.loads(os.environ["IMG_URLS"])
7+
template = "![Detailed Screenshot]({})"
8+
markdown = [template.format(img_url) for img_url in img_urls_list]
9+
print("\n\n".join(markdown))
10+

.github/scripts/icomoon_build.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
from pathlib import Path
2+
import sys
23
from selenium.common.exceptions import TimeoutException
34

45
# pycharm complains that build_assets is an unresolved ref
56
# don't worry about it, the script still runs
67
from build_assets.SeleniumRunner import SeleniumRunner
7-
from build_assets import filehandler, util
8+
from build_assets import filehandler, arg_getters
89

910

1011
def main():
11-
args = util.get_commandline_args()
12+
args = arg_getters.get_selenium_runner_args()
1213
new_icons = filehandler.find_new_icons(args.devicon_json_path, args.icomoon_json_path)
1314
if len(new_icons) == 0:
14-
print("No files need to be uploaded. Ending script...")
15-
return
15+
sys.exit("No files need to be uploaded. Ending script...")
1616

1717
# print list of new icons
1818
print("List of new icons:", *new_icons, sep = "\n")
@@ -32,10 +32,11 @@ def main():
3232
filehandler.rename_extracted_files(args.download_path)
3333
print("Task completed.")
3434
except TimeoutException as e:
35-
print(e)
36-
print(e.stacktrace)
35+
sys.exit("Selenium Time Out Error: \n" + str(e))
36+
except Exception as e:
37+
sys.exit(e)
3738
finally:
38-
runner.close()
39+
runner.close()
3940

4041

4142
if __name__ == "__main__":

0 commit comments

Comments
 (0)