__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 weekDayOfMonthStart
from happening import getTodaysEvents
from happening import getCalendarEvents
from webapp_utils import htmlHeaderWithExternalStyle
from webapp_utils import htmlFooter
from webapp_utils import getAltPath
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'
deletePostStr = htmlHeaderWithExternalStyle(cssFilename)
deletePostStr += \
'
' + postTime + ' ' + str(year) + '/' + \
str(monthNumber) + \
'/' + str(dayNumber) + '
'
deletePostStr += ''
deletePostStr += ' ' + \
translate['Delete this event'] + '
'
postActor = getAltPath(actor, domainFull, callingDomain)
deletePostStr += \
' \n'
deletePostStr += '\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'
calActor = actor
if '/users/' in actor:
calActor = '/users/' + actor.split('/users/')[1]
calendarStr = htmlHeaderWithExternalStyle(cssFilename)
calendarStr += '\n'
calendarStr += '\n'
calendarStr += \
' \n'
calendarStr += \
' ' + str(dayNumber) + ' ' + monthName + \
'
' + str(year) + '\n'
calendarStr += '\n'
calendarStr += '\n'
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 = \
'\n | \n'
if eventTime and eventDescription and eventPlace:
calendarStr += \
'' + eventTime + \
' | ' + \
'' + \
eventPlace + ' ' + eventDescription + \
' | ' + deleteButtonStr + '
\n'
elif eventTime and eventDescription and not eventPlace:
calendarStr += \
'' + eventTime + \
' | ' + \
eventDescription + ' | ' + deleteButtonStr + '
\n'
elif not eventTime and eventDescription and not eventPlace:
calendarStr += \
'' + \
' | ' + \
eventDescription + ' | ' + deleteButtonStr + '
\n'
elif not eventTime and eventDescription and eventPlace:
calendarStr += \
' | ' + \
'' + \
eventPlace + ' ' + eventDescription + \
' | ' + deleteButtonStr + '
\n'
elif eventTime and not eventDescription and eventPlace:
calendarStr += \
'' + eventTime + \
' | ' + \
'' + \
eventPlace + ' | ' + \
deleteButtonStr + '
\n'
calendarStr += '\n'
calendarStr += '
\n'
calendarStr += htmlFooter()
return calendarStr
def htmlCalendar(cssCache: {}, translate: {},
baseDir: str, path: str,
httpPrefix: str, domainFull: str) -> str:
"""Show the calendar for a person
"""
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'
calActor = actor
if '/users/' in actor:
calActor = '/users/' + actor.split('/users/')[1]
calendarStr = htmlHeaderWithExternalStyle(cssFilename)
calendarStr += '\n'
calendarStr += '\n'
calendarStr += \
' '
calendarStr += \
' \n'
calendarStr += ' '
calendarStr += ' ' + monthName + '
\n'
calendarStr += \
' '
calendarStr += \
' \n'
calendarStr += '\n'
calendarStr += '\n'
calendarStr += '\n'
calendarStr += ' \n'
calendarStr += ' \n'
calendarStr += ' \n'
calendarStr += ' \n'
calendarStr += ' \n'
calendarStr += ' \n'
calendarStr += ' \n'
calendarStr += '
\n'
calendarStr += '\n'
calendarStr += '\n'
dayOfMonth = 0
dow = weekDayOfMonthStart(monthNumber, year)
for weekOfMonth in range(1, 7):
if dayOfMonth == daysInMonth:
continue
calendarStr += ' \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 = '' + \
str(dayOfMonth) + ''
# there are events for this day
if not isToday:
calendarStr += \
' ' + \
dayLink + ' | \n'
else:
calendarStr += \
' ' + \
dayLink + ' | \n'
else:
# No events today
if not isToday:
calendarStr += \
' ' + \
str(dayOfMonth) + ' | \n'
else:
calendarStr += \
' ' + str(dayOfMonth) + ' | \n'
else:
calendarStr += ' | \n'
calendarStr += '
\n'
calendarStr += '\n'
calendarStr += '
\n'
calendarStr += htmlFooter()
return calendarStr