Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor code for V3 #34

Merged
merged 3 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ __pycache__/
build/
dist/
.idea/
.vscode/
.vscode/
venv/
51 changes: 25 additions & 26 deletions examples/collect_font_and_mux_them.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,54 @@
import sys
from font_collector import (
AssDocument,
Font,
FontCollection,
FontFile,
FontLoader,
Helpers,
FontSelectionStrategyLibass,
Mkvpropedit,
set_loglevel,
)
from pathlib import Path
from typing import List
from typing import List, Set

# If you don't want to get any log, set the loglevel to logging.CRITICAL
set_loglevel(logging.CRITICAL)


def main():
ass_path = "ASS_FILE_PATH.ass"
mkv_path = "MKV_FILE_PATH.ass"
ass_path = Path("ASS_FILE_PATH.ass")
mkv_path = Path("MKV_FILE_PATH.mkv")

# If you need additional fonts (font that aren't installed in the system), specify them in the additional_fonts_path
additional_fonts_path: List[Path] = []
font_collection = FontLoader(additional_fonts_path, use_system_font=True).fonts
additional_fonts = FontLoader.load_additional_fonts(additional_fonts_path)

subtitle = AssDocument.from_file(ass_path)
styles = subtitle.get_used_style()
# If you need additional fonts (font that aren't installed in the system), specify them in the additional_fonts
font_collection = FontCollection(additional_fonts=additional_fonts)
font_selection_strategy = FontSelectionStrategyLibass()

fonts_found: List[Font] = []
subtitle = AssDocument.from_file(ass_path) # if you have a object that represent the .ass file, you can also use ABCAssDocument
used_styles = subtitle.get_used_style()

for style, usage_data in styles.items():
fonts_file_found: Set[FontFile] = set()

font_result = Helpers.get_used_font_by_style(font_collection, style)

if font_result is None:
print(f"Could not find font '{style.fontname}'")
else:
print(f"Font found: {font_result.font.filename}")
fonts_found.append(font_result.font)
for style, usage_data in used_styles.items():
font_result = font_collection.get_used_font_by_style(style, font_selection_strategy)
if font_result:
family_name = font_result.font_face.get_best_family_name()
font_file = font_result.font_face.font_file
print(f"We found the family {family_name.value} at {font_file.filename}")
fonts_file_found.add(font_file)

# If you wanna verify if the font miss any glyph, use this
missing_glyphs = font_result.font.get_missing_glyphs(
usage_data.characters_used
)
missing_glyphs = font_result.font_face.get_missing_glyphs(usage_data.characters_used)
if len(missing_glyphs) != 0:
print(
f"'{style.fontname}' is missing the following glyphs: {missing_glyphs}"
)
print(f"'{family_name.value}' is missing the following glyphs: {missing_glyphs}")


# If the mkv already contain font, you can remove them
# If the mkv already contains font, you can remove them
Mkvpropedit.delete_fonts_of_mkv(mkv_path)

Mkvpropedit.merge_fonts_into_mkv(fonts_found, mkv_path)
Mkvpropedit.merge_fonts_into_mkv(fonts_file_found, mkv_path)


if __name__ == "__main__":
Expand Down
26 changes: 12 additions & 14 deletions font_collector/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import logging
from .ass_document import AssDocument
from .ass_style import AssStyle
from .exceptions import InvalidFontException, NameNotFoundException
from .font_loader import FontLoader
from .font_result import FontResult
from .font import Font
from .helpers import Helpers
from .mkvpropedit import Mkvpropedit
from .usage_data import UsageData
from ._version import __version__

# Packages
from .ass import *
from .font import *
from .system_lang import *
# Files
from .exceptions import *
from .mkvpropedit import *
from ._version import __version__
from fontTools.misc.loggingTools import configLogger

configLogger(level="ERROR")
configLogger(level="CRITICAL")

# Set our default logger
_logger = logging.getLogger(__name__)
Expand All @@ -27,10 +25,10 @@
_logger.addHandler(_handler)


def set_loglevel(level: int):
def set_loglevel(level: int) -> None:
"""
Parameters:
level (int): An level from logging module (For more detail, see: https://docs.python.org/3/library/logging.html#logging-levels)
Args:
level: An level from logging module (For more detail, see: https://docs.python.org/3/library/logging.html#logging-levels)
"""
_logger.setLevel(level)
_handler.setLevel(level)
96 changes: 53 additions & 43 deletions font_collector/__main__.py
Original file line number Diff line number Diff line change
@@ -1,90 +1,100 @@
import logging
import sys
from .ass_document import AssDocument
from .font import Font
from .font_loader import FontLoader
from .font_result import FontResult
from .helpers import Helpers
import shutil
from .ass.ass_document import AssDocument
from .font import FontCollection, FontFile, FontLoader, FontResult, FontSelectionStrategyLibass, VariableFontFace
from .mkvpropedit import Mkvpropedit
from .parse_arguments import parse_arguments
from typing import List
from pathlib import Path
from typing import List, Set


