Skip to content

Commit

Permalink
Update to version v1.14.1
Browse files Browse the repository at this point in the history
Add features to Tinted Frame card, many other changes and fixes
  • Loading branch information
CollinHeist authored Jun 17, 2023
2 parents d43884f + 68b5522 commit 51e4ef2
Show file tree
Hide file tree
Showing 59 changed files with 1,388 additions and 1,253 deletions.
11 changes: 8 additions & 3 deletions .dockerignore
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ config/
fonts/
logs/
source/
cards/
archives/
title_cards/
docs/
yml/
yaml/
app/title_cards/
.DS_Store
.git
.github
Expand All @@ -11,6 +18,4 @@ source/
README.md
LICENSE
Dockerfile
._*
*.yml
*.yaml
._*
1 change: 1 addition & 0 deletions .github/workflows/discord_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ jobs:
webhook_token: ${{ secrets.RELEASE_WEBHOOK_TOKEN }}
release: true
title: TitleCardMaker VERSION
message: "<@&1111000623261958234> - A new version of TitleCardMaker has been released."
username: MakerBot
avatar_url: https://raw.githubusercontent.com/CollinHeist/TitleCardMaker/master/.github/logo.png
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Below are some examples of each style of title card that can be created automati
### Built-in Card Types
<img alt="Anime" src="https://user-images.githubusercontent.com/17693271/185820454-4e3dca1c-c0df-4fa0-a7a7-81e070aa9e69.jpg" height="150"/> <img alt="Cutout" src="https://user-images.githubusercontent.com/17693271/212500535-e88daff6-ecc0-4cc8-8627-82069114c7e0.jpg" height="150"/> <img alt="Divider" src="https://user-images.githubusercontent.com/17693271/232378485-a9a737dc-9faf-47c2-b639-7df3d3ffb194.jpg" height="150"> <img alt="Fade" src="https://user-images.githubusercontent.com/17693271/214648223-b4f68553-e982-4efa-a16b-9662018b5d40.jpg" height="150"/> <img alt="Frame" src="https://user-images.githubusercontent.com/17693271/202352614-155a176a-fdb0-4476-9f11-6a3a20533a54.jpg" height="150"/> <img alt="Landscape" src="https://user-images.githubusercontent.com/17693271/202352137-b411da21-65ce-4bed-991b-90428c71ec34.jpg" height="150"/> <img alt="Logo" src="https://user-images.githubusercontent.com/17693271/172227163-0ee4990a-b0a8-4dbd-91b3-3f57dfe6e732.jpg" height="150"/> <img alt="Olivier" src="https://user-images.githubusercontent.com/17693271/212500009-067f14ff-4f48-4f75-bacd-7311a9aba716.jpg" height="150"/> <img alt="Poster" src="https://user-images.githubusercontent.com/17693271/180627387-f72bb58e-e001-4608-b4be-82a26263c628.jpg" height="150"/> <img alt="Roman" src="https://user-images.githubusercontent.com/17693271/203910966-4dde1466-6c7e-4422-923b-1f9222ad49e9.jpg" height="150"/> <img alt="Standard" src="https://user-images.githubusercontent.com/17693271/212500240-ae946f2c-a5c8-4881-85f2-83ccb45bf46e.jpg" height="150"/> <img alt="Star Wars" src="https://user-images.githubusercontent.com/17693271/170836059-136fa6eb-40ef-4cd7-9aca-8ad8e0537239.jpg" height="150"> <img alt="tinted Frame" src="https://user-images.githubusercontent.com/17693271/233257029-8b17ce2e-01ea-4ae3-bc73-54e152be4d31.jpg" height="150"> <img alt="Tinted Glass" src="https://user-images.githubusercontent.com/17693271/213939482-6018b2be-28c5-42dd-988d-d7b9733fe0e8.jpg" height="150">

