Skip to content

Commit ca0eb3d

Browse files
authored
Merge pull request #365 from devicons/develop
Release v2.7
2 parents 40cd6bc + 8c63f66 commit ca0eb3d

71 files changed

Lines changed: 5296 additions & 2495 deletions

Some content is hidden

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

.github/scripts/build_assets/SeleniumRunner.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,26 @@ class SeleniumRunner:
3636
"""
3737
ICOMOON_URL = "https://icomoon.io/app/#/select"
3838

39-
def __init__(self, icomoon_json_path: str, download_path: str,
40-
geckodriver_path: str, headless):
39+
def __init__(self, download_path: str,
40+
geckodriver_path: str, headless: bool):
4141
"""
4242
Create a SeleniumRunner object.
43-
:param icomoon_json_path: a path to the iconmoon.json.
4443
:param download_path: the location where you want to download
4544
the icomoon.zip to.
4645
:param geckodriver_path: the path to the firefox executable.
4746
:param headless: whether to run browser in headless (no UI) mode.
4847
"""
49-
self.icomoon_json_path = icomoon_json_path
50-
self.download_path = download_path
5148
self.driver = None
52-
self.set_options(geckodriver_path, headless)
49+
self.set_options(download_path, geckodriver_path, headless)
5350

54-
def set_options(self, geckodriver_path: str, headless: bool):
51+
def set_options(self, download_path: str, geckodriver_path: str,
52+
headless: bool):
5553
"""
5654
Build the WebDriver with Firefox Options allowing downloads and
5755
set download to download_path.
56+
:param download_path: the location where you want to download
5857
:param geckodriver_path: the path to the firefox executable.
58+
the icomoon.zip to.
5959
:param headless: whether to run browser in headless (no UI) mode.
6060
6161
:raises AssertionError: if the page title does not contain
@@ -69,25 +69,34 @@ def set_options(self, geckodriver_path: str, headless: bool):
6969

7070
# set the default download path to downloadPath
7171
options.set_preference("browser.download.folderList", 2)
72-
options.set_preference("browser.download.dir", self.download_path)
72+
options.set_preference("browser.download.dir", download_path)
7373
options.headless = headless
7474

7575
self.driver = WebDriver(options=options, executable_path=geckodriver_path)
7676
self.driver.get(self.ICOMOON_URL)
7777
assert "IcoMoon App" in self.driver.title
78-
79-
def upload_icomoon(self):
78+
79+
# wait until the whole web page is loaded by testing the hamburger input
80+
hamburger_input = WebDriverWait(self.driver, SeleniumRunner.LONG_WAIT_IN_SEC).until(
81+
ec.element_to_be_clickable((By.CSS_SELECTOR,
82+
"button.btn5.lh-def.transparent i.icon-menu"))
83+
)
84+
hamburger_input.click()
85+
print("Accessed icomoon.io")
86+
87+
def upload_icomoon(self, icomoon_json_path: str):
8088
"""
8189
Upload the icomoon.json to icomoon.io.
90+
:param icomoon_json_path: a path to the iconmoon.json.
8291
:raises TimeoutException: happens when elements are not found.
8392
"""
8493
print("Uploading icomoon.json file...")
8594
try:
8695
# find the file input and enter the file path
8796
import_btn = WebDriverWait(self.driver, SeleniumRunner.LONG_WAIT_IN_SEC).until(
88-
ec.presence_of_element_located((By.CSS_SELECTOR, "div#file input"))
97+
ec.element_to_be_clickable((By.CSS_SELECTOR, "div#file input"))
8998
)
90-
import_btn.send_keys(self.icomoon_json_path)
99+
import_btn.send_keys(icomoon_json_path)
91100
except Exception as e:
92101
self.close()
93102
raise e
@@ -130,11 +139,14 @@ def upload_svgs(self, svgs: List[str]):
130139
self.test_for_possible_alert(self.SHORT_WAIT_IN_SEC, "Dismiss")
131140
self.remove_color_from_icon()
132141

142+
# take a screenshot of the icons that were just added
143+
self.driver.save_screenshot("new_icons.png");
133144
self.click_hamburger_input()
134145
select_all_button = WebDriverWait(self.driver, self.LONG_WAIT_IN_SEC).until(
135146
ec.element_to_be_clickable((By.XPATH, "//button[text()='Select All']"))
136147
)
137148
select_all_button.click()
149+
print("Finished uploading the svgs...")
138150
except Exception as e:
139151
self.close()
140152
raise e
@@ -152,7 +164,7 @@ def click_hamburger_input(self):
152164
)
153165

154166
menu_appear_callback = ec.element_to_be_clickable(
155-
(By.CSS_SELECTOR, "h1#setH2 ul")
167+
(By.CSS_SELECTOR, "h1 ul.menuList2")
156168
)
157169

