Calendar module

main
Bob Mottram 2020-11-09 20:15:17 +00:00
parent 86b097f64d
commit 4a3a2c2319
4 changed files with 401 additions and 381 deletions

View File

@ -114,10 +114,11 @@ from blog import htmlBlogPage
from blog import htmlBlogPost
from blog import htmlEditBlog
from webapp_utils import setBlogAddress
from webapp_calendar import htmlCalendarDeleteConfirm
from webapp_calendar import htmlCalendar
from webapp import htmlCitations
from webapp import htmlFollowingList
from webapp import getBlogAddress
from webapp import htmlCalendarDeleteConfirm
from webapp import htmlDeletePost
from webapp import htmlAbout
from webapp import htmlRemoveSharedItem
@ -142,7 +143,6 @@ from webapp import htmlSuspended
from webapp import htmlGetLoginCredentials
from webapp import htmlNewPost
from webapp import htmlFollowConfirm
from webapp import htmlCalendar
from webapp import htmlNewswireMobile
from webapp import htmlLinksMobile
from webapp import htmlUnfollowConfirm

View File

@ -1500,5 +1500,5 @@ def weekDayOfMonthStart(monthNumber: int, year: int) -> int:
"""Gets the day number of the first day of the month
1=sun, 7=sat
"""
firstDayOfMonth = datetime(year, monthNumber, 1, 0, 0)
firstDayOfMonth = datetime.datetime(year, monthNumber, 1, 0, 0)
return int(firstDayOfMonth.strftime("%w")) + 1

378
webapp.py
View File

