aboutsummaryrefslogtreecommitdiff
path: root/savewebfonts_lib.py
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2021-04-04 22:29:18 -0400
committerB. Stack <bgstack15@gmail.com>2021-04-04 22:29:18 -0400
commitd1d92930f8554c9ff9a6aa199cc2b429fd171958 (patch)
tree5ad1167e322c0f6c0158f45ec87904452953e88c /savewebfonts_lib.py
parentadd a default config, which uses dryrun=True (diff)
downloadsave-webfonts-d1d92930f8554c9ff9a6aa199cc2b429fd171958.tar.gz
save-webfonts-d1d92930f8554c9ff9a6aa199cc2b429fd171958.tar.bz2
save-webfonts-d1d92930f8554c9ff9a6aa199cc2b429fd171958.zip
add support for fonts inline in css as url data:
The handler parses the first data value and has support for only one exact entry, but it can be adapted for more.
Diffstat (limited to 'savewebfonts_lib.py')
-rwxr-xr-xsavewebfonts_lib.py111
1 files changed, 72 insertions, 39 deletions
diff --git a/savewebfonts_lib.py b/savewebfonts_lib.py
index 53615c1..b0a6f30 100755
--- a/savewebfonts_lib.py
+++ b/savewebfonts_lib.py
@@ -17,7 +17,7 @@
# req-devuan: python3-bs4, python3-tinycss2
# rec-devuan: python3-fonttools, eot2ttf
-import requests, os, json, tempfile, subprocess
+import requests, os, json, tempfile, subprocess, base64
from sys import stderr
from bs4 import BeautifulSoup as bs # python3-beautifulsoup4
from urllib.parse import urljoin, urlparse
@@ -138,61 +138,88 @@ def save_font(url,destdir,config):
filename=""
filename=os.path.basename(urlparse(url).path)
ext = os.path.splitext(filename)[-1]
+ tf = None
# Do not try to convert .svg
if config.convert and not filename.endswith(".ttf") and ext not in [".svg"]:
need_convert = True
orig_filename = filename # in case we cannot load library later
filename = ttfify_filename(filename)
+
+ if url.startswith("data:"):
+ if url.startswith("data:application/x-font-woff;charset=utf-8;base64,"):
+ need_convert = True
+ ext = ".woff"
+ tf = tempfile.NamedTemporaryFile()
+ contents = url[len("data:application/x-font-woff;charset=utf-8;base64,"):] # no worries about dryrun; we have already downloaded the font contents which are inline in the css file itself.
+ tf.write(base64.b64decode(contents))
+ filename = ttfify_filename(contents[:20])
+
filepath = os.path.join(destdir, filename)
if not os.path.exists(filepath):
if url.startswith("data:"):
- # not supported!
- # WORKHERE: support saving to a tempfile this datastream, probably a base64encoded woff file. Then just convert.
- eprint(f"Warning: Url {url[:config.MAX_STRING_PRINT_LENGTH]} is unsupported.")
- else:
- if not config.dryrun:
- # Download content
- response = config.session.get(url)
+ # Yes, some repetition here.
+ if url.startswith("data:application/x-font-woff;charset=utf-8;base64,"):
+ pass
+ else:
+ # not supported yet!
+ eprint(f"Warning: Url {url[:config.MAX_STRING_PRINT_LENGTH]} is unsupported.")
+ return -1
+ if not config.dryrun:
+ if tf:
+ with open(tf.name,'rb') as otf:
+ file_contents = otf.read()
+ else:
+ # Download content
+ response = config.session.get(url)
if 'Content-Disposition' in response.headers:
filename=response.headers['Content-Disposition']
eprint(f"Using content-disposition value of {response.headers['Content-Disposition']}")
if need_convert and not filename.endswith(".ttf"):
orig_filename = filename # in case we cannot load library later
filename = ttfify_filename(filename)
- filepath = os.path.join(destdir, filename)
-
- try:
- if config.debuglevel >= 1:
- sstring = "Saving" if not config.dryrun else "Save"
- eprint(f"{sstring} {url} to file {filepath}")
- if not config.dryrun:
- if not need_convert:
- with open(filepath,'wb') as thisfile:
- thisfile.write(response.content)
+ file_contents = response.content
+
+ filepath = os.path.join(destdir, filename)
+ #try:
+ if True:
+ if config.debuglevel >= 1:
+ sstring = "Saving" if not config.dryrun else "Save"
+ eprint(f"{sstring} {url[:config.MAX_STRING_PRINT_LENGTH]} to file {filepath}")
+ if not config.dryrun:
+ if not need_convert:
+ with open(filepath,'wb') as thisfile:
+ thisfile.write(file_contents)
+ else:
+ # need_convert is true, and not dryrun, so call function
+ if ext in [".woff",".woff2"]:
+ try:
+ from fontTools import ttLib
+ except Exception as e:
+ raise e
+ convert_in = url
+ if tf:
+ convert_in = tf.name
+ convert_woffwoff2_ttf(convert_in,filepath,config=config)
+ elif ext in [".eot"]:
+ convert_eot_ttf(url,filepath,config=config)
else:
- # need_convert is true, and not dryrun, so call function
- if ext in [".woff",".woff2"]:
- try:
- from fontTools import ttLib
- except Exception as e:
- raise e
- convert_woffwoff2_ttf(url,filepath,config=config)
- elif ext in [".eot"]:
- convert_eot_ttf(url,filepath,config=config)
- else:
- # no plan for conversion!
- eprint(f"Warning: no conversion plan for ext {ext} of {url}. Saving as-is.")
- with open(filepath,'wb') as thisfile:
- thisfile.write(response.content)
- return 0
- except Exception as E:
- eprint(f"Error when downloading {url}, {E}")
- return -1
+ # no plan for conversion!
+ eprint(f"Warning: no conversion plan for ext {ext} of {url[:config.MAX_STRING_PRINT_LENGTH]}. Saving as-is.")
+ with open(filepath,'wb') as thisfile:
+ thisfile.write(file_contents)
+ if tf: tf.close()
+ return 0
+ #except Exception as E:
+ # eprint(f"Error when downloading {url}, {E}")
+ # if tf: tf.close()
+ # return -1
+ if tf: tf.close()
else: # filepath does exist
if config.debuglevel >= 2:
- eprint(f"File {filepath} exists for {url}. Skipping.")
+ eprint(f"File {filepath} exists for {url[:config.MAX_STRING_PRINT_LENGTH]}. Skipping.")
+ if tf: tf.close()
return 0
def get_all_fonts_from_csslist(all_css, config):
@@ -294,7 +321,13 @@ def convert_woffwoff2_ttf(url, filename, config):
Save the given url to filename, with filetype ttf
"""
# This will only be called from save_font when dryrun=False, so the dryrun flag here is useful only if called from some other usage.
- response = config.session.get(url)
+ if (url.startswith("http://") or url.startswith("https://") or url.startswith("ftp://")):
+ response = config.session.get(url)
+ file_contents = response.content
+ else:
+ # assume local file
+ with open(url,'rb') as o:
+ file_contents = o.read()
try:
from fontTools import ttLib
except ModuleNotFoundError:
@@ -304,7 +337,7 @@ def convert_woffwoff2_ttf(url, filename, config):
raise e
with tempfile.TemporaryFile() as tf:
- tf.write(response.content)
+ tf.write(file_contents)
font = ttLib.TTFont(tf)
if config.debuglevel >= 3:
eprint(f"Converting {url[:config.MAX_STRING_PRINT_LENGTH]} from {font.flavor} to ttf as file {filename}")
bgstack15