_logger = logging.getLogger(__name__)


def main():
def main() -> None:
(
ass_files_path,
output_directory,
mkv_path,
delete_fonts,
additional_fonts,
additional_fonts_recursive,
additional_fonts_path,
additional_fonts_recursive_path,
use_system_font,
collect_draw_fonts
collect_draw_fonts,
convert_variable_to_collection
) = parse_arguments()
font_results: List[FontResult] = []
font_collection = FontLoader(additional_fonts, use_system_font, additional_fonts_recursive).fonts
additional_fonts = FontLoader.load_additional_fonts(additional_fonts_path)
additional_fonts.extend(FontLoader.load_additional_fonts(additional_fonts_recursive_path, True))
font_collection = FontCollection(use_system_font=use_system_font, additional_fonts=additional_fonts)
font_strategy = FontSelectionStrategyLibass()

for ass_path in ass_files_path:
subtitle = AssDocument.from_file(ass_path)
_logger.info(f"Loaded successfully {ass_path}")
styles = subtitle.get_used_style(collect_draw_fonts)
used_styles = subtitle.get_used_style(collect_draw_fonts)

nbr_font_not_found = 0

for style, usage_data in styles.items():
for style, usage_data in used_styles.items():

font_result = Helpers.get_used_font_by_style(font_collection, style)
font_result = font_collection.get_used_font_by_style(style, font_strategy)

# Did not found the font
if font_result is None:
nbr_font_not_found += 1
_logger.error(
f"Used on lines: {' '.join(str(line) for line in usage_data.ordered_lines)}"
)
_logger.error(f"Could not find font '{style.fontname}'")
_logger.error(f"Used on lines: {' '.join(str(line) for line in usage_data.ordered_lines)}")
else:
font_results.append(font_result)

if font_result.mismatch_bold:
if font_result.need_faux_bold:
_logger.warning(f"Faux bold used for '{style.fontname}'.")
elif font_result.mismatch_bold:
_logger.warning(f"'{style.fontname}' does not have a bold variant.")
if font_result.mismatch_italic:
_logger.warning(
f"'{style.fontname}' does not have an italic variant."
)

if font_result.mismatch_bold or font_result.mismatch_italic:
_logger.warning(
f"Used on lines: {' '.join(str(line) for line in usage_data.ordered_lines)}"
)

if (
len(
missing_glyphs := font_result.font.get_missing_glyphs(
usage_data.characters_used
)
)
> 0
):
_logger.warning(
f"'{style.fontname}' is missing the following glyphs used: {missing_glyphs}"
)
_logger.warning(f"'{style.fontname}' does not have an italic variant.")

if font_result.need_faux_bold or font_result.mismatch_bold or font_result.mismatch_italic:
_logger.warning(f"Used on lines: {' '.join(str(line) for line in usage_data.ordered_lines)}")


missing_glyphs = font_result.font_face.get_missing_glyphs(usage_data.characters_used)
if len(missing_glyphs) > 0:
_logger.warning(f"'{style.fontname}' is missing the following glyphs used: {missing_glyphs}")

if nbr_font_not_found == 0:
_logger.info(f"All fonts found")
else:
_logger.info(f"{nbr_font_not_found} fonts could not be found.")

fonts_found: List[Font] = [font.font for font in font_results]
fonts_file_found: Set[FontFile] = set()

for font_result in font_results:
if font_result.font_face.font_file is None:
raise ValueError(f"This font_face \"{font_result.font_face}\" isn't linked to any FontFile.")

if convert_variable_to_collection and isinstance(font_result.font_face, VariableFontFace):
font_name = font_result.font_face.get_best_family_prefix_from_lang().value
font_filename = output_directory.joinpath(f"{font_name}.ttc")
generated_font_file = font_result.font_face.variable_font_to_collection(font_filename)
fonts_file_found.add(generated_font_file)
else:
fonts_file_found.add(font_result.font_face.font_file)

if mkv_path is not None:
if delete_fonts:
Mkvpropedit.delete_fonts_of_mkv(mkv_path)
Mkvpropedit.merge_fonts_into_mkv(fonts_found, mkv_path)
Mkvpropedit.merge_fonts_into_mkv(fonts_file_found, mkv_path)
else:
Helpers.copy_font_to_directory(fonts_found, output_directory)
if not output_directory.is_dir():
output_directory.mkdir()

for font in fonts_file_found:
font_filename = output_directory.joinpath(font.filename.resolve().name)
# Don't overwrite fonts
if not font_filename.is_file():
shutil.copy(font.filename, font_filename)

if __name__ == "__main__":
sys.exit(main())
main()
4 changes: 4 additions & 0 deletions font_collector/ass/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .abc_ass_document import *
from .ass_document import *
from .ass_style import *
from .usage_data import *
Loading
Loading