mirror of https://gitlab.com/bashrc2/epicyon
				
				
				
			Calendar module
							parent
							
								
									86b097f64d
								
							
						
					
					
						commit
						4a3a2c2319
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								utils.py
								
								
								
								
							
							
						
						
									
										2
									
								
								utils.py
								
								
								
								
							| 
						 | 
				
			
			@ -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
								
								
								
								
							
							
						
						
									
										378
									
								
								webapp.py
								
								
								
								
							| 
						 | 
				
			
			@ -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: {},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
		Loading…
	
		Reference in New Issue