@ -9,7 +9,6 @@ __status__ = "Production"
import time
import os
from datetime import datetime
from datetime import date
from shutil import copyfile
from pprint import pprint
from person import personBoxJson
@ -22,7 +21,6 @@ from ssb import getSSBAddress
from tox import getToxAddress
from matrix import getMatrixAddress
from donate import getDonationUrl
from utils import weekDayOfMonthStart
from utils import getCSS
from utils import isSystemAccount
from utils import removeIdEnding
@ -51,8 +49,6 @@ from skills import getSkills
from shares import getValidSharedItemID
from happening import todaysEventsCheck
from happening import thisWeeksEventsCheck
from happening import getCalendarEvents
from happening import getTodaysEvents
from theme import getThemesList
from petnames import getPetName
from followingCalendar import receivingCalendarEvents
@ -5044,78 +5040,6 @@ def htmlDeletePost(cssCache: {},
return deletePostStr
def htmlCalendarDeleteConfirm(cssCache: {}, translate: {}, baseDir: str,
path: str, httpPrefix: str,
domainFull: str, postId: str, postTime: str,
year: int, monthNumber: int,
dayNumber: int, callingDomain: str) -> str:
"""Shows a screen asking to confirm the deletion of a calendar event
"""
nickname = getNicknameFromActor(path)
actor = httpPrefix + '://' + domainFull + '/users/' + nickname
domain, port = getDomainFromActor(actor)
messageId = actor + '/statuses/' + postId
postFilename = locatePost(baseDir, nickname, domain, messageId)
if not postFilename:
return None
postJsonObject = loadJson(postFilename)
if not postJsonObject:
return None
if os.path.isfile(baseDir + '/img/delete-background.png'):
if not os.path.isfile(baseDir + '/accounts/delete-background.png'):
copyfile(baseDir + '/img/delete-background.png',
baseDir + '/accounts/delete-background.png')
deletePostStr = None
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if profileStyle:
if httpPrefix != 'https':
profileStyle = profileStyle.replace('https://',
httpPrefix + '://')
deletePostStr = htmlHeader(cssFilename, profileStyle)
deletePostStr += \
'<center><h1>' + postTime + ' ' + str(year) + '/' + \
str(monthNumber) + \
'/' + str(dayNumber) + '</h1></center>'
deletePostStr += '<center>'
deletePostStr += ' <p class="followText">' + \
translate['Delete this event'] + '</p>'
postActor = getAltPath(actor, domainFull, callingDomain)
deletePostStr += \
' <form method="POST" action="' + postActor + '/rmpost">\n'
deletePostStr += ' <input type="hidden" name="year" value="' + \
str(year) + '">\n'
deletePostStr += ' <input type="hidden" name="month" value="' + \
str(monthNumber) + '">\n'
deletePostStr += ' <input type="hidden" name="day" value="' + \
str(dayNumber) + '">\n'
deletePostStr += \
' <input type="hidden" name="pageNumber" value="1">\n'
deletePostStr += \
' <input type="hidden" name="messageId" value="' + \
messageId + '">\n'
deletePostStr += \
' <button type="submit" class="button" name="submitYes">' + \
translate['Yes'] + '</button>\n'
deletePostStr += \
' <a href="' + actor + '/calendar?year=' + \
str(year) + '?month=' + \
str(monthNumber) + '"><button class="button">' + \
translate['No'] + '</button></a>\n'
deletePostStr += ' </form>\n'
deletePostStr += '</center>\n'
deletePostStr += htmlFooter()
return deletePostStr
def htmlFollowConfirm(cssCache: {}, translate: {}, baseDir: str,
originPathStr: str,
followActor: str,
@ -5484,308 +5408,6 @@ def htmlUnblockConfirm(cssCache: {}, translate: {}, baseDir: str,
return blockStr
def htmlCalendarDay(cssCache: {}, translate: {},
baseDir: str, path: str,
year: int, monthNumber: int, dayNumber: int,
nickname: str, domain: str, dayEvents: [],
monthName: str, actor: str) -> str:
"""Show a day within the calendar
"""
accountDir = baseDir + '/accounts/' + nickname + '@' + domain
calendarFile = accountDir + '/.newCalendar'
if os.path.isfile(calendarFile):
os.remove(calendarFile)
cssFilename = baseDir + '/epicyon-calendar.css'
if os.path.isfile(baseDir + '/calendar.css'):
cssFilename = baseDir + '/calendar.css'
calendarStyle = getCSS(baseDir, cssFilename, cssCache)
calActor = actor
if '/users/' in actor:
calActor = '/users/' + actor.split('/users/')[1]
calendarStr = htmlHeader(cssFilename, calendarStyle)
calendarStr += '<main><table class="calendar">\n'
calendarStr += '<caption class="calendar__banner--month">\n'
calendarStr += \
' <a href="' + calActor + '/calendar?year=' + str(year) + \
'?month=' + str(monthNumber) + '">\n'
calendarStr += \
' <h1>' + str(dayNumber) + ' ' + monthName + \
'</h1></a><br><span class="year">' + str(year) + '</span>\n'
calendarStr += '</caption>\n'
calendarStr += '<tbody>\n'
iconsDir = getIconsDir(baseDir)
if dayEvents:
for eventPost in dayEvents:
eventTime = None
eventDescription = None
eventPlace = None
postId = None
# get the time place and description
for ev in eventPost:
if ev['type'] == 'Event':
if ev.get('postId'):
postId = ev['postId']
if ev.get('startTime'):
eventDate = \
datetime.strptime(ev['startTime'],
"%Y-%m-%dT%H:%M:%S%z")
eventTime = eventDate.strftime("%H:%M").strip()
if ev.get('name'):
eventDescription = ev['name'].strip()
elif ev['type'] == 'Place':
if ev.get('name'):
eventPlace = ev['name']
deleteButtonStr = ''
if postId:
deleteButtonStr = \
'<td class="calendar__day__icons"><a href="' + calActor + \
'/eventdelete?id=' + postId + '?year=' + str(year) + \
'?month=' + str(monthNumber) + '?day=' + str(dayNumber) + \
'?time=' + eventTime + \
'">\n<img class="calendardayicon" loading="lazy" alt="' + \
translate['Delete this event'] + ' |" title="' + \
translate['Delete this event'] + '" src="/' + \
iconsDir + '/delete.png" /></a></td>\n'
if eventTime and eventDescription and eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time"><b>' + eventTime + \
'</b></td><td class="calendar__day__event">' + \
'<span class="place">' + \
eventPlace + '</span><br>' + eventDescription + \
'</td>' + deleteButtonStr + '</tr>\n'
elif eventTime and eventDescription and not eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time"><b>' + eventTime + \
'</b></td><td class="calendar__day__event">' + \
eventDescription + '</td>' + deleteButtonStr + '</tr>\n'
elif not eventTime and eventDescription and not eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time">' + \
'</td><td class="calendar__day__event">' + \
eventDescription + '</td>' + deleteButtonStr + '</tr>\n'
elif not eventTime and eventDescription and eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time"></td>' + \
'<td class="calendar__day__event"><span class="place">' + \
eventPlace + '</span><br>' + eventDescription + \
'</td>' + deleteButtonStr + '</tr>\n'
elif eventTime and not eventDescription and eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time"><b>' + eventTime + \
'</b></td><td class="calendar__day__event">' + \
'<span class="place">' + \
eventPlace + '</span></td>' + \
deleteButtonStr + '</tr>\n'
calendarStr += '</tbody>\n'
calendarStr += '</table></main>\n'
calendarStr += htmlFooter()
return calendarStr
def htmlCalendar(cssCache: {}, translate: {},
baseDir: str, path: str,
httpPrefix: str, domainFull: str) -> str:
"""Show the calendar for a person
"""
iconsDir = getIconsDir(baseDir)
domain = domainFull
if ':' in domainFull:
domain = domainFull.split(':')[0]
monthNumber = 0
dayNumber = None
year = 1970
actor = httpPrefix + '://' + domainFull + path.replace('/calendar', '')
if '?' in actor:
first = True
for p in actor.split('?'):
if not first:
if '=' in p:
if p.split('=')[0] == 'year':
numStr = p.split('=')[1]
if numStr.isdigit():
year = int(numStr)
elif p.split('=')[0] == 'month':
numStr = p.split('=')[1]
if numStr.isdigit():
monthNumber = int(numStr)
elif p.split('=')[0] == 'day':
numStr = p.split('=')[1]
if numStr.isdigit():
dayNumber = int(numStr)
first = False
actor = actor.split('?')[0]
currDate = datetime.now()
if year == 1970 and monthNumber == 0:
year = currDate.year
monthNumber = currDate.month
nickname = getNicknameFromActor(actor)
if os.path.isfile(baseDir + '/img/calendar-background.png'):
if not os.path.isfile(baseDir + '/accounts/calendar-background.png'):
copyfile(baseDir + '/img/calendar-background.png',
baseDir + '/accounts/calendar-background.png')
months = ('January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December')
monthName = translate[months[monthNumber - 1]]
if dayNumber:
dayEvents = None
events = \
getTodaysEvents(baseDir, nickname, domain,
year, monthNumber, dayNumber)
if events:
if events.get(str(dayNumber)):
dayEvents = events[str(dayNumber)]
return htmlCalendarDay(cssCache, translate, baseDir, path,
year, monthNumber, dayNumber,
nickname, domain, dayEvents,
monthName, actor)
events = \
getCalendarEvents(baseDir, nickname, domain, year, monthNumber)
prevYear = year
prevMonthNumber = monthNumber - 1
if prevMonthNumber < 1:
prevMonthNumber = 12
prevYear = year - 1
nextYear = year
nextMonthNumber = monthNumber + 1
if nextMonthNumber > 12:
nextMonthNumber = 1
nextYear = year + 1
print('Calendar year=' + str(year) + ' month=' + str(monthNumber) +
' ' + str(weekDayOfMonthStart(monthNumber, year)))
if monthNumber < 12:
daysInMonth = \
(date(year, monthNumber + 1, 1) - date(year, monthNumber, 1)).days
else:
daysInMonth = \
(date(year + 1, 1, 1) - date(year, monthNumber, 1)).days
# print('daysInMonth ' + str(monthNumber) + ': ' + str(daysInMonth))
cssFilename = baseDir + '/epicyon-calendar.css'
if os.path.isfile(baseDir + '/calendar.css'):
cssFilename = baseDir + '/calendar.css'
calendarStyle = getCSS(baseDir, cssFilename, cssCache)
calActor = actor
if '/users/' in actor:
calActor = '/users/' + actor.split('/users/')[1]
calendarStr = htmlHeader(cssFilename, calendarStyle)
calendarStr += '<main><table class="calendar">\n'
calendarStr += '<caption class="calendar__banner--month">\n'
calendarStr += \
' <a href="' + calActor + '/calendar?year=' + str(prevYear) + \
'?month=' + str(prevMonthNumber) + '">'
calendarStr += \
' <img loading="lazy" alt="' + translate['Previous month'] + \
'" title="' + translate['Previous month'] + '" src="/' + iconsDir + \
'/prev.png" class="buttonprev"/></a>\n'
calendarStr += ' <a href="' + calActor + '/inbox" title="'
calendarStr += translate['Switch to timeline view'] + '">'
calendarStr += ' <h1>' + monthName + '</h1></a>\n'
calendarStr += \
' <a href="' + calActor + '/calendar?year=' + str(nextYear) + \
'?month=' + str(nextMonthNumber) + '">'
calendarStr += \
' <img loading="lazy" alt="' + translate['Next month'] + \
'" title="' + translate['Next month'] + '" src="/' + iconsDir + \
'/prev.png" class="buttonnext"/></a>\n'
calendarStr += '</caption>\n'
calendarStr += '<thead>\n'
calendarStr += '<tr>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Sun'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Mon'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Tue'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Wed'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Thu'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Fri'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Sat'] + '</th>\n'
calendarStr += '</tr>\n'
calendarStr += '</thead>\n'
calendarStr += '<tbody>\n'
dayOfMonth = 0
dow = weekDayOfMonthStart(monthNumber, year)
for weekOfMonth in range(1, 7):
if dayOfMonth == daysInMonth:
continue
calendarStr += ' <tr>\n'
for dayNumber in range(1, 8):
if (weekOfMonth > 1 and dayOfMonth < daysInMonth) or \
(weekOfMonth == 1 and dayNumber >= dow):
dayOfMonth += 1
isToday = False
if year == currDate.year:
if currDate.month == monthNumber:
if dayOfMonth == currDate.day:
isToday = True
if events.get(str(dayOfMonth)):
url = calActor + '/calendar?year=' + \
str(year) + '?month=' + \
str(monthNumber) + '?day=' + str(dayOfMonth)
dayLink = '<a href="' + url + '">' + \
str(dayOfMonth) + '</a>'
# there are events for this day
if not isToday:
calendarStr += \
' <td class="calendar__day__cell" ' + \
'data-event="">' + \
dayLink + '</td>\n'
else:
calendarStr += \
' <td class="calendar__day__cell" ' + \
'data-today-event="">' + \
dayLink + '</td>\n'
else:
# No events today
if not isToday:
calendarStr += \
' <td class="calendar__day__cell">' + \
str(dayOfMonth) + '</td>\n'
else:
calendarStr += \
' <td class="calendar__day__cell" ' + \
'data-today="">' + str(dayOfMonth) + '</td>\n'
else:
calendarStr += ' <td class="calendar__day__cell"></td>\n'
calendarStr += ' </tr>\n'
calendarStr += '</tbody>\n'
calendarStr += '</table></main>\n'
calendarStr += htmlFooter()
return calendarStr
def htmlProfileAfterSearch(cssCache: {},
recentPostsCache: {}, maxRecentPosts: int,
translate: {},

398
webapp_calendar.py 100644
View File

@ -0,0 +1,398 @@
__filename__ = "webapp_calendar.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.1.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"
import os
from datetime import datetime
from datetime import date
from shutil import copyfile
from utils import getNicknameFromActor
from utils import getDomainFromActor
from utils import locatePost
from utils import loadJson
from utils import getCSS
from utils import weekDayOfMonthStart
from happening import getTodaysEvents
from happening import getCalendarEvents
from webapp_utils import htmlHeader
from webapp_utils import htmlFooter
from webapp_utils import getAltPath
from webapp_utils import getIconsDir
def htmlCalendarDeleteConfirm(cssCache: {}, translate: {}, baseDir: str,
path: str, httpPrefix: str,
domainFull: str, postId: str, postTime: str,
year: int, monthNumber: int,
dayNumber: int, callingDomain: str) -> str:
"""Shows a screen asking to confirm the deletion of a calendar event
"""
nickname = getNicknameFromActor(path)
actor = httpPrefix + '://' + domainFull + '/users/' + nickname
domain, port = getDomainFromActor(actor)
messageId = actor + '/statuses/' + postId
postFilename = locatePost(baseDir, nickname, domain, messageId)
if not postFilename:
return None
postJsonObject = loadJson(postFilename)
if not postJsonObject:
return None
if os.path.isfile(baseDir + '/img/delete-background.png'):
if not os.path.isfile(baseDir + '/accounts/delete-background.png'):
copyfile(baseDir + '/img/delete-background.png',
baseDir + '/accounts/delete-background.png')
deletePostStr = None
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if profileStyle:
if httpPrefix != 'https':
profileStyle = profileStyle.replace('https://',
httpPrefix + '://')
deletePostStr = htmlHeader(cssFilename, profileStyle)
deletePostStr += \
'<center><h1>' + postTime + ' ' + str(year) + '/' + \
str(monthNumber) + \
'/' + str(dayNumber) + '</h1></center>'
deletePostStr += '<center>'
deletePostStr += ' <p class="followText">' + \
translate['Delete this event'] + '</p>'
postActor = getAltPath(actor, domainFull, callingDomain)
deletePostStr += \
' <form method="POST" action="' + postActor + '/rmpost">\n'
deletePostStr += ' <input type="hidden" name="year" value="' + \
str(year) + '">\n'
deletePostStr += ' <input type="hidden" name="month" value="' + \
str(monthNumber) + '">\n'
deletePostStr += ' <input type="hidden" name="day" value="' + \
str(dayNumber) + '">\n'
deletePostStr += \
' <input type="hidden" name="pageNumber" value="1">\n'
deletePostStr += \
' <input type="hidden" name="messageId" value="' + \
messageId + '">\n'
deletePostStr += \
' <button type="submit" class="button" name="submitYes">' + \
translate['Yes'] + '</button>\n'
deletePostStr += \
' <a href="' + actor + '/calendar?year=' + \
str(year) + '?month=' + \
str(monthNumber) + '"><button class="button">' + \
translate['No'] + '</button></a>\n'
deletePostStr += ' </form>\n'
deletePostStr += '</center>\n'
deletePostStr += htmlFooter()
return deletePostStr
def htmlCalendarDay(cssCache: {}, translate: {},
baseDir: str, path: str,
year: int, monthNumber: int, dayNumber: int,
nickname: str, domain: str, dayEvents: [],
monthName: str, actor: str) -> str:
"""Show a day within the calendar
"""
accountDir = baseDir + '/accounts/' + nickname + '@' + domain
calendarFile = accountDir + '/.newCalendar'
if os.path.isfile(calendarFile):
os.remove(calendarFile)
cssFilename = baseDir + '/epicyon-calendar.css'
if os.path.isfile(baseDir + '/calendar.css'):
cssFilename = baseDir + '/calendar.css'
calendarStyle = getCSS(baseDir, cssFilename, cssCache)
calActor = actor
if '/users/' in actor:
calActor = '/users/' + actor.split('/users/')[1]
calendarStr = htmlHeader(cssFilename, calendarStyle)
calendarStr += '<main><table class="calendar">\n'
calendarStr += '<caption class="calendar__banner--month">\n'
calendarStr += \
' <a href="' + calActor + '/calendar?year=' + str(year) + \
'?month=' + str(monthNumber) + '">\n'
calendarStr += \
' <h1>' + str(dayNumber) + ' ' + monthName + \
'</h1></a><br><span class="year">' + str(year) + '</span>\n'
calendarStr += '</caption>\n'
calendarStr += '<tbody>\n'
iconsDir = getIconsDir(baseDir)
if dayEvents:
for eventPost in dayEvents:
eventTime = None
eventDescription = None
eventPlace = None
postId = None
# get the time place and description
for ev in eventPost:
if ev['type'] == 'Event':
if ev.get('postId'):
postId = ev['postId']
if ev.get('startTime'):
eventDate = \
datetime.strptime(ev['startTime'],
"%Y-%m-%dT%H:%M:%S%z")
eventTime = eventDate.strftime("%H:%M").strip()
if ev.get('name'):
eventDescription = ev['name'].strip()
elif ev['type'] == 'Place':
if ev.get('name'):
eventPlace = ev['name']
deleteButtonStr = ''
if postId:
deleteButtonStr = \
'<td class="calendar__day__icons"><a href="' + calActor + \
'/eventdelete?id=' + postId + '?year=' + str(year) + \
'?month=' + str(monthNumber) + '?day=' + str(dayNumber) + \
'?time=' + eventTime + \
'">\n<img class="calendardayicon" loading="lazy" alt="' + \
translate['Delete this event'] + ' |" title="' + \
translate['Delete this event'] + '" src="/' + \
iconsDir + '/delete.png" /></a></td>\n'
if eventTime and eventDescription and eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time"><b>' + eventTime + \
'</b></td><td class="calendar__day__event">' + \
'<span class="place">' + \
eventPlace + '</span><br>' + eventDescription + \
'</td>' + deleteButtonStr + '</tr>\n'
elif eventTime and eventDescription and not eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time"><b>' + eventTime + \
'</b></td><td class="calendar__day__event">' + \
eventDescription + '</td>' + deleteButtonStr + '</tr>\n'
elif not eventTime and eventDescription and not eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time">' + \
'</td><td class="calendar__day__event">' + \
eventDescription + '</td>' + deleteButtonStr + '</tr>\n'
elif not eventTime and eventDescription and eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time"></td>' + \
'<td class="calendar__day__event"><span class="place">' + \
eventPlace + '</span><br>' + eventDescription + \
'</td>' + deleteButtonStr + '</tr>\n'
elif eventTime and not eventDescription and eventPlace:
calendarStr += \
'<tr><td class="calendar__day__time"><b>' + eventTime + \
'</b></td><td class="calendar__day__event">' + \
'<span class="place">' + \
eventPlace + '</span></td>' + \
deleteButtonStr + '</tr>\n'
calendarStr += '</tbody>\n'
calendarStr += '</table></main>\n'
calendarStr += htmlFooter()
return calendarStr
def htmlCalendar(cssCache: {}, translate: {},
baseDir: str, path: str,
httpPrefix: str, domainFull: str) -> str:
"""Show the calendar for a person
"""
iconsDir = getIconsDir(baseDir)
domain = domainFull
if ':' in domainFull:
domain = domainFull.split(':')[0]
monthNumber = 0
dayNumber = None
year = 1970
actor = httpPrefix + '://' + domainFull + path.replace('/calendar', '')
if '?' in actor:
first = True
for p in actor.split('?'):
if not first:
if '=' in p:
if p.split('=')[0] == 'year':
numStr = p.split('=')[1]
if numStr.isdigit():
year = int(numStr)
elif p.split('=')[0] == 'month':
numStr = p.split('=')[1]
if numStr.isdigit():
monthNumber = int(numStr)
elif p.split('=')[0] == 'day':
numStr = p.split('=')[1]
if numStr.isdigit():
dayNumber = int(numStr)
first = False
actor = actor.split('?')[0]
currDate = datetime.now()
if year == 1970 and monthNumber == 0:
year = currDate.year
monthNumber = currDate.month
nickname = getNicknameFromActor(actor)
if os.path.isfile(baseDir + '/img/calendar-background.png'):
if not os.path.isfile(baseDir + '/accounts/calendar-background.png'):
copyfile(baseDir + '/img/calendar-background.png',
baseDir + '/accounts/calendar-background.png')
months = ('January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December')
monthName = translate[months[monthNumber - 1]]
if dayNumber:
dayEvents = None
events = \
getTodaysEvents(baseDir, nickname, domain,
year, monthNumber, dayNumber)
if events:
if events.get(str(dayNumber)):
dayEvents = events[str(dayNumber)]
return htmlCalendarDay(cssCache, translate, baseDir, path,
year, monthNumber, dayNumber,
nickname, domain, dayEvents,
monthName, actor)
events = \
getCalendarEvents(baseDir, nickname, domain, year, monthNumber)
prevYear = year
prevMonthNumber = monthNumber - 1
if prevMonthNumber < 1:
prevMonthNumber = 12
prevYear = year - 1
nextYear = year
nextMonthNumber = monthNumber + 1
if nextMonthNumber > 12:
nextMonthNumber = 1
nextYear = year + 1
print('Calendar year=' + str(year) + ' month=' + str(monthNumber) +
' ' + str(weekDayOfMonthStart(monthNumber, year)))
if monthNumber < 12:
daysInMonth = \
(date(year, monthNumber + 1, 1) - date(year, monthNumber, 1)).days
else:
daysInMonth = \
(date(year + 1, 1, 1) - date(year, monthNumber, 1)).days
# print('daysInMonth ' + str(monthNumber) + ': ' + str(daysInMonth))
cssFilename = baseDir + '/epicyon-calendar.css'
if os.path.isfile(baseDir + '/calendar.css'):
cssFilename = baseDir + '/calendar.css'
calendarStyle = getCSS(baseDir, cssFilename, cssCache)
calActor = actor
if '/users/' in actor:
calActor = '/users/' + actor.split('/users/')[1]
calendarStr = htmlHeader(cssFilename, calendarStyle)
calendarStr += '<main><table class="calendar">\n'
calendarStr += '<caption class="calendar__banner--month">\n'
calendarStr += \
' <a href="' + calActor + '/calendar?year=' + str(prevYear) + \
'?month=' + str(prevMonthNumber) + '">'
calendarStr += \
' <img loading="lazy" alt="' + translate['Previous month'] + \
'" title="' + translate['Previous month'] + '" src="/' + iconsDir + \
'/prev.png" class="buttonprev"/></a>\n'
calendarStr += ' <a href="' + calActor + '/inbox" title="'
calendarStr += translate['Switch to timeline view'] + '">'
calendarStr += ' <h1>' + monthName + '</h1></a>\n'
calendarStr += \
' <a href="' + calActor + '/calendar?year=' + str(nextYear) + \
'?month=' + str(nextMonthNumber) + '">'
calendarStr += \
' <img loading="lazy" alt="' + translate['Next month'] + \
'" title="' + translate['Next month'] + '" src="/' + iconsDir + \
'/prev.png" class="buttonnext"/></a>\n'
calendarStr += '</caption>\n'
calendarStr += '<thead>\n'
calendarStr += '<tr>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Sun'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Mon'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Tue'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Wed'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Thu'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Fri'] + '</th>\n'
calendarStr += ' <th class="calendar__day__header">' + \
translate['Sat'] + '</th>\n'
calendarStr += '</tr>\n'
calendarStr += '</thead>\n'
calendarStr += '<tbody>\n'
dayOfMonth = 0
dow = weekDayOfMonthStart(monthNumber, year)
for weekOfMonth in range(1, 7):
if dayOfMonth == daysInMonth:
continue
calendarStr += ' <tr>\n'
for dayNumber in range(1, 8):
if (weekOfMonth > 1 and dayOfMonth < daysInMonth) or \
(weekOfMonth == 1 and dayNumber >= dow):
dayOfMonth += 1
isToday = False
if year == currDate.year:
if currDate.month == monthNumber:
if dayOfMonth == currDate.day:
isToday = True
if events.get(str(dayOfMonth)):
url = calActor + '/calendar?year=' + \
str(year) + '?month=' + \
str(monthNumber) + '?day=' + str(dayOfMonth)
dayLink = '<a href="' + url + '">' + \
str(dayOfMonth) + '</a>'
# there are events for this day
if not isToday:
calendarStr += \
' <td class="calendar__day__cell" ' + \
'data-event="">' + \
dayLink + '</td>\n'
else:
calendarStr += \
' <td class="calendar__day__cell" ' + \
'data-today-event="">' + \
dayLink + '</td>\n'
else:
# No events today
if not isToday:
calendarStr += \
' <td class="calendar__day__cell">' + \
str(dayOfMonth) + '</td>\n'
else:
calendarStr += \
' <td class="calendar__day__cell" ' + \
'data-today="">' + str(dayOfMonth) + '</td>\n'
else:
calendarStr += ' <td class="calendar__day__cell"></td>\n'
calendarStr += ' </tr>\n'
calendarStr += '</tbody>\n'
calendarStr += '</table></main>\n'
calendarStr += htmlFooter()
return calendarStr