-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
140 lines (105 loc) · 4.01 KB
/
utils.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
from PIL import ImageFont, Image, ImageDraw
from pathlib import Path
from dataclasses import dataclass
import requests
import logging
from datetime import timedelta
from constants import *
@dataclass
class Block:
width: int
height: int
paste_coord: tuple[int, int]
def as_tuple(self) -> tuple[int, int]:
return (self.width, self.height)
def __str__(self):
return f"width={self.width} height={self.height}"
def find_best_text_size(text: str, max_width: int, max_height: int):
"""Find the largest text size that fit in the given limit
Args:
text (str): text to be checked
max_width (int): maximum width of the text
max_height (int): maximum height of the text
Returns:
image font
"""
font_size = 10
font = ImageFont.truetype(FONT_DIR, font_size)
while True:
max_line_width, total_height = get_text_size(text, font)
if max_line_width < max_width and total_height < max_height:
font_size += 10
font = ImageFont.truetype(FONT_DIR, font_size)
else:
break
if font_size > 1000:
print("reach max font size")
break
return ImageFont.truetype(FONT_DIR, font_size - 10)
def fetch(url: str, des: str) -> dict:
try:
response = requests.get(url)
response.raise_for_status()
logging.info(f"{des} fetched successfully.")
return response.json()
except requests.RequestException as e:
logging.error(f"Failed to fetch {des}: {e}")
raise
def get_icon(path: Path, size: tuple[int, int]) -> Image.Image:
icon = Image.open(path)
icon.thumbnail(size)
return icon
def timedelta_to_hours(td: timedelta) -> int:
""" get the number of hours between the time difference
"""
return int(td.total_seconds() // 3600)
def center_text(txt: str, block_size: tuple[int, int], font) -> tuple[int, int]:
"""calculate the offsets for centering the text
"""
width, height = get_text_size(txt, font)
x_offset = int((block_size[0] - width) // 2)
y_offset = int((block_size[1] - height) // 2)
return x_offset, y_offset
def center_image(icon: Image.Image, block_size: tuple[int, int]) -> tuple[int, int]:
"""calculate the offsets for centering the image
"""
return int((block_size[0] - icon.width) // 2), int((block_size[1] - icon.height) // 2),
def get_center_coord(content: str | Image.Image, block_size: tuple[int, int], old_coord: tuple[int, int],**kwargs) -> tuple[int, int]:
"""get the new coord to paste the content at the center of block
Args:
content (str | Image.Image): content to put in the block
block_size (tuple[int, int]): the size of the block for the content
old_coord (tuple[int, int]): old coordintes to paste the content
Raises:
TypeError: Not implemented type of content
Returns:
tuple[int, int]: new coordinates
"""
if isinstance(content, str):
x_off, y_off = center_text(content, block_size, **kwargs)
elif isinstance(content, Image.Image):
x_off, y_off = center_image(content, block_size, **kwargs)
else:
raise TypeError(f"Unknown type {type(content)=}")
return (old_coord[0] + x_off, old_coord[1] + y_off)
def get_text_size(txt: str, font) -> tuple[int, int]:
"""return the max width and height of the given text
Args:
txt (str): text can be one line or multiple line
font (_type_): font used
Returns:
tuple[int, int]: max width, total height
"""
lines = txt.split("\n")
total_height = sum(font.getsize(line)[1] for line in lines)
max_line_width = max(font.getsize(line)[0] for line in lines)
return (max_line_width, total_height)
def draw_text_at_center(draw: ImageDraw.ImageDraw, txt: str, font, block_size: tuple[int, int], xy: tuple[int, int]):
draw.text(
get_center_coord(
txt, block_size, xy, font=font
),
txt,
fill="black",
font=font,
)