__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 += ' \n' deletePostStr += ' \n' deletePostStr += \ ' \n' deletePostStr += \ ' \n' deletePostStr += \ ' \n' deletePostStr += \ ' \n' 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' 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' if eventTime and eventDescription and eventPlace: calendarStr += \ '' + deleteButtonStr + '\n' elif eventTime and eventDescription and not eventPlace: calendarStr += \ '' + deleteButtonStr + '\n' elif not eventTime and eventDescription and not eventPlace: calendarStr += \ '' + deleteButtonStr + '\n' elif not eventTime and eventDescription and eventPlace: calendarStr += \ '' + \ '' + deleteButtonStr + '\n' elif eventTime and not eventDescription and eventPlace: calendarStr += \ '' + \ deleteButtonStr + '\n' calendarStr += '\n' calendarStr += '
\n' calendarStr += \ ' \n' calendarStr += \ '

' + str(dayNumber) + ' ' + monthName + \ '


' + str(year) + '\n' calendarStr += '
\n' + \
                    translate['Delete this event'] + ' |
' + eventTime + \ '' + \ '' + \ eventPlace + '
' + eventDescription + \ '
' + eventTime + \ '' + \ eventDescription + '
' + \ '' + \ eventDescription + '
' + \ eventPlace + '
' + eventDescription + \ '
' + eventTime + \ '' + \ '' + \ eventPlace + '
\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 += '\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 += \ ' \n' else: calendarStr += \ ' \n' else: # No events today if not isToday: calendarStr += \ ' \n' else: calendarStr += \ ' \n' else: calendarStr += ' \n' calendarStr += ' \n' calendarStr += '\n' calendarStr += '
\n' calendarStr += \ ' ' calendarStr += \ ' ' + translate['Previous month'] + \
        '\n' calendarStr += ' ' calendarStr += '

' + monthName + '

\n' calendarStr += \ ' ' calendarStr += \ ' ' + translate['Next month'] + \
        '\n' calendarStr += '
' + \ translate['Sun'] + '' + \ translate['Mon'] + '' + \ translate['Tue'] + '' + \ translate['Wed'] + '' + \ translate['Thu'] + '' + \ translate['Fri'] + '' + \ translate['Sat'] + '
' + \ dayLink + '' + \ dayLink + '' + \ str(dayOfMonth) + '' + str(dayOfMonth) + '
\n' calendarStr += htmlFooter() return calendarStr