2020-11-09 20:15:17 +00:00
|
|
|
|
__filename__ = "webapp_calendar.py"
|
|
|
|
|
__author__ = "Bob Mottram"
|
|
|
|
|
__license__ = "AGPL3+"
|
2024-01-21 19:01:20 +00:00
|
|
|
|
__version__ = "1.5.0"
|
2020-11-09 20:15:17 +00:00
|
|
|
|
__maintainer__ = "Bob Mottram"
|
2021-09-10 16:14:50 +00:00
|
|
|
|
__email__ = "bob@libreserver.org"
|
2020-11-09 20:15:17 +00:00
|
|
|
|
__status__ = "Production"
|
2021-06-15 15:08:12 +00:00
|
|
|
|
__module_group__ = "Calendar"
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
from datetime import date
|
2023-07-12 11:46:25 +00:00
|
|
|
|
from utils import remove_html
|
2021-12-27 21:59:07 +00:00
|
|
|
|
from utils import get_display_name
|
2021-12-26 14:08:58 +00:00
|
|
|
|
from utils import get_config_param
|
2021-12-27 22:19:18 +00:00
|
|
|
|
from utils import get_nickname_from_actor
|
2021-12-27 19:05:25 +00:00
|
|
|
|
from utils import get_domain_from_actor
|
2021-12-26 20:36:08 +00:00
|
|
|
|
from utils import locate_post
|
2021-12-26 15:13:34 +00:00
|
|
|
|
from utils import load_json
|
2021-12-26 20:52:11 +00:00
|
|
|
|
from utils import week_day_of_month_start
|
2021-12-26 18:32:02 +00:00
|
|
|
|
from utils import get_alt_path
|
2021-12-26 18:17:37 +00:00
|
|
|
|
from utils import remove_domain_port
|
2021-12-26 12:02:29 +00:00
|
|
|
|
from utils import acct_dir
|
2021-12-26 10:19:59 +00:00
|
|
|
|
from utils import local_actor_url
|
2021-12-26 17:21:37 +00:00
|
|
|
|
from utils import replace_users_with_at
|
2023-09-10 10:12:39 +00:00
|
|
|
|
from utils import language_right_to_left
|
2023-11-20 22:27:58 +00:00
|
|
|
|
from utils import date_from_string_format
|
2021-12-29 21:55:09 +00:00
|
|
|
|
from happening import get_todays_events
|
|
|
|
|
from happening import get_calendar_events
|
2022-02-21 11:08:48 +00:00
|
|
|
|
from happening import get_todays_events_icalendar
|
|
|
|
|
from happening import get_month_events_icalendar
|
2022-05-29 16:49:49 +00:00
|
|
|
|
from webapp_utils import get_banner_file
|
2021-12-29 21:55:09 +00:00
|
|
|
|
from webapp_utils import set_custom_background
|
|
|
|
|
from webapp_utils import html_header_with_external_style
|
|
|
|
|
from webapp_utils import html_footer
|
|
|
|
|
from webapp_utils import html_hide_from_screen_reader
|
|
|
|
|
from webapp_utils import html_keyboard_navigation
|
2022-05-23 13:18:03 +00:00
|
|
|
|
from maps import html_open_street_map
|
2021-12-29 21:55:09 +00:00
|
|
|
|
|
|
|
|
|
|
2022-06-03 20:31:42 +00:00
|
|
|
|
def html_calendar_delete_confirm(translate: {}, base_dir: str,
|
2021-12-29 21:55:09 +00:00
|
|
|
|
path: str, http_prefix: str,
|
2022-01-03 22:00:38 +00:00
|
|
|
|
domain_full: str, post_id: str,
|
|
|
|
|
post_time: str,
|
|
|
|
|
year: int, month_number: int,
|
|
|
|
|
day_number: int, calling_domain: str) -> str:
|
2020-11-09 20:15:17 +00:00
|
|
|
|
"""Shows a screen asking to confirm the deletion of a calendar event
|
|
|
|
|
"""
|
2021-12-27 22:19:18 +00:00
|
|
|
|
nickname = get_nickname_from_actor(path)
|
2022-03-23 23:59:29 +00:00
|
|
|
|
if not nickname:
|
|
|
|
|
return None
|
2021-12-26 10:19:59 +00:00
|
|
|
|
actor = local_actor_url(http_prefix, nickname, domain_full)
|
2022-01-03 22:00:38 +00:00
|
|
|
|
domain, _ = get_domain_from_actor(actor)
|
2023-01-15 14:33:18 +00:00
|
|
|
|
if not domain:
|
|
|
|
|
return None
|
2022-01-03 22:00:38 +00:00
|
|
|
|
message_id = actor + '/statuses/' + post_id
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
post_filename = locate_post(base_dir, nickname, domain, message_id)
|
2021-12-26 23:41:34 +00:00
|
|
|
|
if not post_filename:
|
2020-11-09 20:15:17 +00:00
|
|
|
|
return None
|
|
|
|
|
|
2021-12-26 23:41:34 +00:00
|
|
|
|
post_json_object = load_json(post_filename)
|
2021-12-25 22:09:19 +00:00
|
|
|
|
if not post_json_object:
|
2020-11-09 20:15:17 +00:00
|
|
|
|
return None
|
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_post_str = None
|
2021-12-31 21:18:12 +00:00
|
|
|
|
css_filename = base_dir + '/epicyon-profile.css'
|
2021-12-25 16:17:53 +00:00
|
|
|
|
if os.path.isfile(base_dir + '/epicyon.css'):
|
2021-12-31 21:18:12 +00:00
|
|
|
|
css_filename = base_dir + '/epicyon.css'
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
instance_title = \
|
2021-12-26 14:08:58 +00:00
|
|
|
|
get_config_param(base_dir, 'instanceTitle')
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_post_str = \
|
|
|
|
|
html_header_with_external_style(css_filename, instance_title, None)
|
|
|
|
|
delete_post_str += \
|
2022-05-25 18:07:53 +00:00
|
|
|
|
'<center>\n<h1>' + post_time + ' ' + str(year) + '/' + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
str(month_number) + \
|
2022-05-25 18:07:53 +00:00
|
|
|
|
'/' + str(day_number) + '</h1>\n</center>\n'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_post_str += '<center>'
|
|
|
|
|
delete_post_str += ' <p class="followText">' + \
|
2020-11-12 17:05:38 +00:00
|
|
|
|
translate['Delete this event'] + '</p>'
|
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
post_actor = get_alt_path(actor, domain_full, calling_domain)
|
|
|
|
|
delete_post_str += \
|
|
|
|
|
' <form method="POST" action="' + post_actor + '/rmpost">\n'
|
|
|
|
|
delete_post_str += ' <input type="hidden" name="year" value="' + \
|
2020-11-12 17:05:38 +00:00
|
|
|
|
str(year) + '">\n'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_post_str += ' <input type="hidden" name="month" value="' + \
|
|
|
|
|
str(month_number) + '">\n'
|
|
|
|
|
delete_post_str += ' <input type="hidden" name="day" value="' + \
|
|
|
|
|
str(day_number) + '">\n'
|
2022-12-17 17:49:54 +00:00
|
|
|
|
if post_time:
|
|
|
|
|
delete_post_str += ' <input type="hidden" name="time" value="' + \
|
|
|
|
|
post_time + '">\n'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_post_str += \
|
2020-11-12 17:05:38 +00:00
|
|
|
|
' <input type="hidden" name="pageNumber" value="1">\n'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_post_str += \
|
2020-11-12 17:05:38 +00:00
|
|
|
|
' <input type="hidden" name="messageId" value="' + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
message_id + '">\n'
|
|
|
|
|
delete_post_str += \
|
2020-11-12 17:05:38 +00:00
|
|
|
|
' <button type="submit" class="button" name="submitYes">' + \
|
|
|
|
|
translate['Yes'] + '</button>\n'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_post_str += \
|
2020-11-12 17:05:38 +00:00
|
|
|
|
' <a href="' + actor + '/calendar?year=' + \
|
|
|
|
|
str(year) + '?month=' + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
str(month_number) + '"><button class="button">' + \
|
2020-11-12 17:05:38 +00:00
|
|
|
|
translate['No'] + '</button></a>\n'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_post_str += ' </form>\n'
|
|
|
|
|
delete_post_str += '</center>\n'
|
|
|
|
|
delete_post_str += html_footer()
|
|
|
|
|
return delete_post_str
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
|
|
|
|
|
2022-07-12 19:03:30 +00:00
|
|
|
|
def _html_calendar_day(person_cache: {}, translate: {},
|
2021-12-29 21:55:09 +00:00
|
|
|
|
base_dir: str, path: str,
|
2022-01-03 22:00:38 +00:00
|
|
|
|
year: int, month_number: int, day_number: int,
|
|
|
|
|
nickname: str, domain: str, day_events: [],
|
2022-05-29 17:19:26 +00:00
|
|
|
|
month_name: str, actor: str,
|
2022-12-17 13:49:01 +00:00
|
|
|
|
theme: str, access_keys: {},
|
2022-12-17 14:08:43 +00:00
|
|
|
|
system_language: str) -> str:
|
2020-11-09 20:15:17 +00:00
|
|
|
|
"""Show a day within the calendar
|
|
|
|
|
"""
|
2022-01-03 22:00:38 +00:00
|
|
|
|
account_dir = acct_dir(base_dir, nickname, domain)
|
|
|
|
|
calendar_file = account_dir + '/.newCalendar'
|
|
|
|
|
if os.path.isfile(calendar_file):
|
2021-09-05 10:17:43 +00:00
|
|
|
|
try:
|
2022-01-03 22:00:38 +00:00
|
|
|
|
os.remove(calendar_file)
|
2021-11-25 18:42:38 +00:00
|
|
|
|
except OSError:
|
2022-01-03 22:00:38 +00:00
|
|
|
|
print('EX: _html_calendar_day unable to delete ' + calendar_file)
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2021-12-31 21:18:12 +00:00
|
|
|
|
css_filename = base_dir + '/epicyon-calendar.css'
|
2021-12-25 16:17:53 +00:00
|
|
|
|
if os.path.isfile(base_dir + '/calendar.css'):
|
2021-12-31 21:18:12 +00:00
|
|
|
|
css_filename = base_dir + '/calendar.css'
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
cal_actor = actor
|
2020-11-09 20:15:17 +00:00
|
|
|
|
if '/users/' in actor:
|
2022-01-03 22:00:38 +00:00
|
|
|
|
cal_actor = '/users/' + actor.split('/users/')[1]
|
|
|
|
|
|
|
|
|
|
instance_title = get_config_param(base_dir, 'instanceTitle')
|
|
|
|
|
calendar_str = \
|
|
|
|
|
html_header_with_external_style(css_filename, instance_title, None)
|
2022-05-29 17:19:26 +00:00
|
|
|
|
|
|
|
|
|
calendar_link = cal_actor + \
|
|
|
|
|
'/calendar?year=' + str(year) + '?month=' + str(month_number)
|
|
|
|
|
|
|
|
|
|
# show banner
|
|
|
|
|
banner_file, _ = \
|
|
|
|
|
get_banner_file(base_dir, nickname, domain, theme)
|
|
|
|
|
calendar_str += \
|
|
|
|
|
'<header>\n<a href="' + calendar_link + '" title="' + \
|
|
|
|
|
translate['Switch to calendar view'] + '" alt="' + \
|
|
|
|
|
translate['Switch to calendar view'] + '" ' + \
|
|
|
|
|
'tabindex="1" accesskey="' + access_keys['menuCalendar'] + '">\n'
|
|
|
|
|
calendar_str += \
|
|
|
|
|
'<img loading="lazy" decoding="async" ' + \
|
|
|
|
|
'class="timeline-banner" alt="" ' + \
|
|
|
|
|
'src="/users/' + nickname + '/' + banner_file + '" /></a>\n' + \
|
2022-05-29 17:21:47 +00:00
|
|
|
|
'</header>\n<br>\n'
|
2022-05-29 17:19:26 +00:00
|
|
|
|
|
2022-05-25 18:07:53 +00:00
|
|
|
|
calendar_str += '<main>\n'
|
|
|
|
|
# day header
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += \
|
2022-05-29 17:19:26 +00:00
|
|
|
|
' <center>\n<p>\n<a href="' + calendar_link + \
|
|
|
|
|
'" tabindex="1" class="imageAnchor">\n'
|
2022-05-23 16:11:35 +00:00
|
|
|
|
datetime_str = str(year) + '-' + str(month_number) + '-' + str(day_number)
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += \
|
2022-05-25 18:07:53 +00:00
|
|
|
|
' <label class="calheader">' + \
|
|
|
|
|
'<time datetime="' + datetime_str + '">' + \
|
2022-05-23 16:11:35 +00:00
|
|
|
|
str(day_number) + ' ' + month_name + \
|
2022-05-25 18:07:53 +00:00
|
|
|
|
'</time></label></a><br><span class="year">' + str(year) + '</span>\n'
|
2022-05-25 18:09:57 +00:00
|
|
|
|
calendar_str += '</p>\n</center>\n'
|
2022-05-25 18:07:53 +00:00
|
|
|
|
calendar_str += '<table class="calendar">\n'
|
|
|
|
|
# day events list
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += '<tbody>\n'
|
|
|
|
|
if day_events:
|
|
|
|
|
for event_post in day_events:
|
|
|
|
|
event_time = None
|
2023-01-17 13:12:59 +00:00
|
|
|
|
event_time_markup = None
|
2022-05-23 12:46:23 +00:00
|
|
|
|
event_end_time = None
|
2022-05-23 13:31:30 +00:00
|
|
|
|
start_time_str = ''
|
|
|
|
|
end_time_str = ''
|
2022-01-03 22:00:38 +00:00
|
|
|
|
event_description = None
|
2022-12-17 14:08:43 +00:00
|
|
|
|
event_language = system_language
|
2022-01-03 22:00:38 +00:00
|
|
|
|
event_place = None
|
2021-12-26 19:47:06 +00:00
|
|
|
|
post_id = None
|
2022-01-03 22:00:38 +00:00
|
|
|
|
sender_name = ''
|
|
|
|
|
sender_actor = None
|
|
|
|
|
event_is_public = False
|
2020-11-09 20:15:17 +00:00
|
|
|
|
# get the time place and description
|
2022-01-03 22:00:38 +00:00
|
|
|
|
for evnt in event_post:
|
2022-12-17 14:08:43 +00:00
|
|
|
|
event_language = system_language
|
|
|
|
|
if evnt.get('language'):
|
|
|
|
|
event_language = evnt['language']
|
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
if evnt['type'] == 'Event':
|
|
|
|
|
if evnt.get('post_id'):
|
|
|
|
|
post_id = evnt['post_id']
|
|
|
|
|
if evnt.get('startTime'):
|
2022-05-23 13:31:30 +00:00
|
|
|
|
start_time_str = evnt['startTime']
|
2022-01-03 22:00:38 +00:00
|
|
|
|
event_date = \
|
2023-11-20 22:27:58 +00:00
|
|
|
|
date_from_string_format(start_time_str,
|
|
|
|
|
["%Y-%m-%dT%H:%M:%S%z"])
|
2022-01-03 22:00:38 +00:00
|
|
|
|
event_time = event_date.strftime("%H:%M").strip()
|
2022-05-23 12:46:23 +00:00
|
|
|
|
if evnt.get('endTime'):
|
2022-05-23 13:31:30 +00:00
|
|
|
|
end_time_str = evnt['endTime']
|
2022-05-23 12:46:23 +00:00
|
|
|
|
event_end_date = \
|
2023-11-20 22:27:58 +00:00
|
|
|
|
date_from_string_format(end_time_str,
|
|
|
|
|
["%Y-%m-%dT%H:%M:%S%z"])
|
2022-05-23 12:56:38 +00:00
|
|
|
|
event_end_time = \
|
|
|
|
|
event_end_date.strftime("%H:%M").strip()
|
2022-01-03 22:00:38 +00:00
|
|
|
|
if 'public' in evnt:
|
|
|
|
|
if evnt['public'] is True:
|
|
|
|
|
event_is_public = True
|
|
|
|
|
if evnt.get('sender'):
|
2021-03-06 18:20:10 +00:00
|
|
|
|
# get display name from sending actor
|
2022-01-03 22:00:38 +00:00
|
|
|
|
if evnt.get('sender'):
|
|
|
|
|
sender_actor = evnt['sender']
|
|
|
|
|
disp_name = \
|
|
|
|
|
get_display_name(base_dir, sender_actor,
|
2021-12-27 21:59:07 +00:00
|
|
|
|
person_cache)
|
2022-01-03 22:00:38 +00:00
|
|
|
|
if disp_name:
|
|
|
|
|
sender_name = \
|
|
|
|
|
'<a href="' + sender_actor + '">' + \
|
|
|
|
|
disp_name + '</a>: '
|
|
|
|
|
if evnt.get('name'):
|
|
|
|
|
event_description = evnt['name'].strip()
|
|
|
|
|
elif evnt['type'] == 'Place':
|
|
|
|
|
if evnt.get('name'):
|
2023-07-12 11:46:25 +00:00
|
|
|
|
event_place = remove_html(evnt['name'])
|
2022-05-23 13:18:03 +00:00
|
|
|
|
if '://' in event_place:
|
|
|
|
|
bounding_box_degrees = 0.001
|
|
|
|
|
event_map = \
|
|
|
|
|
html_open_street_map(event_place,
|
|
|
|
|
bounding_box_degrees,
|
2022-05-23 13:36:15 +00:00
|
|
|
|
translate,
|
2022-05-23 13:38:45 +00:00
|
|
|
|
'320', '320')
|
2022-05-23 13:18:03 +00:00
|
|
|
|
if event_map:
|
|
|
|
|
event_place = event_map
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2021-03-06 18:48:16 +00:00
|
|
|
|
# prepend a link to the sender of the calendar item
|
2022-01-03 22:00:38 +00:00
|
|
|
|
if sender_name and event_description:
|
2021-03-06 19:41:39 +00:00
|
|
|
|
# if the sender is also mentioned within the event
|
|
|
|
|
# description then this is a reminder
|
2022-01-03 22:00:38 +00:00
|
|
|
|
sender_actor2 = replace_users_with_at(sender_actor)
|
|
|
|
|
if sender_actor not in event_description and \
|
|
|
|
|
sender_actor2 not in event_description:
|
|
|
|
|
event_description = sender_name + event_description
|
2021-03-06 19:04:41 +00:00
|
|
|
|
else:
|
2022-01-03 22:00:38 +00:00
|
|
|
|
event_description = \
|
|
|
|
|
translate['Reminder'] + ': ' + event_description
|
2021-03-06 18:48:16 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_button_str = ''
|
2021-12-26 19:47:06 +00:00
|
|
|
|
if post_id:
|
2022-01-03 22:00:38 +00:00
|
|
|
|
delete_button_str = \
|
|
|
|
|
'<td class="calendar__day__icons"><a href="' + \
|
|
|
|
|
cal_actor + \
|
2021-12-26 19:47:06 +00:00
|
|
|
|
'/eventdelete?eventid=' + post_id + \
|
|
|
|
|
'?year=' + str(year) + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
'?month=' + str(month_number) + \
|
|
|
|
|
'?day=' + str(day_number) + \
|
|
|
|
|
'?time=' + event_time + \
|
2022-03-28 08:47:53 +00:00
|
|
|
|
'">\n<img class="calendardayicon" loading="lazy" ' + \
|
|
|
|
|
'decoding="async" alt="' + \
|
2020-11-09 20:15:17 +00:00
|
|
|
|
translate['Delete this event'] + ' |" title="' + \
|
|
|
|
|
translate['Delete this event'] + '" src="/' + \
|
2020-12-09 13:08:26 +00:00
|
|
|
|
'icons/delete.png" /></a></td>\n'
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-12-17 14:08:43 +00:00
|
|
|
|
is_rtl = language_right_to_left(event_language)
|
2022-12-17 13:49:01 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
event_class = 'calendar__day__event'
|
2022-12-17 13:49:01 +00:00
|
|
|
|
if is_rtl:
|
|
|
|
|
event_class = 'calendar__day__event__rtl'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
cal_item_class = 'calItem'
|
|
|
|
|
if event_is_public:
|
|
|
|
|
event_class = 'calendar__day__event__public'
|
2022-12-17 13:49:01 +00:00
|
|
|
|
if is_rtl:
|
2022-12-17 15:59:23 +00:00
|
|
|
|
event_class = 'calendar__day__event__public__rtl'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
cal_item_class = 'calItemPublic'
|
2022-05-23 13:27:31 +00:00
|
|
|
|
if event_time:
|
2023-01-17 13:07:55 +00:00
|
|
|
|
event_time_markup = \
|
2023-01-17 13:01:53 +00:00
|
|
|
|
'<time datetime="' + start_time_str + '">' + \
|
|
|
|
|
event_time + '</time>'
|
|
|
|
|
if event_time and event_end_time and \
|
|
|
|
|
start_time_str != end_time_str:
|
|
|
|
|
event_time_int_str = event_time.replace(':', '')
|
|
|
|
|
event_end_time_int_str = event_end_time.replace(':', '')
|
|
|
|
|
if event_time_int_str.isdigit() and \
|
|
|
|
|
event_end_time_int_str.isdigit():
|
|
|
|
|
if int(event_end_time_int_str) > \
|
|
|
|
|
int(event_time_int_str):
|
2023-01-17 13:11:59 +00:00
|
|
|
|
event_time_markup = \
|
2023-01-17 13:01:53 +00:00
|
|
|
|
'<time datetime="' + start_time_str + '">' + \
|
2023-01-17 13:07:55 +00:00
|
|
|
|
event_time_markup + '</time> - ' + \
|
2023-01-17 13:01:53 +00:00
|
|
|
|
'<time datetime="' + end_time_str + '">' + \
|
|
|
|
|
event_end_time + '</time>'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
if event_time and event_description and event_place:
|
|
|
|
|
calendar_str += \
|
|
|
|
|
'<tr class="' + cal_item_class + '">' + \
|
2023-01-17 13:07:55 +00:00
|
|
|
|
'<td class="calendar__day__time"><b>' + \
|
|
|
|
|
event_time_markup + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
'</b></td><td class="' + event_class + '">' + \
|
2020-11-09 20:15:17 +00:00
|
|
|
|
'<span class="place">' + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
event_place + '</span><br>' + event_description + \
|
|
|
|
|
'</td>' + delete_button_str + '</tr>\n'
|
|
|
|
|
elif event_time and event_description and not event_place:
|
|
|
|
|
calendar_str += \
|
|
|
|
|
'<tr class="' + cal_item_class + '">' + \
|
2023-01-17 13:07:55 +00:00
|
|
|
|
'<td class="calendar__day__time"><b>' + \
|
|
|
|
|
event_time_markup + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
'</b></td><td class="' + event_class + '">' + \
|
|
|
|
|
event_description + '</td>' + delete_button_str + '</tr>\n'
|
|
|
|
|
elif not event_time and event_description and not event_place:
|
|
|
|
|
calendar_str += \
|
|
|
|
|
'<tr class="' + cal_item_class + '">' + \
|
2021-03-07 17:08:43 +00:00
|
|
|
|
'<td class="calendar__day__time">' + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
'</td><td class="' + event_class + '">' + \
|
|
|
|
|
event_description + '</td>' + delete_button_str + '</tr>\n'
|
|
|
|
|
elif not event_time and event_description and event_place:
|
|
|
|
|
calendar_str += \
|
|
|
|
|
'<tr class="' + cal_item_class + '">' + \
|
2021-03-07 17:08:43 +00:00
|
|
|
|
'<td class="calendar__day__time"></td>' + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
'<td class="' + event_class + '"><span class="place">' + \
|
|
|
|
|
event_place + '</span><br>' + event_description + \
|
|
|
|
|
'</td>' + delete_button_str + '</tr>\n'
|
|
|
|
|
elif event_time and not event_description and event_place:
|
|
|
|
|
calendar_str += \
|
|
|
|
|
'<tr class="' + cal_item_class + '">' + \
|
2023-01-17 13:07:55 +00:00
|
|
|
|
'<td class="calendar__day__time"><b>' + \
|
|
|
|
|
event_time_markup + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
'</b></td><td class="' + event_class + '">' + \
|
2020-11-09 20:15:17 +00:00
|
|
|
|
'<span class="place">' + \
|
2022-01-03 22:00:38 +00:00
|
|
|
|
event_place + '</span></td>' + \
|
|
|
|
|
delete_button_str + '</tr>\n'
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-02-21 11:51:11 +00:00
|
|
|
|
calendar_str += '</tbody>\n'
|
2022-05-25 17:44:11 +00:00
|
|
|
|
calendar_str += '</table>\n</main>\n'
|
2022-02-21 11:51:11 +00:00
|
|
|
|
|
2022-02-21 11:08:48 +00:00
|
|
|
|
# icalendar download link
|
2024-08-14 11:37:38 +00:00
|
|
|
|
# NOTE: don't use download="preferredfilename" which is
|
|
|
|
|
# unsupported by some browsers
|
2022-02-21 11:08:48 +00:00
|
|
|
|
calendar_str += \
|
2022-02-21 17:43:55 +00:00
|
|
|
|
' <a href="' + path + '?ical=true" ' + \
|
2024-08-14 11:37:38 +00:00
|
|
|
|
'download class="imageAnchor" tabindex="3">' + \
|
2022-02-21 11:08:48 +00:00
|
|
|
|
'<img class="ical" src="/icons/ical.png" ' + \
|
|
|
|
|
'title="iCalendar" alt="iCalendar" /></a>\n'
|
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += html_footer()
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
return calendar_str
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
|
|
|
|
|
2022-07-12 19:03:30 +00:00
|
|
|
|
def html_calendar(person_cache: {}, translate: {},
|
2021-12-29 21:55:09 +00:00
|
|
|
|
base_dir: str, path: str,
|
|
|
|
|
http_prefix: str, domain_full: str,
|
2022-02-21 11:08:48 +00:00
|
|
|
|
text_mode_banner: str, access_keys: {},
|
2022-05-25 16:06:05 +00:00
|
|
|
|
icalendar: bool, system_language: str,
|
2022-12-17 14:08:43 +00:00
|
|
|
|
default_timeline: str, theme: str) -> str:
|
2020-11-09 20:15:17 +00:00
|
|
|
|
"""Show the calendar for a person
|
|
|
|
|
"""
|
2021-12-26 18:17:37 +00:00
|
|
|
|
domain = remove_domain_port(domain_full)
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-02-23 18:46:20 +00:00
|
|
|
|
text_match = ''
|
2022-02-21 16:58:37 +00:00
|
|
|
|
default_year = 1970
|
|
|
|
|
default_month = 0
|
|
|
|
|
month_number = default_month
|
2022-01-03 22:00:38 +00:00
|
|
|
|
day_number = None
|
2022-02-21 16:58:37 +00:00
|
|
|
|
year = default_year
|
2021-12-26 10:00:46 +00:00
|
|
|
|
actor = http_prefix + '://' + domain_full + path.replace('/calendar', '')
|
2024-01-22 16:49:23 +00:00
|
|
|
|
only_show_reminders = False
|
2020-11-09 20:15:17 +00:00
|
|
|
|
if '?' in actor:
|
|
|
|
|
first = True
|
2022-01-03 22:00:38 +00:00
|
|
|
|
for part in actor.split('?'):
|
2024-07-16 09:55:34 +00:00
|
|
|
|
if first:
|
|
|
|
|
first = False
|
|
|
|
|
continue
|
|
|
|
|
if '=' not in part:
|
|
|
|
|
continue
|
|
|
|
|
if part.split('=')[0] == 'year':
|
|
|
|
|
num_str = part.split('=')[1]
|
|
|
|
|
if len(num_str) <= 5:
|
|
|
|
|
if num_str.isdigit():
|
|
|
|
|
year = int(num_str)
|
|
|
|
|
elif part.split('=')[0] == 'month':
|
|
|
|
|
num_str = part.split('=')[1]
|
|
|
|
|
if len(num_str) <= 3:
|
|
|
|
|
if num_str.isdigit():
|
|
|
|
|
month_number = int(num_str)
|
|
|
|
|
elif part.split('=')[0] == 'day':
|
|
|
|
|
num_str = part.split('=')[1]
|
|
|
|
|
if len(num_str) <= 3:
|
|
|
|
|
if num_str.isdigit():
|
|
|
|
|
day_number = int(num_str)
|
|
|
|
|
elif part.split('=')[0] == 'ical':
|
|
|
|
|
bool_str = part.split('=')[1]
|
|
|
|
|
if bool_str.lower().startswith('t'):
|
|
|
|
|
icalendar = True
|
|
|
|
|
elif part.split('=')[0] == 'onlyShowReminders':
|
|
|
|
|
bool_str = part.split('=')[1]
|
|
|
|
|
if bool_str.lower().startswith('t'):
|
|
|
|
|
only_show_reminders = True
|
2020-11-09 20:15:17 +00:00
|
|
|
|
actor = actor.split('?')[0]
|
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
curr_date = datetime.now()
|
2022-02-21 16:58:37 +00:00
|
|
|
|
if year == default_year and month_number == default_month:
|
2022-01-03 22:00:38 +00:00
|
|
|
|
year = curr_date.year
|
|
|
|
|
month_number = curr_date.month
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2021-12-27 22:19:18 +00:00
|
|
|
|
nickname = get_nickname_from_actor(actor)
|
2022-03-23 23:59:29 +00:00
|
|
|
|
if not nickname:
|
|
|
|
|
return ''
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2021-12-29 21:55:09 +00:00
|
|
|
|
set_custom_background(base_dir, 'calendar-background',
|
|
|
|
|
'calendar-background')
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2021-11-03 16:44:34 +00:00
|
|
|
|
months = (
|
|
|
|
|
'January', 'February', 'March', 'April', 'May', 'June',
|
|
|
|
|
'July', 'August', 'September', 'October', 'November', 'December'
|
|
|
|
|
)
|
2022-01-03 22:00:38 +00:00
|
|
|
|
month_name = translate[months[month_number - 1]]
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
if day_number:
|
2022-02-21 11:08:48 +00:00
|
|
|
|
if icalendar:
|
|
|
|
|
return get_todays_events_icalendar(base_dir,
|
|
|
|
|
nickname, domain,
|
|
|
|
|
year, month_number,
|
|
|
|
|
day_number,
|
2022-02-21 19:01:19 +00:00
|
|
|
|
person_cache,
|
2022-04-13 15:06:03 +00:00
|
|
|
|
text_match,
|
|
|
|
|
system_language)
|
2022-01-03 22:00:38 +00:00
|
|
|
|
day_events = None
|
2020-11-09 20:15:17 +00:00
|
|
|
|
events = \
|
2021-12-29 21:55:09 +00:00
|
|
|
|
get_todays_events(base_dir, nickname, domain,
|
2022-02-23 18:46:20 +00:00
|
|
|
|
year, month_number, day_number,
|
2022-04-13 15:06:03 +00:00
|
|
|
|
text_match, system_language)
|
2020-11-09 20:15:17 +00:00
|
|
|
|
if events:
|
2022-01-03 22:00:38 +00:00
|
|
|
|
if events.get(str(day_number)):
|
|
|
|
|
day_events = events[str(day_number)]
|
2022-07-12 19:03:30 +00:00
|
|
|
|
return _html_calendar_day(person_cache,
|
2021-12-29 21:55:09 +00:00
|
|
|
|
translate, base_dir, path,
|
2022-01-03 22:00:38 +00:00
|
|
|
|
year, month_number, day_number,
|
|
|
|
|
nickname, domain, day_events,
|
2022-05-29 17:19:26 +00:00
|
|
|
|
month_name, actor,
|
2022-12-17 13:49:01 +00:00
|
|
|
|
theme, access_keys,
|
2022-12-17 14:08:43 +00:00
|
|
|
|
system_language)
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-02-21 11:08:48 +00:00
|
|
|
|
if icalendar:
|
|
|
|
|
return get_month_events_icalendar(base_dir, nickname, domain,
|
2022-02-21 19:01:19 +00:00
|
|
|
|
year, month_number, person_cache,
|
2022-06-14 11:52:43 +00:00
|
|
|
|
text_match)
|
2022-02-21 11:08:48 +00:00
|
|
|
|
|
2020-11-09 20:15:17 +00:00
|
|
|
|
events = \
|
2022-02-23 18:46:20 +00:00
|
|
|
|
get_calendar_events(base_dir, nickname, domain, year, month_number,
|
2024-01-22 16:49:23 +00:00
|
|
|
|
text_match, only_show_reminders)
|
2022-01-03 22:00:38 +00:00
|
|
|
|
|
|
|
|
|
prev_year = year
|
|
|
|
|
prev_month_number = month_number - 1
|
|
|
|
|
if prev_month_number < 1:
|
|
|
|
|
prev_month_number = 12
|
|
|
|
|
prev_year = year - 1
|
|
|
|
|
|
|
|
|
|
next_year = year
|
|
|
|
|
next_month_number = month_number + 1
|
|
|
|
|
if next_month_number > 12:
|
|
|
|
|
next_month_number = 1
|
|
|
|
|
next_year = year + 1
|
|
|
|
|
|
|
|
|
|
print('Calendar year=' + str(year) + ' month=' + str(month_number) +
|
|
|
|
|
' ' + str(week_day_of_month_start(month_number, year)))
|
|
|
|
|
|
|
|
|
|
if month_number < 12:
|
|
|
|
|
days_in_month = \
|
|
|
|
|
(date(year, month_number + 1, 1) -
|
|
|
|
|
date(year, month_number, 1)).days
|
2020-11-09 20:15:17 +00:00
|
|
|
|
else:
|
2022-01-03 22:00:38 +00:00
|
|
|
|
days_in_month = \
|
|
|
|
|
(date(year + 1, 1, 1) - date(year, month_number, 1)).days
|
|
|
|
|
# print('days_in_month ' + str(month_number) + ': ' + str(days_in_month))
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2021-12-31 21:18:12 +00:00
|
|
|
|
css_filename = base_dir + '/epicyon-calendar.css'
|
2021-12-25 16:17:53 +00:00
|
|
|
|
if os.path.isfile(base_dir + '/calendar.css'):
|
2021-12-31 21:18:12 +00:00
|
|
|
|
css_filename = base_dir + '/calendar.css'
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
cal_actor = actor
|
2020-11-09 20:15:17 +00:00
|
|
|
|
if '/users/' in actor:
|
2022-01-03 22:00:38 +00:00
|
|
|
|
cal_actor = '/users/' + actor.split('/users/')[1]
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
instance_title = \
|
2021-12-26 14:08:58 +00:00
|
|
|
|
get_config_param(base_dir, 'instanceTitle')
|
2022-01-03 22:00:38 +00:00
|
|
|
|
header_str = \
|
|
|
|
|
html_header_with_external_style(css_filename, instance_title, None)
|
2021-02-12 15:13:07 +00:00
|
|
|
|
|
2022-05-29 16:49:49 +00:00
|
|
|
|
# show banner
|
|
|
|
|
banner_file, _ = \
|
|
|
|
|
get_banner_file(base_dir, nickname, domain, theme)
|
|
|
|
|
calendar_str = \
|
2022-05-29 17:19:26 +00:00
|
|
|
|
'<header>\n<a href="/users/' + \
|
|
|
|
|
nickname + '/' + default_timeline + '" title="' + \
|
2022-05-29 16:49:49 +00:00
|
|
|
|
translate['Switch to timeline view'] + '" alt="' + \
|
|
|
|
|
translate['Switch to timeline view'] + '" ' + \
|
2022-05-29 16:57:01 +00:00
|
|
|
|
'tabindex="1" accesskey="' + \
|
2022-05-29 16:49:49 +00:00
|
|
|
|
access_keys['menuTimeline'] + '">\n'
|
|
|
|
|
calendar_str += '<img loading="lazy" decoding="async" ' + \
|
|
|
|
|
'class="timeline-banner" alt="" ' + \
|
|
|
|
|
'src="/users/' + nickname + '/' + banner_file + '" /></a>\n' + \
|
|
|
|
|
'</header>\n'
|
|
|
|
|
|
2021-02-12 15:13:07 +00:00
|
|
|
|
# the main graphical calendar as a table
|
2022-05-29 16:49:49 +00:00
|
|
|
|
calendar_str += '<main>\n<center>\n<p class="calendar__banner--month">\n'
|
2022-05-25 18:00:33 +00:00
|
|
|
|
# previous month
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += \
|
|
|
|
|
' <a href="' + cal_actor + '/calendar?year=' + str(prev_year) + \
|
2024-01-22 16:49:23 +00:00
|
|
|
|
'?month=' + str(prev_month_number) + \
|
|
|
|
|
'?onlyShowReminders=' + str(only_show_reminders) + '" ' + \
|
2022-05-25 16:06:05 +00:00
|
|
|
|
'accesskey="' + access_keys['Page up'] + \
|
|
|
|
|
'" tabindex="2" class="imageAnchor">'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += \
|
2022-03-28 08:47:53 +00:00
|
|
|
|
' <img loading="lazy" decoding="async" ' + \
|
|
|
|
|
'alt="' + translate['Previous month'] + \
|
2020-12-09 13:08:26 +00:00
|
|
|
|
'" title="' + translate['Previous month'] + '" src="/icons' + \
|
2020-11-09 20:15:17 +00:00
|
|
|
|
'/prev.png" class="buttonprev"/></a>\n'
|
2022-05-25 18:00:33 +00:00
|
|
|
|
# header
|
2022-05-25 16:06:05 +00:00
|
|
|
|
calendar_str += \
|
2022-05-25 16:55:48 +00:00
|
|
|
|
' <a href="' + cal_actor + '/' + default_timeline + '" title="'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += translate['Switch to timeline view'] + '" ' + \
|
2022-05-25 16:06:05 +00:00
|
|
|
|
'accesskey="' + access_keys['menuTimeline'] + \
|
2022-05-25 18:00:33 +00:00
|
|
|
|
'" tabindex="1" class="imageAnchor">'
|
2022-05-23 16:11:35 +00:00
|
|
|
|
calendar_str += \
|
2022-05-25 18:00:33 +00:00
|
|
|
|
' <label class="calheader"><time datetime="' + \
|
2022-05-23 16:11:35 +00:00
|
|
|
|
str(year) + '-' + str(month_number) + '">' + month_name + \
|
2022-05-25 18:00:33 +00:00
|
|
|
|
'</time></label></a>\n'
|
|
|
|
|
# next month
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += \
|
|
|
|
|
' <a href="' + cal_actor + '/calendar?year=' + str(next_year) + \
|
2024-01-22 16:49:23 +00:00
|
|
|
|
'?month=' + str(next_month_number) + \
|
|
|
|
|
'?onlyShowReminders=' + str(only_show_reminders) + '" ' + \
|
2022-05-25 16:06:05 +00:00
|
|
|
|
'accesskey="' + access_keys['Page down'] + \
|
|
|
|
|
'" tabindex="2" class="imageAnchor">'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += \
|
2022-03-28 08:47:53 +00:00
|
|
|
|
' <img loading="lazy" decoding="async" ' + \
|
|
|
|
|
'alt="' + translate['Next month'] + \
|
2020-12-09 13:08:26 +00:00
|
|
|
|
'" title="' + translate['Next month'] + '" src="/icons' + \
|
2020-11-09 20:15:17 +00:00
|
|
|
|
'/prev.png" class="buttonnext"/></a>\n'
|
2022-05-25 18:00:33 +00:00
|
|
|
|
# calendar table
|
2022-05-25 17:45:58 +00:00
|
|
|
|
calendar_str += '</p>\n</center>\n<table class="calendar">\n'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += '<thead>\n'
|
|
|
|
|
calendar_str += '<tr>\n'
|
2021-07-05 19:35:57 +00:00
|
|
|
|
days = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
|
2022-01-03 22:00:38 +00:00
|
|
|
|
for day in days:
|
|
|
|
|
calendar_str += ' <th scope="col" class="calendar__day__header">' + \
|
|
|
|
|
translate[day] + '</th>\n'
|
|
|
|
|
calendar_str += '</tr>\n'
|
|
|
|
|
calendar_str += '</thead>\n'
|
|
|
|
|
calendar_str += '<tbody>\n'
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2021-02-12 15:13:07 +00:00
|
|
|
|
# beginning of the links used for accessibility
|
2021-12-31 21:18:12 +00:00
|
|
|
|
nav_links = {}
|
2022-01-03 22:00:38 +00:00
|
|
|
|
timeline_link_str = html_hide_from_screen_reader('🏠') + ' ' + \
|
2021-02-12 15:13:07 +00:00
|
|
|
|
translate['Switch to timeline view']
|
2022-06-03 21:03:39 +00:00
|
|
|
|
nav_links[timeline_link_str] = cal_actor + '/' + default_timeline
|
2021-02-12 15:13:07 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
day_of_month = 0
|
|
|
|
|
dow = week_day_of_month_start(month_number, year)
|
|
|
|
|
for week_of_month in range(1, 7):
|
|
|
|
|
if day_of_month == days_in_month:
|
2020-11-09 20:15:17 +00:00
|
|
|
|
continue
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += ' <tr>\n'
|
|
|
|
|
for day_number in range(1, 8):
|
2024-07-16 09:59:06 +00:00
|
|
|
|
if not ((week_of_month > 1 and day_of_month < days_in_month) or
|
|
|
|
|
(week_of_month == 1 and day_number >= dow)):
|
|
|
|
|
calendar_str += ' <td class="calendar__day__cell"></td>\n'
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
day_of_month += 1
|
|
|
|
|
|
|
|
|
|
is_today = False
|
|
|
|
|
if year == curr_date.year:
|
|
|
|
|
if curr_date.month == month_number:
|
|
|
|
|
if day_of_month == curr_date.day:
|
|
|
|
|
is_today = True
|
2024-07-16 10:06:35 +00:00
|
|
|
|
|
2024-07-16 09:59:06 +00:00
|
|
|
|
if events.get(str(day_of_month)):
|
|
|
|
|
url = cal_actor + '/calendar?year=' + \
|
|
|
|
|
str(year) + '?month=' + \
|
|
|
|
|
str(month_number) + '?day=' + str(day_of_month)
|
|
|
|
|
day_description = month_name + ' ' + str(day_of_month)
|
|
|
|
|
datetime_str = \
|
|
|
|
|
str(year) + '-' + str(month_number) + '-' + \
|
|
|
|
|
str(day_of_month)
|
|
|
|
|
day_link = '<a href="' + url + '" ' + \
|
|
|
|
|
'title="' + day_description + '" tabindex="2">' + \
|
|
|
|
|
'<time datetime="' + datetime_str + '">' + \
|
|
|
|
|
str(day_of_month) + '</time></a>'
|
|
|
|
|
# accessibility menu links
|
|
|
|
|
menu_option_str = \
|
|
|
|
|
html_hide_from_screen_reader('📅') + ' ' + \
|
|
|
|
|
'<time datetime="' + datetime_str + '">' + \
|
|
|
|
|
day_description + '</time>'
|
|
|
|
|
nav_links[menu_option_str] = url
|
|
|
|
|
# there are events for this day
|
|
|
|
|
if not is_today:
|
|
|
|
|
calendar_str += \
|
|
|
|
|
' <td class="calendar__day__cell" ' + \
|
2024-07-16 10:06:35 +00:00
|
|
|
|
'data-event="">' + day_link + '</td>\n'
|
2020-11-09 20:15:17 +00:00
|
|
|
|
else:
|
2024-07-16 09:59:06 +00:00
|
|
|
|
calendar_str += \
|
|
|
|
|
' <td class="calendar__day__cell" ' + \
|
2024-07-16 10:06:35 +00:00
|
|
|
|
'data-today-event="">' + day_link + '</td>\n'
|
2020-11-09 20:15:17 +00:00
|
|
|
|
else:
|
2024-07-16 09:59:06 +00:00
|
|
|
|
# No events today
|
|
|
|
|
if not is_today:
|
|
|
|
|
calendar_str += \
|
|
|
|
|
' <td class="calendar__day__cell">' + \
|
|
|
|
|
str(day_of_month) + '</td>\n'
|
|
|
|
|
else:
|
|
|
|
|
calendar_str += \
|
|
|
|
|
' <td class="calendar__day__cell" ' + \
|
|
|
|
|
'data-today="">' + str(day_of_month) + '</td>\n'
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += ' </tr>\n'
|
2020-11-09 20:15:17 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
calendar_str += '</tbody>\n'
|
2022-05-25 17:44:11 +00:00
|
|
|
|
calendar_str += '</table>\n</main>\n'
|
2021-02-12 15:13:07 +00:00
|
|
|
|
|
|
|
|
|
# end of the links used for accessibility
|
2022-01-03 22:00:38 +00:00
|
|
|
|
next_month_str = \
|
2021-12-29 21:55:09 +00:00
|
|
|
|
html_hide_from_screen_reader('→') + ' ' + translate['Next month']
|
2022-01-03 22:00:38 +00:00
|
|
|
|
nav_links[next_month_str] = \
|
|
|
|
|
cal_actor + '/calendar?year=' + str(next_year) + \
|
|
|
|
|
'?month=' + str(next_month_number)
|
|
|
|
|
prev_month_str = \
|
2021-12-29 21:55:09 +00:00
|
|
|
|
html_hide_from_screen_reader('←') + ' ' + translate['Previous month']
|
2022-01-03 22:00:38 +00:00
|
|
|
|
nav_links[prev_month_str] = \
|
|
|
|
|
cal_actor + '/calendar?year=' + str(prev_year) + \
|
|
|
|
|
'?month=' + str(prev_month_number)
|
2021-12-31 21:18:12 +00:00
|
|
|
|
nav_access_keys = {
|
2021-04-22 11:51:19 +00:00
|
|
|
|
}
|
2022-01-03 22:00:38 +00:00
|
|
|
|
screen_reader_cal = \
|
2021-12-31 21:18:12 +00:00
|
|
|
|
html_keyboard_navigation(text_mode_banner, nav_links, nav_access_keys,
|
2024-02-19 18:31:04 +00:00
|
|
|
|
month_name, None, None, False)
|
2021-02-12 15:13:07 +00:00
|
|
|
|
|
2024-01-22 16:49:23 +00:00
|
|
|
|
if not only_show_reminders:
|
|
|
|
|
show_reminders_link = \
|
|
|
|
|
'<a href="' + cal_actor + '/calendar?year=' + str(year) + \
|
|
|
|
|
'?month=' + str(month_number) + \
|
|
|
|
|
'?onlyShowReminders=true" ' + \
|
|
|
|
|
'tabindex="2" class="imageAnchor">' + \
|
2024-01-22 16:59:45 +00:00
|
|
|
|
translate['Only show reminders'] + '</a>'
|
2024-01-22 16:49:23 +00:00
|
|
|
|
else:
|
|
|
|
|
show_reminders_link = \
|
|
|
|
|
'<a href="' + cal_actor + '/calendar?year=' + str(year) + \
|
|
|
|
|
'?month=' + str(month_number) + \
|
|
|
|
|
'?onlyShowReminders=false" ' + \
|
|
|
|
|
'tabindex="2" class="imageAnchor">' + \
|
2024-01-22 16:59:45 +00:00
|
|
|
|
translate['Show all events'] + '</a>'
|
2024-01-22 16:49:23 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
new_event_str = \
|
2021-11-03 16:43:41 +00:00
|
|
|
|
'<br><center>\n<p>\n' + \
|
2022-12-03 09:54:39 +00:00
|
|
|
|
'<a href="' + cal_actor + '/newreminder' + \
|
|
|
|
|
'" tabindex="2">➕ ' + \
|
2024-01-22 16:59:45 +00:00
|
|
|
|
translate['Add to the calendar'] + '</a></p>\n<p>' + \
|
2024-01-22 16:49:23 +00:00
|
|
|
|
show_reminders_link + '</p>\n</center>\n'
|
2021-11-03 16:41:23 +00:00
|
|
|
|
|
2024-08-14 11:37:38 +00:00
|
|
|
|
# NOTE: don't use download="preferredfilename" which is
|
|
|
|
|
# unsupported by some browsers
|
2022-02-21 11:49:12 +00:00
|
|
|
|
calendar_icon_str = \
|
2022-02-21 17:43:55 +00:00
|
|
|
|
' <a href="' + path + '?ical=true" ' + \
|
2024-08-14 11:37:38 +00:00
|
|
|
|
'download class="imageAnchor" tabindex="3">' + \
|
2022-02-21 11:40:14 +00:00
|
|
|
|
'<img class="ical" src="/icons/ical.png" ' + \
|
|
|
|
|
'title="iCalendar" alt="iCalendar" /></a>\n'
|
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
cal_str = \
|
|
|
|
|
header_str + screen_reader_cal + calendar_str + \
|
2022-02-21 11:40:14 +00:00
|
|
|
|
new_event_str + calendar_icon_str + html_footer()
|
2021-11-03 16:41:23 +00:00
|
|
|
|
|
2022-01-03 22:00:38 +00:00
|
|
|
|
return cal_str
|