From d734f36b7b22a8a163e969e2f93328e04a7629d4 Mon Sep 17 00:00:00 2001 From: Ace Date: Mon, 25 Nov 2019 21:31:52 +0100 Subject: [PATCH] Update inkycal_calendar.py --- Inky-Calendar/modules/inkycal_calendar.py | 246 +++++++++++++++------- 1 file changed, 165 insertions(+), 81 deletions(-) diff --git a/Inky-Calendar/modules/inkycal_calendar.py b/Inky-Calendar/modules/inkycal_calendar.py index 40440d2..3dc004f 100644 --- a/Inky-Calendar/modules/inkycal_calendar.py +++ b/Inky-Calendar/modules/inkycal_calendar.py @@ -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()