calendar-social/calsocial/calendar_system/gregorian.py

218 lines
6.3 KiB
Python
Raw Normal View History

# 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
"""
2018-06-25 07:01:13 +00:00
from datetime import datetime, timedelta
from flask_babelex import lazy_gettext as _
2018-06-25 07:01:13 +00:00
from . import CalendarSystem
class GregorianCalendar(CalendarSystem):
"""Gregorian calendar system for Calendar.social
"""
2018-06-25 07:01:13 +00:00
__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'),
)
2018-06-25 07:01:13 +00:00
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)
2018-06-25 07:01:13 +00:00
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
2018-06-25 07:01:13 +00:00
first_display = month_first - timedelta(days=pad_before)
last_display = month_last + timedelta(days=pad_after)
current = first_display
2018-06-25 07:01:13 +00:00
while current <= last_display:
day_list.append(current)
current += timedelta(days=1)
2018-06-25 07:01:13 +00:00
return day_list
2018-06-29 14:14:35 +00:00
@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 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.timestamp.replace(month=self.timestamp.month - 1)
@property
def prev_month_name(self):
"""The name of the previous month
"""
if self.timestamp.month == 1:
timestamp = self.prev_year.replace(month=12)
else:
timestamp = self.timestamp.replace(month=self.timestamp.month - 1)
return self.month_names[timestamp.month - 1]
@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
2018-06-29 14:14:35 +00:00
events = Event.query
if user:
events = events.outerjoin(Invitation) \
.outerjoin(Response) \
.join(Profile, Event.profile) \
.filter(Profile.user == user)
2018-06-29 14:14:35 +00:00
start_timestamp = date.replace(hour=0, minute=0, second=0, microsecond=0)
2018-06-29 14:14:35 +00:00
end_timestamp = start_timestamp + timedelta(days=1)
events = events.filter((Event.start_time <= end_timestamp) &
2018-07-23 10:20:12 +00:00
(Event.end_time >= start_timestamp)) \
.order_by('start_time', 'end_time')
2018-06-29 14:14:35 +00:00
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))
2018-06-29 14:14:35 +00:00
return events