Merge pull request #345 from aceinnolab/hotfix/#326
fix an issue where the text would not be vertically centered
This commit is contained in:
commit
90948d2d29
@ -8,17 +8,17 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
import PIL
|
|
||||||
import requests
|
import requests
|
||||||
import tzlocal
|
import tzlocal
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from PIL import ImageDraw
|
from PIL import ImageDraw
|
||||||
from PIL import ImageFont
|
from PIL import ImageFont
|
||||||
|
|
||||||
logs = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logs.setLevel(level=logging.INFO)
|
logger.setLevel(level=logging.INFO)
|
||||||
|
|
||||||
# Get the path to the Inkycal folder
|
# Get the path to the Inkycal folder
|
||||||
top_level = "/".join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))).split("/")[:-1])
|
top_level = "/".join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))).split("/")[:-1])
|
||||||
@ -39,7 +39,7 @@ for path, dirs, files in os.walk(fonts_location):
|
|||||||
if _.endswith(".ttf"):
|
if _.endswith(".ttf"):
|
||||||
name = _.split(".ttf")[0]
|
name = _.split(".ttf")[0]
|
||||||
fonts[name] = os.path.join(path, _)
|
fonts[name] = os.path.join(path, _)
|
||||||
logs.debug(f"Found fonts: {json.dumps(fonts, indent=4, sort_keys=True)}")
|
logger.debug(f"Found fonts: {json.dumps(fonts, indent=4, sort_keys=True)}")
|
||||||
available_fonts = [key for key, values in fonts.items()]
|
available_fonts = [key for key, values in fonts.items()]
|
||||||
|
|
||||||
|
|
||||||
@ -77,16 +77,16 @@ def get_system_tz() -> str:
|
|||||||
|
|
||||||
>>> import arrow
|
>>> import arrow
|
||||||
>>> print(arrow.now()) # returns non-timezone-aware time
|
>>> print(arrow.now()) # returns non-timezone-aware time
|
||||||
>>> print(arrow.now(tz=get_system_tz()) # prints timezone aware time.
|
>>> print(arrow.now(tz=get_system_tz())) # prints timezone aware time.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
local_tz = tzlocal.get_localzone().key
|
local_tz = tzlocal.get_localzone().key
|
||||||
logs.debug(f"Local system timezone is {local_tz}.")
|
logger.debug(f"Local system timezone is {local_tz}.")
|
||||||
except:
|
except:
|
||||||
logs.error("System timezone could not be parsed!")
|
logger.error("System timezone could not be parsed!")
|
||||||
logs.error("Please set timezone manually!. Falling back to UTC...")
|
logger.error("Please set timezone manually!. Falling back to UTC...")
|
||||||
local_tz = "UTC"
|
local_tz = "UTC"
|
||||||
logs.debug(f"The time is {arrow.now(tz=local_tz).format('YYYY-MM-DD HH:mm:ss ZZ')}.")
|
logger.debug(f"The time is {arrow.now(tz=local_tz).format('YYYY-MM-DD HH:mm:ss ZZ')}.")
|
||||||
return local_tz
|
return local_tz
|
||||||
|
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ def auto_fontsize(font, max_height):
|
|||||||
return font
|
return font
|
||||||
|
|
||||||
|
|
||||||
def write(image, xy, box_size, text, font=None, **kwargs):
|
def write(image: Image, xy: Tuple[int, int], box_size: Tuple[int, int], text: str, font=None, **kwargs):
|
||||||
"""Writes text on an image.
|
"""Writes text on an image.
|
||||||
|
|
||||||
Writes given text at given position on the specified image.
|
Writes given text at given position on the specified image.
|
||||||
@ -165,7 +165,7 @@ def write(image, xy, box_size, text, font=None, **kwargs):
|
|||||||
text_bbox = font.getbbox(text)
|
text_bbox = font.getbbox(text)
|
||||||
text_width = text_bbox[2] - text_bbox[0]
|
text_width = text_bbox[2] - text_bbox[0]
|
||||||
text_bbox_height = font.getbbox("hg")
|
text_bbox_height = font.getbbox("hg")
|
||||||
text_height = text_bbox_height[3] - text_bbox_height[1]
|
text_height = abs(text_bbox_height[3]) # - abs(text_bbox_height[1])
|
||||||
|
|
||||||
while text_width < int(box_width * fill_width) and text_height < int(box_height * fill_height):
|
while text_width < int(box_width * fill_width) and text_height < int(box_height * fill_height):
|
||||||
size += 1
|
size += 1
|
||||||
@ -173,23 +173,23 @@ def write(image, xy, box_size, text, font=None, **kwargs):
|
|||||||
text_bbox = font.getbbox(text)
|
text_bbox = font.getbbox(text)
|
||||||
text_width = text_bbox[2] - text_bbox[0]
|
text_width = text_bbox[2] - text_bbox[0]
|
||||||
text_bbox_height = font.getbbox("hg")
|
text_bbox_height = font.getbbox("hg")
|
||||||
text_height = text_bbox_height[3] - text_bbox_height[1]
|
text_height = abs(text_bbox_height[3]) # - abs(text_bbox_height[1])
|
||||||
|
|
||||||
text_bbox = font.getbbox(text)
|
text_bbox = font.getbbox(text)
|
||||||
text_width = text_bbox[2] - text_bbox[0]
|
text_width = text_bbox[2] - text_bbox[0]
|
||||||
text_bbox_height = font.getbbox("hg")
|
text_bbox_height = font.getbbox("hg")
|
||||||
text_height = text_bbox_height[3] - text_bbox_height[1]
|
text_height = abs(text_bbox_height[3]) # - abs(text_bbox_height[1])
|
||||||
|
|
||||||
# Truncate text if text is too long, so it can fit inside the box
|
# Truncate text if text is too long, so it can fit inside the box
|
||||||
if (text_width, text_height) > (box_width, box_height):
|
if (text_width, text_height) > (box_width, box_height):
|
||||||
logs.debug(("truncating {}".format(text)))
|
logger.debug(("truncating {}".format(text)))
|
||||||
while (text_width, text_height) > (box_width, box_height):
|
while (text_width, text_height) > (box_width, box_height):
|
||||||
text = text[0:-1]
|
text = text[0:-1]
|
||||||
text_bbox = font.getbbox(text)
|
text_bbox = font.getbbox(text)
|
||||||
text_width = text_bbox[2] - text_bbox[0]
|
text_width = text_bbox[2] - text_bbox[0]
|
||||||
text_bbox_height = font.getbbox("hg")
|
text_bbox_height = font.getbbox("hg")
|
||||||
text_height = text_bbox_height[3] - text_bbox_height[1]
|
text_height = abs(text_bbox_height[3]) # - abs(text_bbox_height[1])
|
||||||
logs.debug(text)
|
logger.debug(text)
|
||||||
|
|
||||||
# Align text to desired position
|
# Align text to desired position
|
||||||
if alignment == "center" or None:
|
if alignment == "center" or None:
|
||||||
@ -199,10 +199,13 @@ def write(image, xy, box_size, text, font=None, **kwargs):
|
|||||||
elif alignment == "right":
|
elif alignment == "right":
|
||||||
x = int(box_width - text_width)
|
x = int(box_width - text_width)
|
||||||
|
|
||||||
|
# Vertical centering
|
||||||
|
y = int((box_height / 2) - (text_height / 2))
|
||||||
|
|
||||||
# Draw the text in the text-box
|
# Draw the text in the text-box
|
||||||
draw = ImageDraw.Draw(image)
|
draw = ImageDraw.Draw(image)
|
||||||
space = Image.new('RGBA', (box_width, box_height))
|
space = Image.new('RGBA', (box_width, box_height))
|
||||||
ImageDraw.Draw(space).text((x, 0), text, fill=colour, font=font)
|
ImageDraw.Draw(space).text((x, y), text, fill=colour, font=font)
|
||||||
|
|
||||||
# Uncomment following two lines, comment out above two lines to show
|
# Uncomment following two lines, comment out above two lines to show
|
||||||
# red text-box with white text (debugging purposes)
|
# red text-box with white text (debugging purposes)
|
||||||
@ -217,7 +220,7 @@ def write(image, xy, box_size, text, font=None, **kwargs):
|
|||||||
image.paste(space, xy, space)
|
image.paste(space, xy, space)
|
||||||
|
|
||||||
|
|
||||||
def text_wrap(text, font=None, max_width=None):
|
def text_wrap(text: str, font=None, max_width=None):
|
||||||
"""Splits a very long text into smaller parts
|
"""Splits a very long text into smaller parts
|
||||||
|
|
||||||
Splits a long text to smaller lines which can fit in a line with max_width.
|
Splits a long text to smaller lines which can fit in a line with max_width.
|
||||||
@ -253,7 +256,7 @@ def text_wrap(text, font=None, max_width=None):
|
|||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
def internet_available():
|
def internet_available() -> bool:
|
||||||
"""checks if the internet is available.
|
"""checks if the internet is available.
|
||||||
|
|
||||||
Attempts to connect to google.com with a timeout of 5 seconds to check
|
Attempts to connect to google.com with a timeout of 5 seconds to check
|
||||||
@ -278,15 +281,16 @@ def internet_available():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def draw_border(image, xy, size, radius=5, thickness=1, shrinkage=(0.1, 0.1)):
|
def draw_border(image: Image, xy: Tuple[int, int], size: Tuple[int, int], radius: int = 5, thickness: int = 1,
|
||||||
|
shrinkage: Tuple[int, int] = (0.1, 0.1)) -> None:
|
||||||
"""Draws a border at given coordinates.
|
"""Draws a border at given coordinates.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
- image: The image on which the border should be drawn (usually im_black or
|
- image: The image on which the border should be drawn (usually im_black or
|
||||||
im_colour.
|
im_colour).
|
||||||
|
|
||||||
- xy: Tuple representing the top-left corner of the border e.g. (32, 100)
|
- xy: Tuple representing the top-left corner of the border e.g. (32, 100)
|
||||||
where 32 is the x co-ordinate and 100 is the y-coordinate.
|
where 32 is the x-coordinate and 100 is the y-coordinate.
|
||||||
|
|
||||||
- size: Size of the border as a tuple -> (width, height).
|
- size: Size of the border as a tuple -> (width, height).
|
||||||
|
|
||||||
@ -324,6 +328,7 @@ def draw_border(image, xy, size, radius=5, thickness=1, shrinkage=(0.1, 0.1)):
|
|||||||
c5, c6 = ((x + width) - diameter, (y + height) - diameter), (x + width, y + height)
|
c5, c6 = ((x + width) - diameter, (y + height) - diameter), (x + width, y + height)
|
||||||
c7, c8 = (x, (y + height) - diameter), (x + diameter, y + height)
|
c7, c8 = (x, (y + height) - diameter), (x + diameter, y + height)
|
||||||
|
|
||||||
|
|
||||||
# Draw lines and arcs, creating a square with round corners
|
# Draw lines and arcs, creating a square with round corners
|
||||||
draw = ImageDraw.Draw(image)
|
draw = ImageDraw.Draw(image)
|
||||||
draw.line((p1, p2), fill=colour, width=thickness)
|
draw.line((p1, p2), fill=colour, width=thickness)
|
||||||
@ -338,7 +343,7 @@ def draw_border(image, xy, size, radius=5, thickness=1, shrinkage=(0.1, 0.1)):
|
|||||||
draw.arc((c7, c8), 90, 180, fill=colour, width=thickness)
|
draw.arc((c7, c8), 90, 180, fill=colour, width=thickness)
|
||||||
|
|
||||||
|
|
||||||
def draw_border_2(im: PIL.Image, xy: tuple, size: tuple, radius: int):
|
def draw_border_2(im: Image, xy: Tuple[int, int], size: Tuple[int, int], radius: int):
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
|
|
||||||
x, y = xy
|
x, y = xy
|
||||||
|
@ -6,16 +6,16 @@ Copyright by aceinnolab
|
|||||||
# pylint: disable=logging-fstring-interpolation
|
# pylint: disable=logging-fstring-interpolation
|
||||||
|
|
||||||
import calendar as cal
|
import calendar as cal
|
||||||
import arrow
|
|
||||||
from inkycal.modules.template import inkycal_module
|
|
||||||
from inkycal.custom import *
|
from inkycal.custom import *
|
||||||
|
from inkycal.modules.template import inkycal_module
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Calendar(inkycal_module):
|
class Calendar(inkycal_module):
|
||||||
"""Calendar class
|
"""Calendar class
|
||||||
Create monthly calendar and show events from given icalendars
|
Create monthly calendar and show events from given iCalendars
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "Calendar - Show monthly calendar with events from iCalendars"
|
name = "Calendar - Show monthly calendar with events from iCalendars"
|
||||||
@ -39,12 +39,12 @@ class Calendar(inkycal_module):
|
|||||||
},
|
},
|
||||||
"date_format": {
|
"date_format": {
|
||||||
"label": "Use an arrow-supported token for custom date formatting "
|
"label": "Use an arrow-supported token for custom date formatting "
|
||||||
+ "see https://arrow.readthedocs.io/en/stable/#supported-tokens, e.g. D MMM",
|
+ "see https://arrow.readthedocs.io/en/stable/#supported-tokens, e.g. D MMM",
|
||||||
"default": "D MMM",
|
"default": "D MMM",
|
||||||
},
|
},
|
||||||
"time_format": {
|
"time_format": {
|
||||||
"label": "Use an arrow-supported token for custom time formatting "
|
"label": "Use an arrow-supported token for custom time formatting "
|
||||||
+ "see https://arrow.readthedocs.io/en/stable/#supported-tokens, e.g. HH:mm",
|
+ "see https://arrow.readthedocs.io/en/stable/#supported-tokens, e.g. HH:mm",
|
||||||
"default": "HH:mm",
|
"default": "HH:mm",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ class Calendar(inkycal_module):
|
|||||||
self._days_with_events = None
|
self._days_with_events = None
|
||||||
|
|
||||||
# optional parameters
|
# optional parameters
|
||||||
self.weekstart = config['week_starts_on']
|
self.week_start = config['week_starts_on']
|
||||||
self.show_events = config['show_events']
|
self.show_events = config['show_events']
|
||||||
self.date_format = config["date_format"]
|
self.date_format = config["date_format"]
|
||||||
self.time_format = config['time_format']
|
self.time_format = config['time_format']
|
||||||
@ -109,7 +109,7 @@ class Calendar(inkycal_module):
|
|||||||
# Allocate space for month-names, weekdays etc.
|
# Allocate space for month-names, weekdays etc.
|
||||||
month_name_height = int(im_height * 0.10)
|
month_name_height = int(im_height * 0.10)
|
||||||
text_bbox_height = self.font.getbbox("hg")
|
text_bbox_height = self.font.getbbox("hg")
|
||||||
weekdays_height = int((text_bbox_height[3] - text_bbox_height[1])* 1.25)
|
weekdays_height = int((abs(text_bbox_height[3]) + abs(text_bbox_height[1])) * 1.25)
|
||||||
logger.debug(f"month_name_height: {month_name_height}")
|
logger.debug(f"month_name_height: {month_name_height}")
|
||||||
logger.debug(f"weekdays_height: {weekdays_height}")
|
logger.debug(f"weekdays_height: {weekdays_height}")
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ class Calendar(inkycal_module):
|
|||||||
logger.debug("Allocating space for events")
|
logger.debug("Allocating space for events")
|
||||||
calendar_height = int(im_height * 0.6)
|
calendar_height = int(im_height * 0.6)
|
||||||
events_height = (
|
events_height = (
|
||||||
im_height - month_name_height - weekdays_height - calendar_height
|
im_height - month_name_height - weekdays_height - calendar_height
|
||||||
)
|
)
|
||||||
logger.debug(f'calendar-section size: {im_width} x {calendar_height} px')
|
logger.debug(f'calendar-section size: {im_width} x {calendar_height} px')
|
||||||
logger.debug(f'events-section size: {im_width} x {events_height} px')
|
logger.debug(f'events-section size: {im_width} x {events_height} px')
|
||||||
@ -156,13 +156,13 @@ class Calendar(inkycal_module):
|
|||||||
|
|
||||||
now = arrow.now(tz=self.timezone)
|
now = arrow.now(tz=self.timezone)
|
||||||
|
|
||||||
# Set weekstart of calendar to specified weekstart
|
# Set week-start of calendar to specified week-start
|
||||||
if self.weekstart == "Monday":
|
if self.week_start == "Monday":
|
||||||
cal.setfirstweekday(cal.MONDAY)
|
cal.setfirstweekday(cal.MONDAY)
|
||||||
weekstart = now.shift(days=-now.weekday())
|
week_start = now.shift(days=-now.weekday())
|
||||||
else:
|
else:
|
||||||
cal.setfirstweekday(cal.SUNDAY)
|
cal.setfirstweekday(cal.SUNDAY)
|
||||||
weekstart = now.shift(days=-now.isoweekday())
|
week_start = now.shift(days=-now.isoweekday())
|
||||||
|
|
||||||
# Write the name of current month
|
# Write the name of current month
|
||||||
write(
|
write(
|
||||||
@ -174,9 +174,9 @@ class Calendar(inkycal_module):
|
|||||||
autofit=True,
|
autofit=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set up weeknames in local language and add to main section
|
# Set up week-names in local language and add to main section
|
||||||
weekday_names = [
|
weekday_names = [
|
||||||
weekstart.shift(days=+_).format('ddd', locale=self.language)
|
week_start.shift(days=+_).format('ddd', locale=self.language)
|
||||||
for _ in range(7)
|
for _ in range(7)
|
||||||
]
|
]
|
||||||
logger.debug(f'weekday names: {weekday_names}')
|
logger.debug(f'weekday names: {weekday_names}')
|
||||||
@ -192,7 +192,7 @@ class Calendar(inkycal_module):
|
|||||||
fill_height=0.9,
|
fill_height=0.9,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a calendar template and flatten (remove nestings)
|
# Create a calendar template and flatten (remove nesting)
|
||||||
calendar_flat = self.flatten(cal.monthcalendar(now.year, now.month))
|
calendar_flat = self.flatten(cal.monthcalendar(now.year, now.month))
|
||||||
# logger.debug(f" calendar_flat: {calendar_flat}")
|
# logger.debug(f" calendar_flat: {calendar_flat}")
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ class Calendar(inkycal_module):
|
|||||||
month_start = arrow.get(now.floor('month'))
|
month_start = arrow.get(now.floor('month'))
|
||||||
month_end = arrow.get(now.ceil('month'))
|
month_end = arrow.get(now.ceil('month'))
|
||||||
|
|
||||||
# fetch events from given icalendars
|
# fetch events from given iCalendars
|
||||||
self.ical = iCalendar()
|
self.ical = iCalendar()
|
||||||
parser = self.ical
|
parser = self.ical
|
||||||
|
|
||||||
@ -294,14 +294,12 @@ class Calendar(inkycal_module):
|
|||||||
month_events = parser.get_events(month_start, month_end, self.timezone)
|
month_events = parser.get_events(month_start, month_end, self.timezone)
|
||||||
parser.sort()
|
parser.sort()
|
||||||
self.month_events = month_events
|
self.month_events = month_events
|
||||||
|
|
||||||
# Initialize days_with_events as an empty list
|
# Initialize days_with_events as an empty list
|
||||||
days_with_events = []
|
days_with_events = []
|
||||||
|
|
||||||
# Handle multi-day events by adding all days between start and end
|
# Handle multi-day events by adding all days between start and end
|
||||||
for event in month_events:
|
for event in month_events:
|
||||||
start_date = event['begin'].date()
|
|
||||||
end_date = event['end'].date()
|
|
||||||
|
|
||||||
# Convert start and end dates to arrow objects with timezone
|
# Convert start and end dates to arrow objects with timezone
|
||||||
start = arrow.get(event['begin'].date(), tzinfo=self.timezone)
|
start = arrow.get(event['begin'].date(), tzinfo=self.timezone)
|
||||||
@ -325,8 +323,6 @@ class Calendar(inkycal_module):
|
|||||||
grid[days],
|
grid[days],
|
||||||
(icon_width, icon_height),
|
(icon_width, icon_height),
|
||||||
radius=6,
|
radius=6,
|
||||||
thickness=1,
|
|
||||||
shrinkage=(0.4, 0.2),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Filter upcoming events until 4 weeks in the future
|
# Filter upcoming events until 4 weeks in the future
|
||||||
@ -345,13 +341,13 @@ class Calendar(inkycal_module):
|
|||||||
|
|
||||||
date_width = int(max((
|
date_width = int(max((
|
||||||
self.font.getlength(events['begin'].format(self.date_format, locale=lang))
|
self.font.getlength(events['begin'].format(self.date_format, locale=lang))
|
||||||
for events in upcoming_events))* 1.1
|
for events in upcoming_events)) * 1.1
|
||||||
)
|
)
|
||||||
|
|
||||||
time_width = int(max((
|
time_width = int(max((
|
||||||
self.font.getlength(events['begin'].format(self.time_format, locale=lang))
|
self.font.getlength(events['begin'].format(self.time_format, locale=lang))
|
||||||
for events in upcoming_events))* 1.1
|
for events in upcoming_events)) * 1.1
|
||||||
)
|
)
|
||||||
|
|
||||||
text_bbox_height = self.font.getbbox("hg")
|
text_bbox_height = self.font.getbbox("hg")
|
||||||
line_height = text_bbox_height[3] + line_spacing
|
line_height = text_bbox_height[3] + line_spacing
|
||||||
@ -369,7 +365,8 @@ class Calendar(inkycal_module):
|
|||||||
event_duration = (event['end'] - event['begin']).days
|
event_duration = (event['end'] - event['begin']).days
|
||||||
if event_duration > 1:
|
if event_duration > 1:
|
||||||
# Format the duration using Arrow's localization
|
# Format the duration using Arrow's localization
|
||||||
days_translation = arrow.get().shift(days=event_duration).humanize(only_distance=True, locale=lang)
|
days_translation = arrow.get().shift(days=event_duration).humanize(only_distance=True,
|
||||||
|
locale=lang)
|
||||||
the_name = f"{event['title']} ({days_translation})"
|
the_name = f"{event['title']} ({days_translation})"
|
||||||
else:
|
else:
|
||||||
the_name = event['title']
|
the_name = event['title']
|
||||||
|
@ -1,12 +1,22 @@
|
|||||||
"""
|
"""
|
||||||
Test the functions in the functions module.
|
Test the functions in the functions module.
|
||||||
"""
|
"""
|
||||||
|
import unittest
|
||||||
|
|
||||||
from PIL import Image, ImageFont
|
from PIL import Image, ImageFont
|
||||||
from inkycal.custom import write, fonts
|
|
||||||
|
from inkycal.custom import write, fonts, get_system_tz
|
||||||
|
|
||||||
|
|
||||||
def test_write():
|
class TestIcalendar(unittest.TestCase):
|
||||||
im = Image.new("RGB", (500, 200), "white")
|
|
||||||
font = ImageFont.truetype(fonts['NotoSans-SemiCondensed'], size = 40)
|
def test_write(self):
|
||||||
write(im, (125,75), (250, 50), "Hello World", font)
|
im = Image.new("RGB", (500, 200), "white")
|
||||||
# im.show()
|
font = ImageFont.truetype(fonts['NotoSans-SemiCondensed'], size=40)
|
||||||
|
write(im, (125, 75), (250, 50), "Hello World", font)
|
||||||
|
# im.show()
|
||||||
|
|
||||||
|
def test_get_system_tz(self):
|
||||||
|
tz = get_system_tz()
|
||||||
|
assert isinstance(tz, str)
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ tests = [
|
|||||||
{
|
{
|
||||||
"name": "Calendar",
|
"name": "Calendar",
|
||||||
"config": {
|
"config": {
|
||||||
"size": [500, 500],
|
"size": [500, 600],
|
||||||
"week_starts_on": "Monday",
|
"week_starts_on": "Monday",
|
||||||
"show_events": True,
|
"show_events": True,
|
||||||
"ical_urls": sample_url,
|
"ical_urls": sample_url,
|
||||||
|
Loading…
Reference in New Issue
Block a user