Skip to content

Commit

Permalink
get everything ready for release
Browse files Browse the repository at this point in the history
  • Loading branch information
jorisschellekens committed Jun 16, 2024
1 parent 890961d commit ff03f8b
Show file tree
Hide file tree
Showing 56 changed files with 371 additions and 43 deletions.
2 changes: 1 addition & 1 deletion borb/license/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ def get_version() -> str:
This function returns the current borb version
:return: the current borb version
"""
return "2.1.23"
return "2.1.24"
3 changes: 3 additions & 0 deletions borb/pdf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
from .canvas.color.color import X11Color
from .canvas.color.farrow_and_ball import FarrowAndBall
from .canvas.color.pantone import Pantone
from .canvas.font.google_true_type_font import GoogleTrueTypeFont
from .canvas.font.simple_font.font_type_1 import StandardType1Font
from .canvas.font.simple_font.true_type_font import TrueTypeFont
from .canvas.layout.annotation.annotation import Annotation
from .canvas.layout.annotation.caret_annotation import CaretAnnotation
from .canvas.layout.annotation.circle_annotation import CircleAnnotation
Expand Down
105 changes: 105 additions & 0 deletions borb/pdf/canvas/font/google_true_type_font.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
The TrueType font format was developed by Apple Computer, Inc., and has been adopted as a standard font
format for the Microsoft Windows operating system. Specifications for the TrueType font file format are
available in Apple’s TrueType Reference Manual and Microsoft’s TrueType 1.0 Font Files Technical
Specification (see Bibliography).
"""
import json
import os
import tempfile
import typing
import pathlib

import requests

from borb.pdf.canvas.font.simple_font.true_type_font import TrueTypeFont


class GoogleTrueTypeFont(TrueTypeFont):
"""
A TrueType font dictionary may contain the same entries as a Type 1 font dictionary (see Table 111), with these
differences:
• The value of Subtype shall be TrueType.
• The value of Encoding is subject to limitations that are described in 9.6.6, "Character Encoding".
• The value of BaseFont is derived differently. The PostScript name for the value of BaseFont may be determined in one of two ways:
• If the TrueType font program's “name” table contains a PostScript name, it shall be used.
• In the absence of such an entry in the “name” table, a PostScript name shall be derived from the name by
which the font is known in the host operating system. On a Windows system, the name shall be based on
the lfFaceName field in a LOGFONT structure; in the Mac OS, it shall be based on the name of the FOND
resource. If the name contains any SPACEs, the SPACEs shall be removed.
"""

#
# CONSTRUCTOR
#

#
# PRIVATE
#

@staticmethod
def _download_google_font(font_name: str) -> pathlib.Path:

# get GOOGLE_FONTS_API_KEY
google_fonts_api_key: typing.Optional[str] = os.environ.get(
"GOOGLE_FONTS_API_KEY"
)
assert (
google_fonts_api_key is not None
), "GOOGLE_FONTS_API_KEY not found in os.environ"

# download overview
try:

# list all items
items: typing.List[typing.Dict] = json.loads(
requests.get(
f"https://www.googleapis.com/webfonts/v1/webfonts?key={google_fonts_api_key}"
).content
).get("items", [])

# find matching font_info_dictionary
font_info_dictionary: typing.Dict[str, typing.Any] = next(
iter([x for x in items if x.get("family", None) == font_name]), None
)
assert font_info_dictionary is not None, f"Unable to find font {font_name}"

# get URL
true_type_font_file_url: typing.Optional[str] = font_info_dictionary.get(
"files", {}
).get("regular", None)
assert (
true_type_font_file_url is not None
), f"Unable to find URL for font {font_name}"

# download to temporary file
temp_font_file: pathlib.Path = pathlib.Path(tempfile.NamedTemporaryFile(suffix=".ttf").name)
with open(temp_font_file, "wb") as fh:
fh.write(requests.get(true_type_font_file_url).content)

# return
return temp_font_file
except:
assert False, f"Unable to process font {font_name}"

#
# PUBLIC
#

@staticmethod
def true_type_font_from_google(
font_name: str,
) -> typing.Union["TrueTypeFont", "Type0Font"]:
"""
This function returns the PDF TrueTypeFont object for a given font name.
It does so by looking up the font using the Google Fonts API,
downloading the font to a temporary file,
and subsequently loading that temporary file using TrueTypeFont.true_type_font_from_file
:param font_name: the font name
:return: a TrueTypeFont or Type0Font
"""
return TrueTypeFont.true_type_font_from_file(
GoogleTrueTypeFont._download_google_font(font_name)
)
14 changes: 6 additions & 8 deletions borb/pdf/canvas/layout/image/unsplash.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

