Merge branch 'main' of gitlab.com:bashrc2/epicyon
60
daemon.py
|
@ -679,6 +679,16 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _request_icalendar(self) -> bool:
|
||||||
|
"""Should an icalendar response be given?
|
||||||
|
"""
|
||||||
|
if not self.headers.get('Accept'):
|
||||||
|
return False
|
||||||
|
accept_str = self.headers['Accept']
|
||||||
|
if 'text/calendar' in accept_str:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def _signed_ge_tkey_id(self) -> str:
|
def _signed_ge_tkey_id(self) -> str:
|
||||||
"""Returns the actor from the signed GET key_id
|
"""Returns the actor from the signed GET key_id
|
||||||
"""
|
"""
|
||||||
|
@ -14056,9 +14066,12 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# is this a html request?
|
# is this a html request?
|
||||||
html_getreq = False
|
html_getreq = False
|
||||||
|
icalendar_getreq = False
|
||||||
if self._has_accept(calling_domain):
|
if self._has_accept(calling_domain):
|
||||||
if self._request_http():
|
if self._request_http():
|
||||||
html_getreq = True
|
html_getreq = True
|
||||||
|
elif self._request_icalendar():
|
||||||
|
icalendar_getreq = True
|
||||||
else:
|
else:
|
||||||
if self.headers.get('Connection'):
|
if self.headers.get('Connection'):
|
||||||
# https://developer.mozilla.org/en-US/
|
# https://developer.mozilla.org/en-US/
|
||||||
|
@ -15532,7 +15545,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
'_GET', 'search screen shown done',
|
'_GET', 'search screen shown done',
|
||||||
self.server.debug)
|
self.server.debug)
|
||||||
|
|
||||||
# Show the calendar for a user
|
# Show the html calendar for a user
|
||||||
if html_getreq and users_in_path:
|
if html_getreq and users_in_path:
|
||||||
if '/calendar' in self.path:
|
if '/calendar' in self.path:
|
||||||
nickname = self.path.split('/users/')[1]
|
nickname = self.path.split('/users/')[1]
|
||||||
|
@ -15551,10 +15564,17 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.http_prefix,
|
self.server.http_prefix,
|
||||||
self.server.domain_full,
|
self.server.domain_full,
|
||||||
self.server.text_mode_banner,
|
self.server.text_mode_banner,
|
||||||
access_keys).encode('utf-8')
|
access_keys,
|
||||||
|
False).encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
self._set_headers('text/html', msglen, cookie, calling_domain,
|
if 'ical=true' in self.path:
|
||||||
False)
|
self._set_headers('text/calendar',
|
||||||
|
msglen, cookie, calling_domain,
|
||||||
|
False)
|
||||||
|
else:
|
||||||
|
self._set_headers('text/html',
|
||||||
|
msglen, cookie, calling_domain,
|
||||||
|
False)
|
||||||
self._write(msg)
|
self._write(msg)
|
||||||
fitness_performance(getreq_start_time, self.server.fitness,
|
fitness_performance(getreq_start_time, self.server.fitness,
|
||||||
'_GET', 'calendar shown',
|
'_GET', 'calendar shown',
|
||||||
|
@ -15562,6 +15582,38 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.getreq_busy = False
|
self.server.getreq_busy = False
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Show the icalendar for a user
|
||||||
|
if icalendar_getreq and users_in_path:
|
||||||
|
if '/calendar' in self.path:
|
||||||
|
nickname = self.path.split('/users/')[1]
|
||||||
|
if '/' in nickname:
|
||||||
|
nickname = nickname.split('/')[0]
|
||||||
|
|
||||||
|
access_keys = self.server.access_keys
|
||||||
|
if self.server.key_shortcuts.get(nickname):
|
||||||
|
access_keys = self.server.key_shortcuts[nickname]
|
||||||
|
|
||||||
|
# show the calendar screen
|
||||||
|
msg = html_calendar(self.server.person_cache,
|
||||||
|
self.server.css_cache,
|
||||||
|
self.server.translate,
|
||||||
|
self.server.base_dir, self.path,
|
||||||
|
self.server.http_prefix,
|
||||||
|
self.server.domain_full,
|
||||||
|
self.server.text_mode_banner,
|
||||||
|
access_keys,
|
||||||
|
True).encode('utf-8')
|
||||||
|
msglen = len(msg)
|
||||||
|
self._set_headers('text/calendar',
|
||||||
|
msglen, cookie, calling_domain,
|
||||||
|
False)
|
||||||
|
self._write(msg)
|
||||||
|
fitness_performance(getreq_start_time, self.server.fitness,
|
||||||
|
'_GET', 'icalendar shown',
|
||||||
|
self.server.debug)
|
||||||
|
self.server.getreq_busy = False
|
||||||
|
return
|
||||||
|
|
||||||
fitness_performance(getreq_start_time, self.server.fitness,
|
fitness_performance(getreq_start_time, self.server.fitness,
|
||||||
'_GET', 'calendar shown done',
|
'_GET', 'calendar shown done',
|
||||||
self.server.debug)
|
self.server.debug)
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
--calendar-header-font-style: italic;
|
--calendar-header-font-style: italic;
|
||||||
--main-link-color-hover: blue;
|
--main-link-color-hover: blue;
|
||||||
--rendering: normal;
|
--rendering: normal;
|
||||||
|
--ical-icon-size: 32px;
|
||||||
|
--ical-icon-size-mobile: 80px;
|
||||||
|
--ical-icon-size-tiny: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
|
@ -256,6 +259,10 @@ tr:nth-child(even) > .calendar__day__cell:nth-child(even) {
|
||||||
body {
|
body {
|
||||||
font-size: var(--font-size-calendar);
|
font-size: var(--font-size-calendar);
|
||||||
}
|
}
|
||||||
|
body img.ical {
|
||||||
|
width: var(--ical-icon-size);
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1000px) {
|
@media screen and (max-width: 1000px) {
|
||||||
|
@ -276,6 +283,10 @@ tr:nth-child(even) > .calendar__day__cell:nth-child(even) {
|
||||||
body {
|
body {
|
||||||
font-size: var(--font-size-calendar-mobile);
|
font-size: var(--font-size-calendar-mobile);
|
||||||
}
|
}
|
||||||
|
body img.ical {
|
||||||
|
width: var(--ical-icon-size-mobile);
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 480px) {
|
@media screen and (max-width: 480px) {
|
||||||
|
@ -296,4 +307,8 @@ tr:nth-child(even) > .calendar__day__cell:nth-child(even) {
|
||||||
body {
|
body {
|
||||||
font-size: var(--font-size-calendar-tiny);
|
font-size: var(--font-size-calendar-tiny);
|
||||||
}
|
}
|
||||||
|
body img.ical {
|
||||||
|
width: var(--ical-icon-size-tiny);
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
225
happening.py
|
@ -18,6 +18,8 @@ from utils import save_json
|
||||||
from utils import locate_post
|
from utils import locate_post
|
||||||
from utils import has_object_dict
|
from utils import has_object_dict
|
||||||
from utils import acct_dir
|
from utils import acct_dir
|
||||||
|
from utils import remove_html
|
||||||
|
from utils import get_display_name
|
||||||
|
|
||||||
|
|
||||||
def _valid_uuid(test_uuid: str, version: int):
|
def _valid_uuid(test_uuid: str, version: int):
|
||||||
|
@ -175,24 +177,24 @@ def _is_happening_post(post_json_object: {}) -> bool:
|
||||||
|
|
||||||
|
|
||||||
def get_todays_events(base_dir: str, nickname: str, domain: str,
|
def get_todays_events(base_dir: str, nickname: str, domain: str,
|
||||||
currYear: int, currMonthNumber: int,
|
curr_year: int, curr_month_number: int,
|
||||||
currDayOfMonth: int) -> {}:
|
curr_day_of_month: int) -> {}:
|
||||||
"""Retrieves calendar events for today
|
"""Retrieves calendar events for today
|
||||||
Returns a dictionary of lists containing Event and Place activities
|
Returns a dictionary of lists containing Event and Place activities
|
||||||
"""
|
"""
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
if not currYear:
|
if not curr_year:
|
||||||
year = now.year
|
year = now.year
|
||||||
else:
|
else:
|
||||||
year = currYear
|
year = curr_year
|
||||||
if not currMonthNumber:
|
if not curr_month_number:
|
||||||
month_number = now.month
|
month_number = now.month
|
||||||
else:
|
else:
|
||||||
month_number = currMonthNumber
|
month_number = curr_month_number
|
||||||
if not currDayOfMonth:
|
if not curr_day_of_month:
|
||||||
day_number = now.day
|
day_number = now.day
|
||||||
else:
|
else:
|
||||||
day_number = currDayOfMonth
|
day_number = curr_day_of_month
|
||||||
|
|
||||||
calendar_filename = \
|
calendar_filename = \
|
||||||
acct_dir(base_dir, nickname, domain) + \
|
acct_dir(base_dir, nickname, domain) + \
|
||||||
|
@ -238,6 +240,7 @@ def get_todays_events(base_dir: str, nickname: str, domain: str,
|
||||||
# link to the id so that the event can be
|
# link to the id so that the event can be
|
||||||
# easily deleted
|
# easily deleted
|
||||||
tag['post_id'] = post_id.split('#statuses#')[1]
|
tag['post_id'] = post_id.split('#statuses#')[1]
|
||||||
|
tag['id'] = post_id.replace('#', '/')
|
||||||
tag['sender'] = post_id.split('#statuses#')[0]
|
tag['sender'] = post_id.split('#statuses#')[0]
|
||||||
tag['sender'] = tag['sender'].replace('#', '/')
|
tag['sender'] = tag['sender'].replace('#', '/')
|
||||||
tag['public'] = public_event
|
tag['public'] = public_event
|
||||||
|
@ -263,13 +266,206 @@ def get_todays_events(base_dir: str, nickname: str, domain: str,
|
||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
|
def _ical_date_string(date_str: str) -> str:
|
||||||
|
"""Returns an icalendar formatted date
|
||||||
|
"""
|
||||||
|
date_str = date_str.replace('-', '')
|
||||||
|
date_str = date_str.replace(':', '')
|
||||||
|
return date_str.replace(' ', '')
|
||||||
|
|
||||||
|
|
||||||
|
def _icalendar_day(base_dir: str, nickname: str, domain: str,
|
||||||
|
day_events: [], person_cache: {},
|
||||||
|
http_prefix: str) -> str:
|
||||||
|
"""Returns a day's events in icalendar format
|
||||||
|
"""
|
||||||
|
ical_str = ''
|
||||||
|
print('icalendar: ' + str(day_events))
|
||||||
|
for event_post in day_events:
|
||||||
|
event_description = None
|
||||||
|
event_place = None
|
||||||
|
post_id = None
|
||||||
|
sender_name = ''
|
||||||
|
sender_actor = None
|
||||||
|
event_is_public = False
|
||||||
|
event_start = None
|
||||||
|
event_end = None
|
||||||
|
|
||||||
|
for evnt in event_post:
|
||||||
|
if evnt['type'] == 'Event':
|
||||||
|
if evnt.get('id'):
|
||||||
|
post_id = evnt['id']
|
||||||
|
if evnt.get('startTime'):
|
||||||
|
event_start = \
|
||||||
|
datetime.strptime(evnt['startTime'],
|
||||||
|
"%Y-%m-%dT%H:%M:%S%z")
|
||||||
|
if evnt.get('endTime'):
|
||||||
|
event_end = \
|
||||||
|
datetime.strptime(evnt['startTime'],
|
||||||
|
"%Y-%m-%dT%H:%M:%S%z")
|
||||||
|
if 'public' in evnt:
|
||||||
|
if evnt['public'] is True:
|
||||||
|
event_is_public = True
|
||||||
|
if evnt.get('sender'):
|
||||||
|
# get display name from sending actor
|
||||||
|
if evnt.get('sender'):
|
||||||
|
sender_actor = evnt['sender']
|
||||||
|
disp_name = \
|
||||||
|
get_display_name(base_dir, sender_actor,
|
||||||
|
person_cache)
|
||||||
|
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'):
|
||||||
|
event_place = evnt['name']
|
||||||
|
|
||||||
|
print('icalendar: ' + str(post_id) + ' ' +
|
||||||
|
str(event_start) + ' ' + str(event_description) + ' ' +
|
||||||
|
str(sender_actor))
|
||||||
|
|
||||||
|
if not post_id or not event_start or not event_end or \
|
||||||
|
not event_description or not sender_actor:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# find the corresponding post
|
||||||
|
post_filename = locate_post(base_dir, nickname, domain, post_id)
|
||||||
|
if not post_filename:
|
||||||
|
continue
|
||||||
|
|
||||||
|
post_json_object = load_json(post_filename)
|
||||||
|
if not post_json_object:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# get the published date from the post
|
||||||
|
if not post_json_object.get('object'):
|
||||||
|
continue
|
||||||
|
if not isinstance(post_json_object['object'], dict):
|
||||||
|
continue
|
||||||
|
if not post_json_object['object'].get('published'):
|
||||||
|
continue
|
||||||
|
if not isinstance(post_json_object['object']['published'], str):
|
||||||
|
continue
|
||||||
|
published = \
|
||||||
|
_ical_date_string(post_json_object['object']['published'])
|
||||||
|
|
||||||
|
event_start = \
|
||||||
|
_ical_date_string(event_start.strftime("%Y-%m-%dT%H:%M:%SZ"))
|
||||||
|
event_end = \
|
||||||
|
_ical_date_string(event_end.strftime("%Y-%m-%dT%H:%M:%SZ"))
|
||||||
|
|
||||||
|
ical_str += \
|
||||||
|
'BEGIN:VEVENT\n' + \
|
||||||
|
'DTSTAMP:' + published + '\n' + \
|
||||||
|
'UID:' + post_id + '\n' + \
|
||||||
|
'DTSTART:' + event_start + '\n' + \
|
||||||
|
'DTEND:' + event_end + '\n' + \
|
||||||
|
'STATUS:CONFIRMED\n'
|
||||||
|
descr = remove_html(event_description)
|
||||||
|
if len(descr) < 255:
|
||||||
|
ical_str += \
|
||||||
|
'SUMMARY:' + descr + '\n'
|
||||||
|
else:
|
||||||
|
ical_str += \
|
||||||
|
'SUMMARY:' + descr[255:] + '\n'
|
||||||
|
ical_str += \
|
||||||
|
'DESCRIPTION:' + descr + '\n'
|
||||||
|
if event_is_public:
|
||||||
|
ical_str += \
|
||||||
|
'CATEGORIES:APPOINTMENT,PUBLIC\n'
|
||||||
|
else:
|
||||||
|
ical_str += \
|
||||||
|
'CATEGORIES:APPOINTMENT\n'
|
||||||
|
if sender_name:
|
||||||
|
ical_str += \
|
||||||
|
'ORGANIZER;CN=' + remove_html(sender_name) + ':' + \
|
||||||
|
sender_actor + '\n'
|
||||||
|
else:
|
||||||
|
ical_str += \
|
||||||
|
'ORGANIZER:' + sender_actor + '\n'
|
||||||
|
if event_place:
|
||||||
|
ical_str += \
|
||||||
|
'LOCATION:' + remove_html(event_place) + '\n'
|
||||||
|
ical_str += 'END:VEVENT\n'
|
||||||
|
return ical_str
|
||||||
|
|
||||||
|
|
||||||
|
def get_todays_events_icalendar(base_dir: str, nickname: str, domain: str,
|
||||||
|
year: int, month_number: int,
|
||||||
|
day_number: int, person_cache: {},
|
||||||
|
http_prefix: str) -> str:
|
||||||
|
"""Returns today's events in icalendar format
|
||||||
|
"""
|
||||||
|
day_events = None
|
||||||
|
events = \
|
||||||
|
get_todays_events(base_dir, nickname, domain,
|
||||||
|
year, month_number, day_number)
|
||||||
|
if events:
|
||||||
|
if events.get(str(day_number)):
|
||||||
|
day_events = events[str(day_number)]
|
||||||
|
|
||||||
|
ical_str = \
|
||||||
|
'BEGIN:VCALENDAR\n' + \
|
||||||
|
'PRODID:-//Fediverse//NONSGML Epicyon//EN\n' + \
|
||||||
|
'VERSION:2.0\n'
|
||||||
|
if not day_events:
|
||||||
|
print('icalendar daily: ' + nickname + '@' + domain + ' ' +
|
||||||
|
str(year) + '-' + str(month_number) +
|
||||||
|
'-' + str(day_number) + ' ' + str(day_events))
|
||||||
|
ical_str += 'END:VCALENDAR\n'
|
||||||
|
return ical_str
|
||||||
|
|
||||||
|
ical_str += \
|
||||||
|
_icalendar_day(base_dir, nickname, domain, day_events, person_cache,
|
||||||
|
http_prefix)
|
||||||
|
|
||||||
|
ical_str += 'END:VCALENDAR\n'
|
||||||
|
return ical_str
|
||||||
|
|
||||||
|
|
||||||
|
def get_month_events_icalendar(base_dir: str, nickname: str, domain: str,
|
||||||
|
year: int,
|
||||||
|
month_number: int,
|
||||||
|
person_cache: {},
|
||||||
|
http_prefix: str) -> str:
|
||||||
|
"""Returns today's events in icalendar format
|
||||||
|
"""
|
||||||
|
month_events = \
|
||||||
|
get_calendar_events(base_dir, nickname, domain, year,
|
||||||
|
month_number)
|
||||||
|
|
||||||
|
ical_str = \
|
||||||
|
'BEGIN:VCALENDAR\n' + \
|
||||||
|
'PRODID:-//Fediverse//NONSGML Epicyon//EN\n' + \
|
||||||
|
'VERSION:2.0\n'
|
||||||
|
if not month_events:
|
||||||
|
ical_str += 'END:VCALENDAR\n'
|
||||||
|
return ical_str
|
||||||
|
|
||||||
|
print('icalendar month: ' + str(month_events))
|
||||||
|
for day_of_month in range(1, 32):
|
||||||
|
if not month_events.get(str(day_of_month)):
|
||||||
|
continue
|
||||||
|
day_events = month_events[str(day_of_month)]
|
||||||
|
ical_str += \
|
||||||
|
_icalendar_day(base_dir, nickname, domain,
|
||||||
|
day_events, person_cache,
|
||||||
|
http_prefix)
|
||||||
|
|
||||||
|
ical_str += 'END:VCALENDAR\n'
|
||||||
|
return ical_str
|
||||||
|
|
||||||
|
|
||||||
def day_events_check(base_dir: str, nickname: str, domain: str,
|
def day_events_check(base_dir: str, nickname: str, domain: str,
|
||||||
currDate) -> bool:
|
curr_date) -> bool:
|
||||||
"""Are there calendar events for the given date?
|
"""Are there calendar events for the given date?
|
||||||
"""
|
"""
|
||||||
year = currDate.year
|
year = curr_date.year
|
||||||
month_number = currDate.month
|
month_number = curr_date.month
|
||||||
day_number = currDate.day
|
day_number = curr_date.day
|
||||||
|
|
||||||
calendar_filename = \
|
calendar_filename = \
|
||||||
acct_dir(base_dir, nickname, domain) + \
|
acct_dir(base_dir, nickname, domain) + \
|
||||||
|
@ -427,6 +623,11 @@ def get_calendar_events(base_dir: str, nickname: str, domain: str,
|
||||||
if int(event_time.strftime("%Y")) == year and \
|
if int(event_time.strftime("%Y")) == year and \
|
||||||
int(event_time.strftime("%m")) == month_number:
|
int(event_time.strftime("%m")) == month_number:
|
||||||
day_of_month = str(int(event_time.strftime("%d")))
|
day_of_month = str(int(event_time.strftime("%d")))
|
||||||
|
if '#statuses#' in post_id:
|
||||||
|
tag['post_id'] = post_id.split('#statuses#')[1]
|
||||||
|
tag['id'] = post_id.replace('#', '/')
|
||||||
|
tag['sender'] = post_id.split('#statuses#')[0]
|
||||||
|
tag['sender'] = tag['sender'].replace('#', '/')
|
||||||
post_event.append(tag)
|
post_event.append(tag)
|
||||||
else:
|
else:
|
||||||
# tag is a place
|
# tag is a place
|
||||||
|
|
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 9.2 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 9.2 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 11 KiB |
|
@ -24,6 +24,8 @@ from utils import local_actor_url
|
||||||
from utils import replace_users_with_at
|
from utils import replace_users_with_at
|
||||||
from happening import get_todays_events
|
from happening import get_todays_events
|
||||||
from happening import get_calendar_events
|
from happening import get_calendar_events
|
||||||
|
from happening import get_todays_events_icalendar
|
||||||
|
from happening import get_month_events_icalendar
|
||||||
from webapp_utils import set_custom_background
|
from webapp_utils import set_custom_background
|
||||||
from webapp_utils import html_header_with_external_style
|
from webapp_utils import html_header_with_external_style
|
||||||
from webapp_utils import html_footer
|
from webapp_utils import html_footer
|
||||||
|
@ -243,6 +245,14 @@ def _html_calendar_day(person_cache: {}, css_cache: {}, translate: {},
|
||||||
|
|
||||||
calendar_str += '</tbody>\n'
|
calendar_str += '</tbody>\n'
|
||||||
calendar_str += '</table></main>\n'
|
calendar_str += '</table></main>\n'
|
||||||
|
|
||||||
|
# icalendar download link
|
||||||
|
calendar_str += \
|
||||||
|
' <a href="' + path + '?ical=true" ' + \
|
||||||
|
'download="icalendar.ics">' + \
|
||||||
|
'<img class="ical" src="/icons/ical.png" ' + \
|
||||||
|
'title="iCalendar" alt="iCalendar" /></a>\n'
|
||||||
|
|
||||||
calendar_str += html_footer()
|
calendar_str += html_footer()
|
||||||
|
|
||||||
return calendar_str
|
return calendar_str
|
||||||
|
@ -251,14 +261,17 @@ def _html_calendar_day(person_cache: {}, css_cache: {}, translate: {},
|
||||||
def html_calendar(person_cache: {}, css_cache: {}, translate: {},
|
def html_calendar(person_cache: {}, css_cache: {}, translate: {},
|
||||||
base_dir: str, path: str,
|
base_dir: str, path: str,
|
||||||
http_prefix: str, domain_full: str,
|
http_prefix: str, domain_full: str,
|
||||||
text_mode_banner: str, access_keys: {}) -> str:
|
text_mode_banner: str, access_keys: {},
|
||||||
|
icalendar: bool) -> str:
|
||||||
"""Show the calendar for a person
|
"""Show the calendar for a person
|
||||||
"""
|
"""
|
||||||
domain = remove_domain_port(domain_full)
|
domain = remove_domain_port(domain_full)
|
||||||
|
|
||||||
month_number = 0
|
default_year = 1970
|
||||||
|
default_month = 0
|
||||||
|
month_number = default_month
|
||||||
day_number = None
|
day_number = None
|
||||||
year = 1970
|
year = default_year
|
||||||
actor = http_prefix + '://' + domain_full + path.replace('/calendar', '')
|
actor = http_prefix + '://' + domain_full + path.replace('/calendar', '')
|
||||||
if '?' in actor:
|
if '?' in actor:
|
||||||
first = True
|
first = True
|
||||||
|
@ -277,11 +290,15 @@ def html_calendar(person_cache: {}, css_cache: {}, translate: {},
|
||||||
num_str = part.split('=')[1]
|
num_str = part.split('=')[1]
|
||||||
if num_str.isdigit():
|
if num_str.isdigit():
|
||||||
day_number = int(num_str)
|
day_number = int(num_str)
|
||||||
|
elif part.split('=')[0] == 'ical':
|
||||||
|
bool_str = part.split('=')[1]
|
||||||
|
if bool_str.lower().startswith('t'):
|
||||||
|
icalendar = True
|
||||||
first = False
|
first = False
|
||||||
actor = actor.split('?')[0]
|
actor = actor.split('?')[0]
|
||||||
|
|
||||||
curr_date = datetime.now()
|
curr_date = datetime.now()
|
||||||
if year == 1970 and month_number == 0:
|
if year == default_year and month_number == default_month:
|
||||||
year = curr_date.year
|
year = curr_date.year
|
||||||
month_number = curr_date.month
|
month_number = curr_date.month
|
||||||
|
|
||||||
|
@ -297,6 +314,13 @@ def html_calendar(person_cache: {}, css_cache: {}, translate: {},
|
||||||
month_name = translate[months[month_number - 1]]
|
month_name = translate[months[month_number - 1]]
|
||||||
|
|
||||||
if day_number:
|
if day_number:
|
||||||
|
if icalendar:
|
||||||
|
return get_todays_events_icalendar(base_dir,
|
||||||
|
nickname, domain,
|
||||||
|
year, month_number,
|
||||||
|
day_number,
|
||||||
|
person_cache,
|
||||||
|
http_prefix)
|
||||||
day_events = None
|
day_events = None
|
||||||
events = \
|
events = \
|
||||||
get_todays_events(base_dir, nickname, domain,
|
get_todays_events(base_dir, nickname, domain,
|
||||||
|
@ -310,6 +334,11 @@ def html_calendar(person_cache: {}, css_cache: {}, translate: {},
|
||||||
nickname, domain, day_events,
|
nickname, domain, day_events,
|
||||||
month_name, actor)
|
month_name, actor)
|
||||||
|
|
||||||
|
if icalendar:
|
||||||
|
return get_month_events_icalendar(base_dir, nickname, domain,
|
||||||
|
year, month_number, person_cache,
|
||||||
|
http_prefix)
|
||||||
|
|
||||||
events = \
|
events = \
|
||||||
get_calendar_events(base_dir, nickname, domain, year, month_number)
|
get_calendar_events(base_dir, nickname, domain, year, month_number)
|
||||||
|
|
||||||
|
@ -469,8 +498,14 @@ def html_calendar(person_cache: {}, css_cache: {}, translate: {},
|
||||||
'<a href="' + cal_actor + '/newreminder">➕ ' + \
|
'<a href="' + cal_actor + '/newreminder">➕ ' + \
|
||||||
translate['Add to the calendar'] + '</a>\n</p>\n</center>\n'
|
translate['Add to the calendar'] + '</a>\n</p>\n</center>\n'
|
||||||
|
|
||||||
|
calendar_icon_str = \
|
||||||
|
' <a href="' + path + '?ical=true" ' + \
|
||||||
|
'download="icalendar.ics">' + \
|
||||||
|
'<img class="ical" src="/icons/ical.png" ' + \
|
||||||
|
'title="iCalendar" alt="iCalendar" /></a>\n'
|
||||||
|
|
||||||
cal_str = \
|
cal_str = \
|
||||||
header_str + screen_reader_cal + calendar_str + \
|
header_str + screen_reader_cal + calendar_str + \
|
||||||
new_event_str + html_footer()
|
new_event_str + calendar_icon_str + html_footer()
|
||||||
|
|
||||||
return cal_str
|
return cal_str
|
||||||
|
|