158170
while not menu_appear_callback(self.driver):

.github/scripts/build_assets/filehandler.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
def find_new_icons(devicon_json_path: str, icomoon_json_path: str) -> List[dict]:
1010
"""
1111
Find the newly added icons by finding the difference between
12-
the devicon_test.json and the icomoon_test.json.
13-
:param devicon_json_path, the path to the devicon_test.json.
12+
the devicon.json and the icomoon.json.
13+
:param devicon_json_path, the path to the devicon.json.
1414
:param icomoon_json_path: a path to the iconmoon.json.
1515
:return: a list of the new icons as JSON objects.
1616
"""
@@ -33,8 +33,8 @@ def is_not_in_icomoon_json(icon, icomoon_json) -> bool:
3333
Checks whether the icon's name is not in the icomoon_json.
3434
:param icon: the icon object we are searching for.
3535
:param icomoon_json: the icomoon json object parsed from
36-
icomoon_test.json.
37-
:return: True if icon's name is not in the icomoon_test.json, else False.
36+
icomoon.json.
37+
:return: True if icon's name is not in the icomoon.json, else False.
3838
"""
3939
pattern = re.compile(f"^{icon['name']}-")
4040

@@ -46,7 +46,7 @@ def is_not_in_icomoon_json(icon, icomoon_json) -> bool:
4646

4747
def get_svgs_paths(new_icons: List[dict], icons_folder_path: str) -> List[str]:
4848
"""
49-
Get all the suitable svgs file path listed in the devicon_test.json.
49+
Get all the suitable svgs file path listed in the devicon.json.
5050
:param new_icons, a list containing the info on the new icons.
5151
:param icons_folder_path, the path where the function can find the
5252
listed folders.
@@ -66,7 +66,9 @@ def get_svgs_paths(new_icons: List[dict], icons_folder_path: str) -> List[str]:
6666
aliases = [] # create empty list of aliases if not provided in devicon.json
6767

6868
for font_version in icon_info["versions"]["font"]:
69+
# if it's an alias, we don't want to make it into an icon
6970
if is_alias(font_version, aliases):
71+
print(f"Not exist {icon_info['name']}-{font_version}.svg")
7072
continue
7173

7274
file_name = f"{icon_info['name']}-{font_version}.svg"

.github/scripts/icomoon_peek.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from pathlib import Path
2+
from argparse import ArgumentParser
3+
from selenium.common.exceptions import TimeoutException
4+
5+
# pycharm complains that build_assets is an unresolved ref
6+
# don't worry about it, the script still runs
7+
from build_assets.SeleniumRunner import SeleniumRunner
8+
from build_assets import filehandler
9+
from build_assets.PathResolverAction import PathResolverAction
10+
11+
12+
def main():
13+
parser = ArgumentParser(description="Upload svgs to Icomoon to create icon files.")
14+
15+
parser.add_argument("--headless",
16+
help="Whether to run the browser in headless/no UI mode",
17+
action="store_true")
18+
19+
parser.add_argument("geckodriver_path",
20+
help="The path to the firefox executable file",
21+
action=PathResolverAction)
22+
23+
parser.add_argument("icomoon_json_path",
24+
help="The path to the icomoon.json aka the selection.json created by Icomoon",
25+
action=PathResolverAction)
26+
27+
parser.add_argument("devicon_json_path",
28+
help="The path to the devicon.json",
29+
action=PathResolverAction)
30+
31+
parser.add_argument("icons_folder_path",
32+
help="The path to the icons folder",
33+
action=PathResolverAction)
34+
35+
parser.add_argument("download_path",
36+
help="The path where you'd like to download the Icomoon files to",
37+
action=PathResolverAction)
38+
39+
args = parser.parse_args()
40+
41+
new_icons = filehandler.find_new_icons(args.devicon_json_path, args.icomoon_json_path)
42+
if len(new_icons) == 0:
43+
print("No files need to be peek. Ending script...")
44+
return
45+
46+
# print list of new icons, separated by comma
47+
print("List of new icons:")
48+
print(*new_icons, sep = "\n")
49+
try:
50+
runner = SeleniumRunner(args.download_path,
51+
args.geckodriver_path, args.headless)
52+
svgs = filehandler.get_svgs_paths(new_icons, args.icons_folder_path)
53+
runner.upload_svgs(svgs)
54+
runner.close()
55+
print("Task completed.")
56+
except TimeoutException as e:
57+
print(e)
58+
print(e.stacktrace)
59+
runner.close()
60+
61+
62+
if __name__ == "__main__":
63+
main()