import json
import os
import typing
import urllib.request
from decimal import Decimal
Expand Down Expand Up @@ -52,14 +53,11 @@ def get_image(
# build keyword str
keyword_str: str = "".join([(k + "+") for k in keywords])[:-1]

# get access_key
import keyring # type: ignore[import]

keyring.get_keyring()
unsplash_access_key: typing.Optional[str] = keyring.get_password(
"unsplash", "access_key"
)
assert unsplash_access_key is not None
# get UNSPLASH_API_KEY
unsplash_access_key: typing.Optional[str] = os.environ.get("UNSPLASH_API_KEY")
assert (
unsplash_access_key is not None
), "UNSPLASH_API_KEY not found in os.environ"

# fetch json
min_delta: typing.Optional[Decimal] = None
Expand Down
19 changes: 12 additions & 7 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@

# :mega: borb release notes

This release features `A4PortraitResumeTemplate` which offers a convenient way of making a resume.
This release features `GoogleTrueTypeFont` which enables users to access the Google Font API,
to directly use a `TrueTypeFont` in `borb` by specifying its name.

Tests have been added for this feature:

- `test_add_paragraphs_using_jacquard_12`
- `test_add_paragraphs_using_pacifico`
- `test_add_paragraphs_using_shadows_into_light`

Some tests have been added to guard code quality:

- `TestCodeFilesAreSmall`
- `TestCodeFilesContainVisibilityCommentBlocks`
- `TestCodeFilesStartWithPythonBash`
- `TestCodeFilesUseFullyQualifiedBorbImports`
- `TestCodeFilesUseKnownExternalImports`
- `TestCodeFilesUseSingleLineImports`
- `TestCodeFilesContainSortedMethods`
- `TestCodeFilesContainVisibilityComments`
- `TestCodeFilesDoNotContainNumbersInMethods`
- `TestCodeFilesNeverUseKeyring`
11 changes: 0 additions & 11 deletions tests/borb_secrets.py

This file was deleted.

6 changes: 3 additions & 3 deletions tests/license/artifacts_test_register_license/license.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"anonymous_user_id": "Joris Schellekens",
"company": "borb (EZ)",
"valid_from_as_str": "2024-05-04 00:35:59",
"valid_until_as_str": "2024-05-11 00:35:59",
"license_key": "P5yPQlUVr8ub0/TdH5vS+FGl3FGM3ZtBXQkWT6vQm4lQIE+jQjGf/ZMd8nACHAtfAL7JLC5PoPMAgvBPuj8RhxW7E8k3aG2bQVqG8pvQajl/o+hXpAv8Nlh4h/Ug3YNDnfxQBxACNdQnhYOv1GOpsVbYkWvjppifTs9KiE+BOc4TxtlxVYFaBtb90HdOxpx00nbRORlkz9ID0/ZYMhXMaNo8BkXHC60orbnS05V03PbfjQswW/G+MJ7hBmhxouW4cxWdhrE1/ReIoqrDIkZvu6Wl7lrLIzyYbbSkpTykoCyQkHXCgnTstUwfeE1Ou4sZmbdSpeZEtu6UzBAWe52NVg=="
"valid_from_as_str": "2024-06-16 19:24:45",
"valid_until_as_str": "2024-06-23 19:24:45",
"license_key": "d3V8jPaCN7OPrLqmyTjnRWBQEs5fe1/NodIFf11Qq/LKVQHS58+5pkJ7wI2RlkIG27o6SlznCSuH9le5+O2Wn79UVGFxbWk0IrqIN8c5vWZlF8Jydd55UQcc5EXxyMzNxvVBSja7vcplUr6CB3yMjLTbJN9iM8QLTb0p7SBXjRqurT9+33VQLgGZeQBcsyEZnUTZW2CF5LqbB+fIGAyIG4CeCtp0mmsTx5LDwyGJnje/zFvk9qoMsLEyDJdPEWNTmWtSoz39nq4MpYuD/LEjB9NIXEgnxQgA9S5OGV+wvZxWlJlpMDZdXV57WjsN0ynVIFwVAsCvXIR+70eETxasEA=="
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
139 changes: 139 additions & 0 deletions tests/pdf/canvas/font/test_add_paragraphs_using_google_fonts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
from decimal import Decimal

from borb.pdf import Document
from borb.pdf import FixedColumnWidthTable
from borb.pdf import GoogleTrueTypeFont
from borb.pdf import PDF
from borb.pdf import Page
from borb.pdf import PageLayout
from borb.pdf import Paragraph
from borb.pdf import SingleColumnLayout
from borb.pdf import Table
from borb.pdf import TrueTypeFont
from tests.test_case import TestCase


class TestAddParagraphsUsingGoogleFonts(TestCase):
"""
This test loads a truetype _font from a .ttf file and attempts to use it to write 2 paragraphs of lorem ipsum.
"""

def _write_document_with_font(
self,
font_name: str,
) -> Document:

# create document
pdf = Document()

# add page
page = Page()
pdf.add_page(page)

# layout
layout: PageLayout = SingleColumnLayout(page)

# add test information
layout.add(
self.get_test_header(
f"This test loads {font_name} from a file and attempts to write letters and numbers with it."
)
)

# load font
ttf: TrueTypeFont = GoogleTrueTypeFont.true_type_font_from_google(font_name)

# add paragraph 1
uppercase_letter_table: Table = FixedColumnWidthTable(
number_of_columns=5, number_of_rows=6
)
for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
try:
uppercase_letter_table.add(Paragraph(c, font=ttf))
except:
uppercase_letter_table.add(Paragraph(""))
uppercase_letter_table.set_padding_on_all_cells(
Decimal(2), Decimal(2), Decimal(2), Decimal(2)
)
layout.add(Paragraph("Uppercase:"))
layout.add(uppercase_letter_table)

# lowercase
lowercase_letter_table: Table = FixedColumnWidthTable(
number_of_columns=5, number_of_rows=6
)
for c in "abcdefghijklmnopqrstuvwxyz":
try:
lowercase_letter_table.add(Paragraph(c, font=ttf))
except:
lowercase_letter_table.add(Paragraph(""))
lowercase_letter_table.set_padding_on_all_cells(
Decimal(2), Decimal(2), Decimal(2), Decimal(2)
)
layout.add(Paragraph("Lowercase:"))
layout.add(lowercase_letter_table)

# lowercase
digit_table: Table = FixedColumnWidthTable(
number_of_columns=5, number_of_rows=2
)
for c in "0123456789":
try:
digit_table.add(Paragraph(c, font=ttf))
except:
digit_table.add(Paragraph(""))
digit_table.set_padding_on_all_cells(
Decimal(2), Decimal(2), Decimal(2), Decimal(2)
)
layout.add(Paragraph("Digits:"))
layout.add(digit_table)

# return
return pdf

def test_add_paragraphs_using_jacquard_12(self):

# set GOOGLE_FONTS_API_KEY
try:
from tests.borb_secrets import populate_os_environ

populate_os_environ()
except:
pass

with open(self.get_first_output_file(), "wb") as in_file_handle:
PDF.dumps(in_file_handle, self._write_document_with_font("Jacquard 12"))
self.compare_visually_to_ground_truth(self.get_first_output_file())
self.check_pdf_using_validator(self.get_first_output_file())

def test_add_paragraphs_using_pacifico(self):

# set GOOGLE_FONTS_API_KEY
try:
from tests.borb_secrets import populate_os_environ

populate_os_environ()
except:
pass

with open(self.get_second_output_file(), "wb") as in_file_handle:
PDF.dumps(in_file_handle, self._write_document_with_font("Pacifico"))
self.compare_visually_to_ground_truth(self.get_second_output_file())
self.check_pdf_using_validator(self.get_second_output_file())

def test_add_paragraphs_using_shadows_into_light(self):

# set GOOGLE_FONTS_API_KEY
try:
from tests.borb_secrets import populate_os_environ

populate_os_environ()
except:
pass

with open(self.get_third_output_file(), "wb") as in_file_handle:
PDF.dumps(
in_file_handle, self._write_document_with_font("Shadows Into Light")
)
self.compare_visually_to_ground_truth(self.get_third_output_file())
self.check_pdf_using_validator(self.get_third_output_file())
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit ff03f8b

Please sign in to comment.