calendar-social/calsocial/calendar_system/gregorian.py

220 lines
6.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Calendar.social
# Copyright (C) 2018 Gergely Polonkai
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Gregorian calendar system for Calendar.social
"""
from datetime import datetime, timedelta
from flask_babelex import lazy_gettext as _
from . import CalendarSystem
class GregorianCalendar(CalendarSystem):
"""Gregorian calendar system for Calendar.social
"""
__name__ = _('Gregorian')
__has_months__ = True
START_DAY = 0
END_DAY = 7
month_names = (
_('January'),
_('February'),
_('March'),
_('April'),
_('May'),
_('June'),
_('July'),
_('August'),
_('September'),
_('October'),
_('November'),
_('December'),
)
day_names = (
_('Monday'),
_('Tuesday'),
_('Wednesday'),
_('Thursday'),
_('Friday'),
_('Saturday'),
_('Sunday'),
)
def __init__(self, timestamp):
self.timestamp = datetime.utcfromtimestamp(timestamp)
@property
def month(self):
return self.timestamp.strftime("%B, %Y")
@property
def days(self):
day_list = []
month_first = self.timestamp.replace(day=1)
if self.timestamp.month == 12:
month_last = month_first.replace(day=31)
else:
month_last = month_first.replace(month=month_first.month + 1) - timedelta(days=1)
pad_before = (7 - self.START_DAY + month_first.weekday()) % 7
pad_after = (6 - month_last.weekday() + self.START_DAY) % 7
first_display = month_first - timedelta(days=pad_before)
last_display = month_last + timedelta(days=pad_after)
current = first_display
while current <= last_display:
day_list.append(current)
current += timedelta(days=1)
return day_list
@property
def prev_year(self):
"""Returns the timestamp of the same date in the previous year
"""
return self.timestamp.replace(year=self.timestamp.year - 1)
@property
def prev_year_year(self):
"""The number of the previous year
"""
return self.timestamp.replace(year=self.timestamp.year - 1).year
@property
def current_month_first(self):
"""Return the timestamp for the first day of the current month
"""
return self.timestamp.replace(day=1)
@property
def prev_month(self):
"""Returns the timestamp of the same day in the previous month
"""
if self.timestamp.month == 1:
return self.prev_year.replace(month=12)
return self.current_month_first - timedelta(days=1)
@property
def prev_month_name(self):
"""The name of the previous month
"""
return self.month_names[self.prev_month.month]
@property
def next_month(self):
"""Returns the timestamp of the same day in the next month
"""
if self.timestamp.month == 12:
return self.next_year.replace(month=1)
return self.timestamp.replace(month=self.timestamp.month + 1)
@property
def next_month_name(self):
"""The name of the next month
"""
if self.timestamp.month == 12:
timestamp = self.prev_year.replace(month=1)
else:
timestamp = self.timestamp.replace(month=self.timestamp.month + 1)
return self.month_names[timestamp.month - 1]
@property
def next_year(self):
"""Returns the timestamp of the same date in the next year
"""
return self.timestamp.replace(year=self.timestamp.year + 1)
@property
def next_year_year(self):
"""The number of the next year
"""
return self.timestamp.replace(year=self.timestamp.year + 1).year
@property
def has_today(self):
"""``True`` if the set month holds todays date
"""
now = datetime.utcnow()
month_start_timestamp = self.timestamp.replace(day=1,
hour=0,
minute=0,
second=0,
microsecond=0)
if self.timestamp.month == 12:
next_month = 1
else:
next_month = self.timestamp.month + 1
month_end_timestamp = month_start_timestamp.replace(month=next_month)
return month_start_timestamp <= now < month_end_timestamp
@staticmethod
def day_events(date, user=None):
"""Returns all events for a given day
"""
from ..models import Event, EventVisibility, Invitation, Profile, Response
events = Event.query
if user:
events = events.outerjoin(Invitation) \
.outerjoin(Response) \
.join(Profile, Event.profile) \
.filter(Profile.user == user)
start_timestamp = date.replace(hour=0, minute=0, second=0, microsecond=0)
end_timestamp = start_timestamp + timedelta(days=1)
events = events.filter((Event.start_time <= end_timestamp) &
(Event.end_time >= start_timestamp)) \
.order_by('start_time', 'end_time')
if user is None:
events = events.filter(Event.visibility == EventVisibility.public)
else:
events = events.filter((Event.visibility == EventVisibility.public) |
(Event.profile == user.profile) |
(Invitation.invitee == user.profile) |
(Response.profile == user.profile))
return events