> The above cards are, in order, the [anime](https://github.com/CollinHeist/TitleCardMaker/wiki/AnimeTitleCard), [cutout](https://github.com/CollinHeist/TitleCardMaker/wiki/CutoutTitleCard), [divider](https://github.com/CollinHeist/TitleCardMaker/wiki/DividerTitleCard) [fade](https://github.com/CollinHeist/TitleCardMaker/wiki/FadeTitleCard), [frame](https://github.com/CollinHeist/TitleCardMaker/wiki/FrameTitleCard), [landscape](https://github.com/CollinHeist/TitleCardMaker/wiki/LandscapeTitleCard), [logo](https://github.com/CollinHeist/TitleCardMaker/wiki/LogoTitleCard), [olivier](https://github.com/CollinHeist/TitleCardMaker/wiki/OlivierTitleCard), [poster](https://github.com/CollinHeist/TitleCardMaker/wiki/PosterTitleCard), [roman](https://github.com/CollinHeist/TitleCardMaker/wiki/RomanNumeralTitleCard), [standard](https://github.com/CollinHeist/TitleCardMaker/wiki/StandardTitleCard), [star wars](https://github.com/CollinHeist/TitleCardMaker/wiki/StarWarsTitleCard), [tinted frame](https://github.com/CollinHeist/TitleCardMaker/wiki/TintedFrameTitleCard), and the [tinted glass](https://github.com/CollinHeist/TitleCardMaker/wiki/TintedGlassTitleCard) title cards - the [textless](https://github.com/CollinHeist/TitleCardMaker/wiki/TitleCard) card is not shown.
> The above cards are, in order, the [anime](https://github.com/CollinHeist/TitleCardMaker/wiki/AnimeTitleCard), [cutout](https://github.com/CollinHeist/TitleCardMaker/wiki/CutoutTitleCard), [divider](https://github.com/CollinHeist/TitleCardMaker/wiki/DividerTitleCard), [fade](https://github.com/CollinHeist/TitleCardMaker/wiki/FadeTitleCard), [frame](https://github.com/CollinHeist/TitleCardMaker/wiki/FrameTitleCard), [landscape](https://github.com/CollinHeist/TitleCardMaker/wiki/LandscapeTitleCard), [logo](https://github.com/CollinHeist/TitleCardMaker/wiki/LogoTitleCard), [olivier](https://github.com/CollinHeist/TitleCardMaker/wiki/OlivierTitleCard), [poster](https://github.com/CollinHeist/TitleCardMaker/wiki/PosterTitleCard), [roman](https://github.com/CollinHeist/TitleCardMaker/wiki/RomanNumeralTitleCard), [standard](https://github.com/CollinHeist/TitleCardMaker/wiki/StandardTitleCard), [star wars](https://github.com/CollinHeist/TitleCardMaker/wiki/StarWarsTitleCard), [tinted frame](https://github.com/CollinHeist/TitleCardMaker/wiki/TintedFrameTitleCard), and the [tinted glass](https://github.com/CollinHeist/TitleCardMaker/wiki/TintedGlassTitleCard) title cards - the [textless](https://github.com/CollinHeist/TitleCardMaker/wiki/TitleCard) card is not shown.

<details><summary><h3>User-Created Card Types</h3></summary>

Expand Down
30 changes: 21 additions & 9 deletions fixer.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,16 @@ class Episode:
spoil_type: str

# Create MediaServer Interface
if args.media_server == 'emby':
media_interface = EmbyInterface(**pp.emby_interface_kwargs)
elif args.media_server == 'jellyfin':
media_interface = JellyfinInterface(**pp.jellyfin_interface_kwargs)
else:
media_interface = PlexInterface(**pp.plex_interface_kwargs)
try:
if args.media_server == 'emby':
media_interface = EmbyInterface(**pp.emby_interface_kwargs)
elif args.media_server == 'jellyfin':
media_interface = JellyfinInterface(**pp.jellyfin_interface_kwargs)
else:
media_interface = PlexInterface(**pp.plex_interface_kwargs)
except Exception as e:
log.critical(f'Cannot connect to "{args.media_server}" Media Server')
exit(1)

# Get series/name + year from archive directory if unspecified
if hasattr(args, 'import_cards'):
Expand All @@ -228,13 +232,14 @@ class Episode:
archive = pp.source_directory / series_info.full_clean_name
library = args.revert_series[0]

# Get series ID's if provided
# Get series database ID's
if args.id:
for id_type, id_ in args.id:
try:
getattr(series_info, f'set_{id_type}_id')(id_)
except Exception as e:
log.error(f'Unrecognized ID type "{id_type}" - {e}')
media_interface.set_series_ids(library, series_info)

# Forget cards associated with this series
media_interface.remove_records(library, series_info)
Expand All @@ -246,7 +251,7 @@ class Episode:
exit(1)

# For each image, fill out episode map to load into server
episode_map = {}
episode_infos, episode_map = [], {}
for image in all_images:
if (groups := match(r'.*s(\d+).*e(\d+)', image.name, IGNORECASE)):
season, episode = map(int, groups.groups())
Expand All @@ -255,9 +260,16 @@ class Episode:
continue

# Import image into library
ep = Episode(image, EpisodeInfo('', season, episode), 'spoiled')
episode_infos.append((episode_info := EpisodeInfo('', season, episode)))
ep = Episode(image, episode_info, 'spoiled')
episode_map[f'{season}-{episode}'] = ep

# Set EpisodeInfo database ID's
media_interface.set_episode_ids(
library_name=library, series_info=series_info,
episode_infos=episode_infos, inplace=True
)

# Load images into server
media_interface.set_title_cards(library, series_info, episode_map)

Expand Down
3 changes: 2 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ def check_for_update():
except Exception:
log.debug(f'Failed to check for new version')
else:
if (available_version := response.json().get('name')) != pp.version:
available_version = response.json().get('name', '').strip()
if available_version != pp.version:
log.info(f'New version of TitleCardMaker ({available_version}) '
f'available')
if is_docker:
Expand Down
20 changes: 16 additions & 4 deletions mini_maker.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,16 @@
season_poster_group.add_argument(
'--season-poster',
type=Path,
nargs=3,
nargs=2,
default=SUPPRESS,
metavar=('SOURCE', 'LOGO', 'DESTINATION'),
metavar=('SOURCE', 'DESTINATION'),
help='Create a season poster with the given assets')
season_poster_group.add_argument(
'--season-poster-logo',
type=Path,
default=SUPPRESS,
metavar='LOGO',
help='Add the given logo to the created season poster')
season_poster_group.add_argument(
'--season-text',
type=str,
Expand Down Expand Up @@ -550,15 +556,21 @@ class Show:

# Create season posters
if hasattr(args, 'season_poster'):
if hasattr(args, 'season_poster_logo'):
logo = args.season_poster_logo
else:
logo = None

SeasonPoster(
source=args.season_poster[0],
logo=args.season_poster[1],
destination=args.season_poster[2],
destination=args.season_poster[1],
logo=logo,
season_text=args.season_text,
font=args.season_font,
font_color=args.season_font_color,
font_size=float(args.season_font_size[:-1])/100.0,
font_kerning=float(args.season_font_kerning[:-1])/100.0,
top_placement=args.top_placement,
omit_gradient=args.no_gradient,
omit_logo=not hasattr(args, 'season_poster_logo'),
).create()
13 changes: 12 additions & 1 deletion modules/BaseCardType.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def USES_SEASON_TITLE(self) -> bool:
def __init__(self,
blur: bool = False,
grayscale: bool = False, *,
preferences: Optional['Preferences'] = None) -> None:
preferences: Optional['Preferences'] = None) -> None: # type: ignore
"""
Construct a new CardType. Must call super().__init__() to
initialize the parent ImageMaker class (for PreferenceParser and
Expand Down Expand Up @@ -190,6 +190,8 @@ def resize(self) -> ImageMagickCommands:
"""

return [
# Use 4:4:4 sampling by default
f'-sampling-factor 4:4:4',
# Full sRGB colorspace on source image
f'-set colorspace sRGB',
# Ignore profile conversion warnings
Expand All @@ -213,6 +215,8 @@ def style(self) -> ImageMagickCommands:
"""

return [
# Use 4:4:4 sampling by default
f'-sampling-factor 4:4:4',
# Full sRGB colorspace on source image
f'-set colorspace sRGB',
# Ignore profile conversion warnings
Expand All @@ -237,6 +241,8 @@ def resize_and_style(self) -> ImageMagickCommands:
"""

return [
# Use 4:4:4 sampling by default
f'-sampling-factor 4:4:4',
# Full sRGB colorspace on source image
f'-set colorspace sRGB',
# Ignore profile conversion warnings
Expand Down Expand Up @@ -267,6 +273,11 @@ def resize_output(self) -> ImageMagickCommands:
"""

return [
f'-sampling-factor 4:4:4',
f'-set colorspace sRGB',
f'+profile "*"',
f'-background transparent',
f'-gravity center',
f'-resize "{self.preferences.card_dimensions}"',
f'-extent "{self.preferences.card_dimensions}"',
]
Expand Down
5 changes: 3 additions & 2 deletions modules/BaseSummary.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from math import ceil
from pathlib import Path
from random import sample
from typing import Optional

from modules.Debug import log
from modules.ImageMaker import ImageMaker
Expand Down Expand Up @@ -35,7 +36,7 @@ class BaseSummary(ImageMaker):


@abstractmethod
def __init__(self, show: 'Show', created_by: str=None) -> None:
def __init__(self, show: 'Show', created_by: Optional[str] = None) -> None:
"""
Initialize this object.
Expand Down Expand Up @@ -65,7 +66,7 @@ def __init__(self, show: 'Show', created_by: str=None) -> None:
self.number_rows = 0


def _select_images(self, maximum_images: int=9) -> bool:
def _select_images(self, maximum_images: int = 9) -> bool:
"""
Select the images that are to be incorporated into the show
summary. This updates the object's inputs and number_rows
Expand Down
1 change: 0 additions & 1 deletion modules/CleanPath.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ def sanitize(self) -> 'CleanPath':
finalized_path = self.finalize()
# If path resolution raises an error, clean and then re-resolve
except Exception as e:
log.exception(f'Error finalizing "{self}"', e)
finalized_path =self._sanitize_parts(CleanPath.cwd()/self).resolve()

return self._sanitize_parts(finalized_path)
5 changes: 3 additions & 2 deletions modules/DataFileInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from modules.Debug import log
from modules.EpisodeInfo import EpisodeInfo
from modules.SeriesInfo import SeriesInfo
import modules.global_objects as global_objects
from modules.Title import Title

Expand All @@ -18,7 +19,7 @@ class DataFileInterface:
GENERIC_DATA_FILE_NAME = 'data.yml'


def __init__(self, series_info: 'SeriesInfo', data_file: Path) -> None:
def __init__(self, series_info: SeriesInfo, data_file: Path) -> None:
"""
Constructs a new instance of the interface for the specified
data file. This also creates the parent directories for the data
Expand Down Expand Up @@ -223,7 +224,7 @@ def add_data_to_entry(self, episode_info: EpisodeInfo,
self.__write_data(yaml)


def add_many_entries(self, new_episodes: Iterable['EpisodeInfo']) -> None:
def add_many_entries(self, new_episodes: Iterable[EpisodeInfo]) -> None:
"""
Adds many entries at once. This only reads and writes from this
interface's file once.
Expand Down
13 changes: 9 additions & 4 deletions modules/DatabaseInfoContainer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from abc import ABC
from typing import Any, Optional
from typing import Any, Callable, Optional

from modules.Debug import log

Expand All @@ -11,8 +11,10 @@ class DatabaseInfoContainer(ABC):
within an objct.
"""

def _update_attribute(self, attribute: str, value: Any,
type_: Optional[callable] = None) -> None:
def _update_attribute(self,
attribute: str,
value: Any,
type_: Optional[Callable] = None) -> None:
"""
Set the given attribute to the given value with the given type.
Expand All @@ -23,7 +25,10 @@ def _update_attribute(self, attribute: str, value: Any,
"""

# Set attribute if current value is None and new value isn't
if getattr(self, attribute) is None and value is not None:
if (value is not None
and value != 0
and getattr(self, attribute) is None
and len(str(value)) > 0):
# If a type is defined, use that
if type_ is None:
setattr(self, attribute, value)
Expand Down
13 changes: 0 additions & 13 deletions modules/Debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,14 @@ def exception(self, msg: object, excpt: Exception, *args, **kwargs) -> None:

# StreamHandler to integrate log messages with TQDM
class LogHandler(StreamHandler):
def __init__(self, level=NOTSET):
super().__init__(level)
self.__just_logged = []

def emit(self, record):
# Skip if logged recently and not at least an error
if record.levelno < ERROR and record.msg in self.__just_logged:
return None

# Write after flushing buffer to integrate with tqdm
try:
tqdm.write(self.format(record))
self.flush()
except Exception:
self.handleError(record)

# Add to just logged list, keep list below 5 entries
self.__just_logged.append(record.msg)
if len(self.__just_logged) > 5:
self.__just_logged.pop(0)


# Formatter classes to handle exceptions
class ErrorFormatterColor(Formatter):
Expand Down
Loading

0 comments on commit 51e4ef2

Please sign in to comment.