Update inkycal_calendar.py

This commit is contained in:
Ace 2019-11-25 21:31:52 +01:00 committed by GitHub
parent 28360a9eec
commit d734f36b7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,97 +2,181 @@
# -*- coding: utf-8 -*-
"""
Calendar module for Inky-Calendar Project
Copyright by aceisace
"""
from __future__ import print_function
import calendar
from configuration import *
from settings import *
import datetime
from settings import middle_section, week_starts_on, language, hours, display_type
import arrow
from PIL import Image, ImageDraw
"""Define some parameters for the grid"""
grid_width, grid_height = display_width, 324
grid_rows = 6
grid_coloums = 7
print_events = False
show_events = True
max_event_lines = 4
style = "DD MMM"
padding_left = int((display_width % grid_coloums) / 2)
padding_up = int((grid_height % grid_rows) / 2)
icon_width = grid_width // grid_coloums
icon_height = grid_height // grid_rows
if show_events == True:
from inkycal_icalendar import upcoming_events
weekdays_height = 22
#def main():
this = datetime.datetime.now()
"""Add a border to increase readability"""
border_top = int(middle_section_height * 0.02)
border_left = int(middle_section_width * 0.02)
"""Add grid-coordinates in the grid dictionary for a later lookup"""
grid = {}
main_area_height = middle_section_height-border_top*2
main_area_width = middle_section_width-border_left*2
counter = 0
for row in range(grid_rows):
y = middle_section_offset - grid_height + row*icon_height
for col in range(grid_coloums):
x = padding_left + col*icon_width
counter += 1
grid['pos'+str(counter)] = (x,y)
"""Calculate height for each sub-section"""
month_name_height = int(main_area_height*0.1)
weekdays_height = int(main_area_height*0.05)
calendar_height = int(main_area_height*0.6)
events_height = int(main_area_height*0.25)
"""Set rows and coloumns in the calendar section and calculate sizes"""
calendar_rows, calendar_coloumns = 6, 7
icon_width = main_area_width // calendar_coloumns
icon_height = calendar_height // calendar_rows
"""Calculate paddings for calendar section"""
x_padding_calendar = int((main_area_width % icon_width) / 2)
y_padding_calendar = int((main_area_height % calendar_rows) / 2)
"""Add coordinates for number icons inside the calendar section"""
grid_start_y = (middle_section_offset + border_top + month_name_height +
weekdays_height + y_padding_calendar)
grid_start_x = border_left + x_padding_calendar
grid = [(grid_start_x + icon_width*x, grid_start_y + icon_height*y)
for y in range(calendar_rows) for x in range(calendar_coloumns)]
weekday_pos = [(grid_start_x + icon_width*_, middle_section_offset +
month_name_height) for _ in range(calendar_coloumns)]
event_lines = [(border_left,(bottom_section_offset - events_height)+
int(events_height/max_event_lines*_)) for _ in
range(max_event_lines)]
def main():
try:
print('Calendar module: Generating image...', end = '')
now = arrow.now(tz = get_tz())
"""Set up the Calendar template based on personal preferences"""
if week_starts_on == "Monday":
calendar.setfirstweekday(calendar.MONDAY)
weekstart = now.replace(days = - now.weekday())
else:
calendar.setfirstweekday(calendar.SUNDAY)
weekstart = now.replace(days = - now.isoweekday())
"""Write the name of the current month at the correct position"""
write_text(main_area_width, month_name_height,
str(now.format('MMMM',locale=language)), (border_left,
middle_section_offset), autofit = True)
"""Set up weeknames in local language and add to main section"""
weekday_names = [weekstart.replace(days=+_).format('ddd',locale=language)
for _ in range(7)]
for _ in range(len(weekday_pos)):
write_text(icon_width, weekdays_height, weekday_names[_],
weekday_pos[_], autofit = True)
"""Create a calendar template and flatten (remove nestings)"""
flatten = lambda z: [x for y in z for x in y]
calendar_flat = flatten(calendar.monthcalendar(now.year, now.month))
"""Add the numbers on the correct positions"""
for i in range(len(calendar_flat)):
if calendar_flat[i] != 0:
write_text(icon_width, icon_height, str(calendar_flat[i]), grid[i])
"""Create some reference points for the current month"""
days_current_month = calendar.monthrange(now.year, now.month)[1]
month_start = now.replace(days =-now.day+1)
month_end = now.replace(days=+(days_current_month-now.day))
if show_events == True:
"""Filter events which begin before the end of this month"""
calendar_events = [events for events in upcoming_events if
events.begin.to(get_tz()) < month_end and
events.begin.month == now.month]
"""Find days with events in the current month"""
days_with_events = []
for events in calendar_events:
if events.duration.days <= 1:
days_with_events.append(int(events.begin.format('D')))
else:
for day in range(events.duration.days):
days_with_events.append(
int(events.begin.replace(days=+i).format('D')))
days_with_events = set(days_with_events)
for days in days_with_events:
write_text(icon_width, int(icon_height * 0.2), '',
(grid[calendar_flat.index(days)][0],
int(grid[calendar_flat.index(days)][1] + icon_height*0.8)))
"""Add a small section showing events of today and tomorrow"""
event_list = ['{0} at {1} : {2}'.format('today', event.begin.format(
'HH:mm' if hours == 24 else 'hh:mm'), event.name)
for event in calendar_events if event.begin.day == now.day]
event_list += ['{0} at {1} : {2}'.format('tomorrow', event.begin.format(
'HH:mm' if hours == 24 else 'hh:mm'), event.name)
for event in calendar_events
if event.begin.day == now.replace(days=+1).day]
del event_list[4:]
if event_list:
for lines in event_list:
write_text(main_area_width, int(events_height/max_event_lines), lines,
event_lines[event_list.index(lines)], alignment='left',
fill_height = 0.7)
else:
write_text(main_area_width, int(events_height/max_event_lines),
'No events today or tomorrow', event_lines[0], alignment='left',
fill_height = 0.7)
"""Draw a red/black circle with the current day of month in white"""
space = Image.new('RGB', (icon_width, icon_height), color=background_colour)
current_day_pos = grid[calendar_flat.index(now.day)]
x_circle,y_circle = int(icon_width/2), int(icon_height/2)
radius = int(icon_width * 0.3)
text_width, text_height = default.getsize(str(now.day))
x_text = int((icon_width / 2) - (text_width / 2))
y_text = int((icon_height / 2) - (text_height / 1.7))
ImageDraw.Draw(space).ellipse((x_circle-radius, y_circle-radius,
x_circle+radius, y_circle+radius), fill= 'red' if
display_type == 'colour' else 'black', outline=None)
ImageDraw.Draw(space).text((x_text, y_text), str(now.day), fill='white',
font=default)
image.paste(space, current_day_pos)
"""Set print_events_to True to print all events in this month"""
style = 'DD MMM YY HH:mm'
if print_events == True and calendar_events:
line_width = max(len(_.name) for _ in calendar_events)
for events in calendar_events:
print('{0} {1} | {2} | {3} | All day ='.format(events.name,
' ' * (line_width - len(events.name)), events.begin.format(style),
events.end.format(style)), events.all_day)
calendar_image = image.crop((0, top_section_height, display_width,
display_height-bottom_section_height))
calendar_image.save(image_path+'calendar.png')
print('Done')
except Exception as e:
"""If something went wrong, print a Error message on the Terminal"""
print('Failed!')
print('Error in Calendar module!')
print('Reason: ',e)
pass
"""Set the Calendar to start on the day specified by the settings file """
if week_starts_on is "" or "Monday":
calendar.setfirstweekday(calendar.MONDAY)
else:
calendar.setfirstweekday(calendar.SUNDAY)
"""Create a scrolling calendar"""
cal = calendar.monthcalendar(this.year, this.month)
current_row = [cal.index(i) for i in cal if this.day in i][0]
if current_row > 1:
del cal[:current_row-1]
if len(cal) < grid_rows:
next_month = this + datetime.timedelta(days=30)
cal_next_month = calendar.monthcalendar(next_month.year, next_month.month)
cal.extend(cal_next_month[:grid_rows - len(cal)]
"""
flatten = lambda z: [x for y in z for x in y]
cal = flatten(cal)
cal_next_month = flatten(cal_next_month)
cal.extend(cal_next_month)
num_font= ImageFont.truetype(NotoSansCJK+'Light.otf', 30)
"""
#draw = ImageDraw.Draw(image) #
"""
counter = 0
for i in range(len(cal)):
counter += 1
if cal[i] != 0 and counter <= grid_rows*grid_coloums:
write_text(icon_width, icon_height, str(cal[i]), grid['pos'+str(counter)],
font = num_font)
##if this.day == cal[i]:
##pos = grid['pos'+str(counter)]
#x = pos[0] + int(icon_width/2)
#y = pos[1] + int(icon_height/2)
#r = int(icon_width * 0.75#coords = (x-r, y-r, x+r, y+r)
#draw.ellipse(coords, fill= 0, outline='black',
#width=3)
image.crop((0, top_section_height, display_width,
display_height-bottom_section_height)).save('cal.png')
#if __name__ == '__main__':
# main()
"""
if __name__ == '__main__':
main()