Update inkycal_calendar.py
This commit is contained in:
		| @@ -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() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user