-
Notifications
You must be signed in to change notification settings - Fork 1
/
Font-Downloader.py
227 lines (207 loc) · 10.5 KB
/
Font-Downloader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
import requests
import os
import time
from colorama import init, Fore, Back, Style
os.system("cls" if os.name=="nt" else "clear")
init()
#App title and info
print( " " + Fore.CYAN + " ___ _ " + "" + " ")
print(Fore.YELLOW + " Dev: " + Fore.CYAN + "| __|__ _ _| |_ " + Fore.YELLOW + " Version: ")
print(Fore.GREEN + " hamid0740 " + Fore.CYAN + "| _/ _ \ ' \ _|" + Fore.GREEN + " 1.9.1 Beta ")
print( " " + Fore.CYAN + "|_|\___/_||_\__|" + "" + " ")
print(Fore.CYAN + " ___ _ _ ")
print(Fore.CYAN + "| \ _____ __ ___ _ | |___ __ _ __| |___ _ _ ")
print(Fore.CYAN + "| |) / _ \ V V / ' \| / _ \/ _` / _` / -_) '_|")
print(Fore.CYAN + "|___/\___/\_/\_/|_||_|_\___/\__,_\__,_\___|_| ")
print(Fore.MAGENTA + " https://github.com/hamid0740/Font-Downloader " + "\n")
#Asking inspection speed
speed_codes = ["2"]
print(Fore.GREEN + "code 1: " + Fore.RED + "Fastest speed, least accurate (Default)\n" + Fore.GREEN + "code 2: " + Fore.RED + "Slower speed, more accurate")
print(Fore.YELLOW + "Enter inspection speed:" + Style.RESET_ALL, end = " ")
speed = input()
#Defining temporary variables for weight names
##Weight names that don't ever get Extra, Ultra, Very, Semi or Demi
weights1 = ["Hairline", "Line", "Book", "News", "Demi", "Regular", "Normal", "Text", "Medium", "Heavy", "Mass", "Fat", "Poster"]
##Weight names that may get Extra, Ultra or Very
weights2 = ["Thin", "Light", "Lite", "Thick", "Bold", "Dark", "Black"]
##Weight names that may get Semi or Demi
weights3 = ["Light", "Bold"]
def crt_tmp_wgts():
global weights2_temp
global weights3_temp
#Creating temporary weight names that may get Extra, Ultra or Very
weights2_temp = []
for i in range(len(weights2)):
weights2_temp.append(weights2[i])
weights2_temp.append("Extra" + weights2[i])
weights2_temp.append("Extra" + weights2[i].lower())
weights2_temp.append("Ultra" + weights2[i])
weights2_temp.append("Ultra" + weights2[i].lower())
weights2_temp.append("Extra-" + weights2[i])
weights2_temp.append("Extra-" + weights2[i].lower())
weights2_temp.append("Ultra-" + weights2[i])
weights2_temp.append("Ultra-" + weights2[i].lower())
weights2_temp.append("Very" + weights2[i])
weights2_temp.append("Very" + weights2[i].lower())
weights2_temp.append("Very-" + weights2[i])
weights2_temp.append("Very-" + weights2[i].lower())
#Creating temp weight names that may get Semi or Demi
weights3_temp = []
for i in range(len(weights3)):
weights3_temp.append(weights3[i])
weights3_temp.append("Semi" + weights3[i])
weights3_temp.append("Semi" + weights3[i].lower())
weights3_temp.append("Demi" + weights3[i])
weights3_temp.append("Demi" + weights3[i].lower())
weights3_temp.append("Semi-" + weights3[i])
weights3_temp.append("Semi-" + weights3[i].lower())
weights3_temp.append("Demi-" + weights3[i])
weights3_temp.append("Demi-" + weights3[i].lower())
crt_tmp_wgts()
#Defining font formats
formats = ["eot", "otf", "svg", "ttf", "woff", "woff2"]
#Asking font name
print(Fore.GREEN + "\nThis name will be used to save font files as.")
print(Fore.YELLOW + "Enter the font name:" + Style.RESET_ALL, end = " ")
font_name = input()
#Asking font file URL
print(Fore.CYAN + "\nFind a font file URL in a website and enter it below. You may use these variables to create the URL pattern yourself.\n" + Fore.MAGENTA + "{WEIGHT}: Thin, Regular, Bold ...\n{FORMAT}: eot, ttf, woff2 ...\n" + Fore.RED + "Direct: " + Fore.GREEN + "https://example.com/fonts/Arial/woff2/Arial-Bold.woff2\n" + Fore.RED + "Pattern: " + Fore.GREEN + "https://example.com/fonts/Arial/{FORMAT}/Arial-{WEIGHT}.{FORMAT}")
print(Fore.YELLOW + "Enter the font file Direct or Pattern URL:" + Style.RESET_ALL, end = " ")
pattern_url = input()
####To do (for v2.0)
####Fixing weight name on any case
####Now "LiGhT" won't be renamed with "{WEIGHT}"
#Creating pattern URL
for i in range(len(weights1)):
pattern_url = pattern_url.replace(weights1[i], "{WEIGHT}")
for i in range(len(weights2)):
pattern_url = pattern_url.replace(weights2[i], "{WEIGHT}")
for i in range(len(weights3)):
pattern_url = pattern_url.replace(weights3[i], "{WEIGHT}")
frmts_rplc = ["eot", "otf", "svg", "ttf", "woff2", "woff"]
for i in range(len(frmts_rplc)):
pattern_url = pattern_url.replace(frmts_rplc[i], "{FORMAT}")
####To do (for v1.9.2)
####Delete def crt_tmp_wgts()
####Make for loop for weights2_temp and if "Very" in that item, pop that item
#Applying speed code
if not speed in speed_codes:
weights1 = [e for e in weights1 if e not in ["Line", "Book", "News", "Demi", "Normal", "Text", "Mass", "Poster"]]
weights1.append("Thin")
weights2 = [e for e in weights2 if e not in ["Thin", "Lite", "Thick", "Dark"]]
weights3 = [e for e in weights3 if e not in ["Light"]]
formats = [e for e in formats if e not in ["otf", "svg"]]
crt_tmp_wgts()
for i in range(len(weights2)):
if not speed in speed_codes:
weights2_temp.remove("Extra-" + weights2[i])
weights2_temp.remove("Extra-" + weights2[i].lower())
weights2_temp.remove("Ultra-" + weights2[i])
weights2_temp.remove("Ultra-" + weights2[i].lower())
weights2_temp.remove("Very" + weights2[i])
weights2_temp.remove("Very" + weights2[i].lower())
weights2_temp.remove("Very-" + weights2[i])
weights2_temp.remove("Very-" + weights2[i].lower())
for i in range(len(weights3)):
if not speed in speed_codes:
weights3_temp.remove("Semi-" + weights3[i])
weights3_temp.remove("Semi-" + weights3[i].lower())
weights3_temp.remove("Demi-" + weights3[i])
weights3_temp.remove("Demi-" + weights3[i].lower())
#Defining final weight names
weights_standard = list(dict.fromkeys(weights1 + weights2_temp + weights3_temp))
weights_lower = list(dict.fromkeys([w.lower() for w in weights_standard]))
weights_upper = list(dict.fromkeys([w.upper() for w in weights_standard]))
#Asking weight names case
print(Fore.MAGENTA + "\n's' for Standard case (" + str(len(weights_standard)) + " weight names)\n" + "'l' for Lower case (" + str(len(weights_lower)) + " weight names)\n" + "'u' for Upper case (" + str(len(weights_upper)) + " weight names)\n" + "'all' for All cases (" + str(len(weights_standard) + len(weights_lower) + len(weights_upper)) + " weight names)\n" + Fore.CYAN + "You can combine letters for combined cases. like 'lu' to have Lower and Upper cases.")
print(Fore.YELLOW + "As you've inspected font URLs, how is their weight name case?" + Style.RESET_ALL, end = " ")
weights_case = input()
weights = []
if "all" in weights_case.lower():
weights = weights_standard + weights_lower + weights_upper
if "s" in weights_case.lower() and not "all" in weights_case.lower():
weights += weights_standard
if "l" in weights_case.lower() and not "all" in weights_case.lower():
weights += weights_lower
if "u" in weights_case.lower() and not "all" in weights_case.lower():
weights += weights_upper
if "s" not in weights_case.lower() and "l" not in weights_case.lower() and "u" not in weights_case.lower() and not "all" in weights_case.lower():
weights = weights_standard
print("")
#Generate links for inspection
if not os.path.exists(font_name):
os.makedirs(font_name)
links = []
links_format = []
for j in range(len(formats)):
url = pattern_url.replace("{WEIGHT}", "").replace("{FORMAT}", formats[j])
url = url.replace("-." + formats[j], "." + formats[j]).replace("_." + formats[j], "." + formats[j]).replace(" ." + formats[j], "." + formats[j])
links.append(url)
links_format.append(formats[j])
for i in range(len(weights)):
for j in range(len(formats)):
url = pattern_url.replace("{WEIGHT}", weights[i]).replace("{FORMAT}", formats[j])
links.append(url)
links_format.append(formats[j])
##Writing links in Links-All.txt
links_text = ""
for i in range(len(links)):
links_text += links[i] + "\n"
open(font_name + "/" + font_name + "-Links-All.txt", "w").write(links_text.rstrip())
#Download function
count = 0
r_headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36", "referer": "https://github.com/hamid0740/Font-Downloader" }
def dl(url, frmt):
global count
name = url.split("/")[-1]
response = requests.head(url, allow_redirects = True, headers = r_headers)
r_sc = response.status_code
r_ct = response.headers.get("content-type")
if r_sc in range(200, 299) and not r_ct in ["text/html"]:
if not url.lower() in open(font_name + "/" + font_name + "-Links.txt", "r").read().lower():
request = requests.get(url, allow_redirects = True, headers = r_headers)
open(font_name + "/" + frmt + "/" + name, "wb").write(request.content)
print(Fore.GREEN + "[✓] " + name +" | Downloaded!")
open(font_name + "/" + font_name + "-Links.txt", "a").write(url + "\n")
count += 1
else:
print(Fore.MAGENTA + "[!] " + name +" | File already exists!")
elif r_sc == 403:
print(Fore.RED + "[X] " + name +" | (403) Access denied!")
elif r_sc == 404:
print(Fore.RED + "[X] " + name +" | (404) Not found!")
elif r_sc == 408:
print(Fore.RED + "[X] " + name +" | (408) Request timed out!")
elif r_ct in ["text/html"]:
print(Fore.RED + "[X] " + name +" | Returned HTML page!")
else:
print(Fore.RED + "[X] " + name +" | (" + str(r_sc) + ") Problem!")
#Starting inspection and downloading process
open(font_name + "/" + font_name + "-Links.txt", "w").write("")
for j in range(len(formats)):
if not os.path.exists(font_name + "/" + formats[j]):
os.makedirs(font_name + "/" + formats[j])
#Checking and downloading links that were generated before
start_time = time.time_ns()
for i in range(len(links)):
dl(links[i], links_format[i])
end_time = time.time_ns()
#Counting processing time
processing_time = (end_time - start_time) / (10**9)
pt_min, pt_sec = divmod(processing_time, 60)
pt_sec = round(pt_sec, 2)
#Removing extra empty lines in Links.txt file
l_text = open(font_name + "/" + font_name + "-Links.txt", "r").read().rstrip()
open(font_name + "/" + font_name + "-Links.txt", "w").write(l_text)
#Removing empty font format folders
for j in range(len(formats)):
if not os.listdir(font_name + "/" + formats[j]):
os.rmdir(font_name + "/" + formats[j])
#Showing results
print(Fore.YELLOW + "\n[!] Results:")
if pt_min == 0:
print(Fore.CYAN + "[!] Processing time: " + Fore.YELLOW + str(pt_sec) + " seconds")
else:
print(Fore.CYAN + "[!] Processing time: " + Fore.YELLOW + str(int(pt_min)) + " minutes and " + str(pt_sec) + " seconds")
print(Fore.CYAN + "[!] Downloaded: " + Fore.YELLOW + str(count) + " files")
print(Fore.CYAN + "[!] Inspected: " + Fore.YELLOW + str(len(links)) + " files")