.github/scripts/icomoon_upload.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ def main():
4747
print("List of new icons:")
4848
print(*new_icons, sep = "\n")
4949
try:
50-
runner = SeleniumRunner(args.icomoon_json_path, args.download_path,
50+
runner = SeleniumRunner(args.download_path,
5151
args.geckodriver_path, args.headless)
52-
runner.upload_icomoon()
52+
runner.upload_icomoon(args.icomoon_json_path)
5353
svgs = filehandler.get_svgs_paths(new_icons, args.icons_folder_path)
5454
runner.upload_svgs(svgs)
5555

.github/workflows/build_icons.yml

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
name: Build Icons
2-
on:
3-
pull_request:
4-
branches:
5-
- master
6-
push:
7-
branches:
8-
- master
2+
on: workflow_dispatch
93
jobs:
104
build:
115
name: Get Fonts From Icomoon
@@ -14,6 +8,7 @@ jobs:
148
- uses: actions/checkout@v2
159
with:
1610
ref: ${{ github.head_ref }}
11+
repository: ${{ github.event.pull_request.head.repo.full_name}}
1712
- name: Setup Python v3.8
1813
uses: actions/setup-python@v2
1914
with:
@@ -30,13 +25,26 @@ jobs:
3025
./icomoon.json ./devicon.json ./icons ./ --headless
3126
- name: Upload geckodriver.log for debugging purposes
3227
uses: actions/upload-artifact@v2
28+
if: ${{failure()}}
3329
with:
3430
name: geckodriver-log
3531
path: ./geckodriver.log
36-
- name: Running gulp default task for building devicon.min.css
37-
run: |
38-
gulp default
39-
- name: Commit changes
40-
uses: stefanzweifel/git-auto-commit-action@v4
32+
- name: Upload screenshot of the newly made icons
33+
uses: actions/upload-artifact@v2
34+
if: ${{success()}}
35+
with:
36+
name: new_icons
37+
path: ./new_icons.png
38+
- name: Running npm task for building devicon.min.css
39+
if: ${{ success() }}
40+
run: npm run build-css
41+
- name: Create Pull Request
42+
if: ${{ success() }}
43+
uses: peter-evans/create-pull-request@v3
4144
with:
42-
commit_message: Build new icons, icomoon.json and devicon.css
45+
branch: ${{ format('build/{0}', github.head_ref) }}
46+
base: 'develop'
47+
commit-message: 'Built new icons, icomoon.json and devicon.css'
48+
title: 'bot:build new icons, icomoon.json and devicon.css'
49+
body: 'Automated font-building task ran by GitHub Actions bot'
50+
delete-branch: true

.github/workflows/peek_icons.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Peek Icons
2+
on:
3+
pull_request:
4+
types: [labeled]
5+
jobs:
6+
build:
7+
name: Get Fonts From Icomoon
8+
if: contains(github.event.pull_request.labels.*.name, 'bot:peek')
9+
runs-on: windows-2019
10+
steps:
11+
- uses: actions/checkout@v2
12+
with:
13+
ref: ${{ github.head_ref }}
14+
repository: ${{ github.event.pull_request.head.repo.full_name}}
15+
- name: Setup Python v3.8
16+
uses: actions/setup-python@v2
17+
with:
18+
python-version: 3.8
19+
- name: Install dependencies (python, pip, npm)
20+
run: |
21+
python -m pip install --upgrade pip
22+
pip install -r ./.github/scripts/requirements.txt
23+
npm install
24+
- name: Run icomoon_peek.py
25+
run: >
26+
python ./.github/scripts/icomoon_peek.py
27+
./.github/scripts/build_assets/geckodriver-v0.27.0-win64/geckodriver.exe
28+
./icomoon.json ./devicon.json ./icons ./ --headless
29+
- name: Upload geckodriver.log for debugging purposes
30+
uses: actions/upload-artifact@v2
31+
if: ${{failure()}}
32+
with:
33+
name: geckodriver-log
34+
path: ./geckodriver.log
35+
- name: Upload screenshot of the newly made icons
36+
uses: actions/upload-artifact@v2
37+
if: ${{success()}}
38+
with:
39+
name: new_icons
40+
path: ./new_icons.png
41+
# - name: Comment on the PR about the result
42+
# uses: github-actions-up-and-running/pr-comment@v1.0.1
43+
# with:
44+
# repo-token: ${{ secrets.GITHUB_TOKEN }}
45+
# message: >
46+
# Hi! I'm Devicons' GitHub Actions Bot!
47+
48+
# I just peeked at the icons that you wanted to add and upload them to the
49+
# [Actions page](https://github.com/devicons/devicon/actions). The maintainers
50+
# will now take a look at it and decide whether to merge your PR.
51+
52+
# Cheers :),
53+
54+
# Bot

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ node_modules
33
.idea
44
geckodriver.log
55
__pycache__
6-
*.pyc
6+
*.pyc
7+
new_icons.png

0 commit comments

Comments
 (0)