[fedocal] master: Back-end work (ae518fd)
by Pierre-YvesChibon
Repository : http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
>---------------------------------------------------------------
commit ae518fdb4e9d2f3415498c26aaad9f48e93944e7
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Thu Dec 13 11:53:04 2012 +0100
Back-end work
Rework the get_by_date function. It can be used in more places
giving simpler and more robust code.
Add function to expand recursive meetings, we need this at several
places so we need one central place to reuse it.
Adjust the unit-test for these changes, since we expand the recursive
meeting that does return more results in a number of places.
>---------------------------------------------------------------
fedocal/fedocallib/__init__.py | 96 ++++++++-----------------
fedocal/fedocallib/model.py | 151 +++++++++++++++++++++++++++++--------
fedocal/tests/test_fedocallib.py | 5 +-
fedocal/tests/test_flask.py | 4 +-
fedocal/tests/test_flask_api.py | 4 +-
fedocal/tests/test_meeting.py | 12 +++
6 files changed, 167 insertions(+), 105 deletions(-)
diff --git a/fedocal/fedocallib/__init__.py b/fedocal/fedocallib/__init__.py
index ceedcfb..0c31269 100644
--- a/fedocal/fedocallib/__init__.py
+++ b/fedocal/fedocallib/__init__.py
@@ -20,7 +20,6 @@ import operator
from datetime import datetime
from datetime import date
-from datetime import time
from datetime import timedelta
from sqlalchemy import create_engine
@@ -325,8 +324,7 @@ def get_meetings_by_date(session, calendar_name, start_date, end_date):
meetings (this day is excluded from the selection).
"""
calendar = Calendar.by_id(session, calendar_name)
- return Meeting.get_by_date(session, calendar, start_date,
- end_date)
+ return get_by_date(session, calendar, start_date, end_date)
def get_meetings_by_date_and_region(session, calendar, start_date,
@@ -376,26 +374,14 @@ def get_past_meeting_of_user(session, username, tzone='UTC',
:kwarg from_date: the date from which the futur meetings should be
retrieved. Defaults to today
"""
- meetings_tmp = Meeting.get_past_meeting_of_user(session, username,
- from_date)
+ meetings_tmp = Meeting.expand_regular_meetings(
+ Meeting.get_past_meeting_of_user(session, username,
+ from_date),
+ end_date=from_date)
meetings = []
for meeting in meetings_tmp:
- if meeting.recursion_frequency and meeting.recursion_ends:
- rec_meetings = []
- cnt = 0
- meetingobj = Meeting.copy(meeting)
- while meetingobj.meeting_date < from_date:
- meetingobj = Meeting.copy(meeting)
- meetingobj.meeting_date = meetingobj.meeting_date + \
- timedelta(days=meeting.recursion_frequency * cnt)
- cnt = cnt + 1
- if meetingobj.meeting_date < from_date:
- rec_meetings.append(convert_meeting_timezone(
- meetingobj, 'UTC', tzone))
- rec_meetings.reverse()
- meetings.extend(rec_meetings)
- else:
- meetings.append(convert_meeting_timezone(meeting, 'UTC', tzone))
+ meetings.append(convert_meeting_timezone(meeting, 'UTC', tzone))
+ meetings.sort(key=operator.attrgetter('meeting_date'))
return meetings
@@ -443,10 +429,10 @@ def get_future_regular_meeting_of_user(session, username, tzone='UTC',
return meetings
-def agenda_is_free(session, calendar, meeting_date,
+def agenda_is_free(session, calendarobj, meeting_date,
time_start, time_stop):
"""Check if there is already someting planned in this agenda at that
- time.
+ time on that day.
:arg session: the database session to use
:arg calendar: the name of the calendar of interest.
@@ -454,14 +440,12 @@ def agenda_is_free(session, calendar, meeting_date,
:arg time_start: the time at which the meeting starts (as int)
:arg time_stop: the time at which the meeting stops (as int)
"""
- meetings = Meeting.at_time(session, calendar, meeting_date,
- time_start)
- meetings.extend(Meeting.at_time(session, calendar, meeting_date,
- time_stop))
- meetings.extend(Meeting.get_by_time(session, calendar, meeting_date,
- time_start, time_stop))
+ meetings = get_by_date(session, calendarobj, meeting_date,
+ meeting_date + timedelta(days=1))
agenda_free = True
for meeting in set(meetings):
+ if meeting.meeting_date != meeting_date:
+ continue
if time_start <= meeting.meeting_time_start \
and meeting.meeting_time_start < time_stop:
agenda_free = False
@@ -477,27 +461,25 @@ def agenda_is_free(session, calendar, meeting_date,
return agenda_free
-def agenda_is_free_in_future(session, calendar, meeting_date,
- recursion_ends, time_start, time_stop):
+def agenda_is_free_in_future(session, calendarobj, meeting_date,
+ time_start, time_stop):
"""For recursive meeting, check for meetings happening at the
- specified time between the specified date and the end of the
+ specified time between the specified date and to the end of the
recursion.
:arg session: the database session to use
- :arg calendar: the name of the calendar of interest.
+ :arg calendarobj: the calendar of interest.
:arg meeting_date: the date of the meeting (as Datetime object)
:arg recursion_ends: the end date of the recursion
:arg time_start: the time at which the meeting starts (as int)
:arg time_stop: the time at which the meeting stops (as int)
"""
- meetings = Meeting.in_future_at_time(session, calendar, meeting_date,
- recursion_ends, time_start)
- meetings.extend(Meeting.in_future_at_time(session, calendar,
- meeting_date, recursion_ends, time_stop))
- meetings.extend(Meeting.get_in_future_by_time(session, calendar,
- meeting_date, recursion_ends, time_start, time_stop))
+ meetings = get_by_date(session, calendarobj, meeting_date,
+ meeting_date + timedelta(days=1))
agenda_free = True
for meeting in set(meetings):
+ if meeting.meeting_date != meeting_date:
+ continue
if time_start <= meeting.meeting_time_start \
and meeting.meeting_time_start < time_stop:
agenda_free = False
@@ -674,31 +656,13 @@ def get_by_date(session, calendarobj, start_date, end_date, tzone='UTC'):
defaults to UTC.
"""
meetings_utc = Meeting.get_by_date(session, calendarobj, start_date,
- end_date)
- meetings_utc.extend(Meeting.get_active_regular_meeting(session,
- calendarobj, start_date))
+ end_date, no_recursive=True)
+ meetings_utc.extend(Meeting.get_regular_meeting_by_date(session,
+ calendarobj, start_date, end_date))
meetings = []
for meeting in list(set(meetings_utc)):
- if meeting.recursion_frequency and meeting.recursion_ends:
- meeting_date = meeting.meeting_date
- cnt = 0
- while meeting_date < end_date and \
- meeting_date <= meeting.recursion_ends:
- recmeeting = meeting.copy()
- if meeting_date >= start_date:
- recmeeting.meeting_id = meeting.meeting_id
- recmeeting.meeting_date = meeting.meeting_date + timedelta(
- days=meeting.recursion_frequency * cnt)
- recmeeting.meeting_date_end = meeting.meeting_date_end \
- + timedelta(days=meeting.recursion_frequency * cnt)
- meetings.append(convert_meeting_timezone(recmeeting,
- 'UTC', tzone))
- cnt = cnt + 1
- meeting_date = meeting.meeting_date + timedelta(
- days=meeting.recursion_frequency * cnt)
- else:
- meetings.append(convert_meeting_timezone(meeting, 'UTC',
- tzone))
+ meetings.append(convert_meeting_timezone(meeting, 'UTC',
+ tzone))
meetings.sort(key=operator.attrgetter('meeting_date'))
return meetings
@@ -750,8 +714,8 @@ def add_meeting(session, calendarobj, fas_user,
if frequency and end_repeats:
futur_meeting_at_time = agenda_is_free_in_future(session, calendarobj,
- meeting_date, end_repeats,
- meeting_time_start.time(), meeting_time_stop.time())
+ meeting_date, meeting_time_start.time(),
+ meeting_time_stop.time())
if not bool(calendarobj.calendar_multiple_meetings) and \
not(futur_meeting_at_time):
@@ -840,8 +804,8 @@ def edit_meeting(session, meeting, calendarobj, fas_user,
if recursion_frequency and recursion_ends:
futur_meeting_at_time = agenda_is_free_in_future(session,
- calendarobj, meeting_date, recursion_ends,
- meeting_time_start.time(), meeting_time_stop.time())
+ calendarobj, meeting_date, meeting_time_start.time(),
+ meeting_time_stop.time())
if not bool(calendarobj.calendar_multiple_meetings) and \
not(futur_meeting_at_time):
diff --git a/fedocal/fedocallib/model.py b/fedocal/fedocallib/model.py
index 9c0bfd5..645138f 100644
--- a/fedocal/fedocallib/model.py
+++ b/fedocal/fedocallib/model.py
@@ -16,6 +16,7 @@ license.
"""
__requires__ = ['SQLAlchemy >= 0.7']
import pkg_resources
+import operator
from datetime import datetime
from datetime import date
@@ -232,6 +233,7 @@ class Meeting(BASE):
meeting.meeting_time_start = self.meeting_time_start
meeting.meeting_time_stop = self.meeting_time_stop
meeting.calendar_name = self.calendar_name
+ meeting.calendar = self.calendar
meeting.reminder_id = self.reminder_id
meeting.meeting_region = self.meeting_region
meeting.recursion_frequency = self.recursion_frequency
@@ -272,23 +274,43 @@ class Meeting(BASE):
@classmethod
def get_by_date(cls, session, calendar, start_date, stop_date,
- full_day=False):
+ full_day=False, no_recursive=False):
""" Retrieve the list of meetings between two date.
We include the start date and exclude the stop date.
"""
+ if no_recursive:
+ return session.query(cls).filter(and_
+ (Meeting.calendar == calendar),
+ (Meeting.meeting_date >= start_date),
+ (Meeting.meeting_date < stop_date),
+ (Meeting.recursion_frequency == None),
+ (Meeting.full_day == full_day)
+ ).order_by(Meeting.meeting_date).all()
+ else:
+ return session.query(cls).filter(and_
+ (Meeting.calendar == calendar),
+ (Meeting.meeting_date >= start_date),
+ (Meeting.meeting_date < stop_date),
+ (Meeting.full_day == full_day)
+ ).order_by(Meeting.meeting_date).all()
+
+ @classmethod
+ def get_at_date(cls, session, calendar, meeting_date, full_day=False):
+ """ Retrieve the list of meetings happening at a given date.
+ The full_day boolean allows to specify if you want full day
+ meetings or not (defaults to False).
+ """
return session.query(cls).filter(and_
(Meeting.calendar == calendar),
- (Meeting.meeting_date >= start_date),
- (Meeting.meeting_date < stop_date),
+ (Meeting.meeting_date == meeting_date),
(Meeting.full_day == full_day)
).order_by(Meeting.meeting_date).all()
@classmethod
def get_active_regular_meeting(cls, session, calendar, end_date,
full_day=False):
- """ Retrieve the list of meetings with a recursion which
- end_date is not past the provided end_date and starting before
- the end of the time considered.
+ """ Retrieve the list of recursive meetings occuring before the
+ end_date in the specified calendar.
"""
meetings = session.query(cls).filter(and_
(Meeting.meeting_date <= end_date),
@@ -299,6 +321,45 @@ class Meeting(BASE):
).order_by(Meeting.meeting_date).all()
return meetings
+ @classmethod
+ def get_regular_meeting_at_date(cls, session, calendar, end_date,
+ full_day=False):
+ """ Retrieve the list of recursive meetings happening at the
+ specified end_date.
+ """
+ meetings = cls.expand_regular_meetings(
+ cls.get_active_regular_meeting(session, calendar,
+ end_date, full_day),
+ end_date)
+ return meetings
+
+ @classmethod
+ def get_active_regular_meeting_by_date(cls, session, calendar,
+ start_date, end_date, full_day=False):
+ """ Retrieve the list of recursive meetings occuring after the
+ start_date in the specified calendar.
+ """
+ meetings = session.query(cls).filter(and_
+ (Meeting.recursion_ends >= start_date),
+ (Meeting.calendar == calendar),
+ (Meeting.recursion_frequency != None),
+ (Meeting.full_day == full_day)
+ ).order_by(Meeting.meeting_date).all()
+ return meetings
+
+
+ @classmethod
+ def get_regular_meeting_by_date(cls, session, calendar, start_date,
+ end_date, full_day=False):
+ """ Retrieve the list of recursive meetings happening in between
+ the two specified dates.
+ """
+ meetings = cls.expand_regular_meetings(
+ cls.get_active_regular_meeting_by_date(session, calendar,
+ start_date, full_day),
+ end_date=end_date, start_date=start_date)
+ return meetings
+
# pylint: disable=R0913
@classmethod
def get_by_date_and_region(cls, session, calendar, start_date,
@@ -325,20 +386,7 @@ class Meeting(BASE):
(Meeting.meeting_time_stop < stop_time)).all()
@classmethod
- def get_in_future_by_time(cls, session, calendar, meetingdate,
- recursion_ends, start_time, stop_time):
- """ Retrieve the list of meetings for a given date and between
- two times for a specific calendar.
- """
- return session.query(cls).filter(and_
- (Meeting.calendar == calendar),
- (Meeting.meeting_date >= meetingdate),
- (Meeting.meeting_date <= recursion_ends),
- (Meeting.meeting_time_start >= start_time),
- (Meeting.meeting_time_stop < stop_time)).all()
-
- @classmethod
- def at_time(cls, session, calendar, meetingdate, t_time):
+ def get_at_time(cls, session, calendar, meetingdate, t_time):
""" Returns the meeting occuring at this specifict time point.
"""
return session.query(cls).filter(and_
@@ -348,19 +396,6 @@ class Meeting(BASE):
(Meeting.meeting_time_stop > t_time)).all()
@classmethod
- def get_in_future_at_time(cls, session, calendar, meetingdate,
- recursion_ends, t_time):
- """ Returns the meeting occuring at this specifict time point
- at any time in the future.
- """
- return session.query(cls).filter(and_
- (Meeting.calendar == calendar),
- (Meeting.meeting_date >= meetingdate),
- (Meeting.meeting_date <= recursion_ends),
- (Meeting.meeting_time_start <= t_time),
- (Meeting.meeting_time_stop > t_time)).all()
-
- @classmethod
def get_past_meeting_of_user(cls, session, username, start_date):
""" Retrieve the list of meetings which specified username
is among the managers and which date is older than the specified
@@ -433,6 +468,56 @@ class Meeting(BASE):
return meetings
+ @classmethod
+ def expand_regular_meetings(cls, meetings_in, end_date=None,
+ start_date=None):
+ """ For a given list of meetings, go through all of them and if
+ the meeting is recursive, expand the recursion as if they were
+ all different meetings.
+ The end_date keyword argument allows to stop the process earlier
+ allowing to have all recursive meeting up to a certain time
+ point.
+ The start_date keyword argument allows to only keep the meeting
+ from a certain time point.
+ """
+ meetings = []
+ for meeting in meetings_in:
+ if not end_date:
+ end_date = meeting.recursion_ends
+ if meeting.recursion_frequency and meeting.recursion_ends:
+ meeting_date = meeting.meeting_date
+ cnt = 0
+ while meeting_date <= end_date and \
+ meeting_date <= meeting.recursion_ends:
+ recmeeting = meeting.copy()
+ recmeeting.meeting_id = meeting.meeting_id
+ recmeeting.calendar = meeting.calendar
+ if start_date \
+ and meeting_date >= start_date:
+ recmeeting.meeting_date = \
+ meeting.meeting_date + timedelta(
+ days=meeting.recursion_frequency * cnt)
+ recmeeting.meeting_date_end = \
+ meeting.meeting_date_end + timedelta(
+ days=meeting.recursion_frequency * cnt)
+ meetings.append(recmeeting)
+ elif not start_date:
+ recmeeting.meeting_date = \
+ meeting.meeting_date + timedelta(
+ days=meeting.recursion_frequency * cnt)
+ recmeeting.meeting_date_end = \
+ meeting.meeting_date_end + timedelta(
+ days=meeting.recursion_frequency * cnt)
+ meetings.append(recmeeting)
+
+ cnt = cnt + 1
+ meeting_date = meeting.meeting_date + timedelta(
+ days=meeting.recursion_frequency * cnt)
+ else:
+ meetings.append(meeting)
+ meetings.sort(key=operator.attrgetter('meeting_date'))
+ return meetings
+
class Reminder(BASE):
""" Reminders table.
diff --git a/fedocal/tests/test_fedocallib.py b/fedocal/tests/test_fedocallib.py
index 601d261..3a18f43 100644
--- a/fedocal/tests/test_fedocallib.py
+++ b/fedocal/tests/test_fedocallib.py
@@ -520,10 +520,11 @@ class Fedocallibtests(Modeltests):
TODAY + timedelta(days=10),
TODAY + timedelta(days=12)
)
- self.assertEqual(len(meetings), 3)
+ self.assertEqual(len(meetings), 4)
for meeting in meetings:
self.assertTrue(meeting.meeting_name in ['test-meeting2',
- 'Another test meeting', 'Test meeting with reminder'])
+ 'Another test meeting', 'Test meeting with reminder',
+ 'Test meeting with reminder and recursion'])
self.assertEqual(meeting.meeting_manager, 'pingou,')
# pylint: disable=C0103
diff --git a/fedocal/tests/test_flask.py b/fedocal/tests/test_flask.py
index eca8fb5..40524c8 100644
--- a/fedocal/tests/test_flask.py
+++ b/fedocal/tests/test_flask.py
@@ -148,8 +148,8 @@ class Flasktests(Modeltests):
self.assertTrue('DESCRIPTION:This is a test meeting with '\
'recursion' in output.data)
self.assertTrue('ORGANIZER:pingou' in output.data)
- self.assertEqual(output.data.count('BEGIN:VEVENT'), 8)
- self.assertEqual(output.data.count('END:VEVENT'), 8)
+ self.assertEqual(output.data.count('BEGIN:VEVENT'), 45)
+ self.assertEqual(output.data.count('END:VEVENT'), 45)
def test_view_meeting(self):
""" Test the view_meeting function. """
diff --git a/fedocal/tests/test_flask_api.py b/fedocal/tests/test_flask_api.py
index 90a6afe..9f4fb7e 100644
--- a/fedocal/tests/test_flask_api.py
+++ b/fedocal/tests/test_flask_api.py
@@ -97,7 +97,7 @@ class FlaskApitests(Modeltests):
self.assertTrue(' "meeting_manager": "pingou, shaiton,",' in \
output.data)
self.assertTrue('"meeting_name": "test-meeting2"' in output.data)
- self.assertEqual(output.data.count('meeting_name'), 8)
+ self.assertEqual(output.data.count('meeting_name'), 45)
output = self.app.get('/api/date/test_calendar4/')
self.assertEqual(output.status_code, 200)
@@ -125,7 +125,7 @@ class FlaskApitests(Modeltests):
output.data)
self.assertTrue('"meeting_name": "Another test meeting2",' in \
output.data)
- self.assertEqual(output.data.count('meeting_name'), 4)
+ self.assertEqual(output.data.count('meeting_name'), 6)
end_date = TODAY + timedelta(days=2)
output = self.app.get('/api/date/test_calendar4/%s/%s/' % (TODAY,
diff --git a/fedocal/tests/test_meeting.py b/fedocal/tests/test_meeting.py
index 8377fa2..b12b17c 100644
--- a/fedocal/tests/test_meeting.py
+++ b/fedocal/tests/test_meeting.py
@@ -154,6 +154,7 @@ class Meetingtests(Modeltests):
recursion_frequency=7,
recursion_ends=TODAY + timedelta(days=90))
obj.save(self.session)
+
obj = model.Meeting( # id:8
meeting_name='Another test meeting2',
meeting_manager='pingou,',
@@ -398,6 +399,17 @@ class Meetingtests(Modeltests):
'This is a test meeting with recursion2')
self.assertEqual(obj[1].reminder, None)
+ obj = model.Meeting.get_by_date(self.session, cal,
+ week_start, week_stop, no_recursive=True)
+ self.assertNotEqual(obj, None)
+ self.assertEqual(len(obj), 1)
+ self.assertEqual(obj[0].meeting_name, 'Fedora-fr-test-meeting')
+ self.assertEqual(obj[0].meeting_manager, 'pingou, shaiton,')
+ self.assertEqual(obj[0].calendar.calendar_name, 'test_calendar')
+ self.assertEqual(obj[0].meeting_information,
+ 'This is a test meeting')
+ self.assertEqual(obj[0].reminder, None)
+
week_stop = week_day + timedelta(days=12)
obj = model.Meeting.get_by_date(self.session, cal,
week_start, week_stop)
11 years, 4 months
[fedocal] master: Add a boolean on the Meeting for full_day meeting (dbb5968)
by Pierre-YvesChibon
Repository : http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
>---------------------------------------------------------------
commit dbb59687c7f2e5bafe37bf68a17c5f67dbc38dd8
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Wed Dec 12 21:36:36 2012 +0100
Add a boolean on the Meeting for full_day meeting
This means that in the Week, full_day meetings are separated from the non full-day
meetings.
Adjust the queries to only return full_day meetings when we desire.
Adjust the unit-tests to cover the new features and test their behavior.
>---------------------------------------------------------------
.../versions/2e5d25a095df_add_boolean_to_meeti.py | 23 ++++++++++
fedocal/fedocallib/model.py | 22 +++++++---
fedocal/fedocallib/week.py | 17 +++++++
fedocal/tests/test_fedocallib.py | 16 ++++---
fedocal/tests/test_meeting.py | 45 ++++++++++++++++++-
fedocal/tests/test_week.py | 20 +++++++++
6 files changed, 127 insertions(+), 16 deletions(-)
diff --git a/alembic/versions/2e5d25a095df_add_boolean_to_meeti.py b/alembic/versions/2e5d25a095df_add_boolean_to_meeti.py
new file mode 100644
index 0000000..989986b
--- /dev/null
+++ b/alembic/versions/2e5d25a095df_add_boolean_to_meeti.py
@@ -0,0 +1,23 @@
+"""Add boolean to Meeting for full-day meeting
+
+Revision ID: 2e5d25a095df
+Revises: 45d83da297e8
+Create Date: 2012-12-12 08:46:15.378554
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '2e5d25a095df'
+down_revision = '45d83da297e8'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+ op.add_column('meetings', sa.Column('full_days',
+ sa.Boolean))
+
+
+def downgrade():
+ op.drop_column('meetings', 'full_days')
diff --git a/fedocal/fedocallib/model.py b/fedocal/fedocallib/model.py
index ce75348..9c0bfd5 100644
--- a/fedocal/fedocallib/model.py
+++ b/fedocal/fedocallib/model.py
@@ -148,6 +148,7 @@ class Meeting(BASE):
reminder_id = Column(Integer, ForeignKey('reminders.reminder_id'),
nullable=True)
reminder = relationship("Reminder")
+ full_day = Column(Boolean, default=False)
recursion_frequency = Column(Integer, nullable=True, default=None)
recursion_ends = Column(Date, nullable=True, default=None)
@@ -158,7 +159,7 @@ class Meeting(BASE):
meeting_time_start, meeting_time_stop,
meeting_information, calendar_name, reminder_id=None,
meeting_region=None, recursion_frequency=None,
- recursion_ends=None):
+ recursion_ends=None, full_day=False):
""" Constructor instanciating the defaults values. """
self.meeting_name = meeting_name
self.meeting_manager = meeting_manager
@@ -172,6 +173,7 @@ class Meeting(BASE):
self.meeting_region = meeting_region
self.recursion_frequency = recursion_frequency
self.recursion_ends = recursion_ends
+ self.full_day = full_day
def __repr__(self):
""" Representation of the Reminder object when printed.
@@ -234,6 +236,7 @@ class Meeting(BASE):
meeting.meeting_region = self.meeting_region
meeting.recursion_frequency = self.recursion_frequency
meeting.recursion_ends = self.recursion_ends
+ meeting.full_day = self.full_day
else:
meeting = Meeting(self.meeting_name, self.meeting_manager,
self.meeting_date, self.meeting_date_end,
@@ -243,7 +246,8 @@ class Meeting(BASE):
self.reminder_id,
self.meeting_region,
self.recursion_frequency,
- self.recursion_ends)
+ self.recursion_ends,
+ self.full_day)
return meeting
@classmethod
@@ -267,18 +271,21 @@ class Meeting(BASE):
return managers
@classmethod
- def get_by_date(cls, session, calendar, start_date, stop_date):
+ def get_by_date(cls, session, calendar, start_date, stop_date,
+ full_day=False):
""" Retrieve the list of meetings between two date.
We include the start date and exclude the stop date.
"""
return session.query(cls).filter(and_
(Meeting.calendar == calendar),
(Meeting.meeting_date >= start_date),
- (Meeting.meeting_date < stop_date)
+ (Meeting.meeting_date < stop_date),
+ (Meeting.full_day == full_day)
).order_by(Meeting.meeting_date).all()
@classmethod
- def get_active_regular_meeting(cls, session, calendar, end_date):
+ def get_active_regular_meeting(cls, session, calendar, end_date,
+ full_day=False):
""" Retrieve the list of meetings with a recursion which
end_date is not past the provided end_date and starting before
the end of the time considered.
@@ -287,7 +294,8 @@ class Meeting(BASE):
(Meeting.meeting_date <= end_date),
(Meeting.recursion_ends >= end_date),
(Meeting.calendar == calendar),
- (Meeting.recursion_frequency != None)
+ (Meeting.recursion_frequency != None),
+ (Meeting.full_day == full_day)
).order_by(Meeting.meeting_date).all()
return meetings
@@ -340,7 +348,7 @@ class Meeting(BASE):
(Meeting.meeting_time_stop > t_time)).all()
@classmethod
- def in_future_at_time(cls, session, calendar, meetingdate,
+ def get_in_future_at_time(cls, session, calendar, meetingdate,
recursion_ends, t_time):
""" Returns the meeting occuring at this specifict time point
at any time in the future.
diff --git a/fedocal/fedocallib/week.py b/fedocal/fedocallib/week.py
index 2d24291..0902870 100644
--- a/fedocal/fedocallib/week.py
+++ b/fedocal/fedocallib/week.py
@@ -34,7 +34,9 @@ class Week(object):
self.start_date = start_date
self.stop_date = start_date + timedelta(days=7)
self.meetings = []
+ self.full_day_meetings = []
self.get_meetings()
+ self.get_full_day_meetings()
def get_meetings(self):
""" Retrieves the list of this week meeting from the database.
@@ -51,6 +53,21 @@ class Week(object):
if meeting not in self.meetings:
self.meetings.append(meeting)
+ def get_full_day_meetings(self):
+ """ Retrieve all the full day meetings of this week. """
+ self.full_day_meetings = Meeting.get_by_date(self.session,
+ self.calendar, self.start_date, self.stop_date,
+ full_day=True)
+
+ for meeting in Meeting.get_active_regular_meeting(self.session,
+ self.calendar, self.stop_date, full_day=True):
+ for delta in range(0, 7):
+ day = self.start_date + timedelta(days=delta)
+ if ((meeting.meeting_date - day).days %
+ meeting.recursion_frequency) == 0:
+ if meeting not in self.full_day_meetings:
+ self.full_day_meetings.append(meeting)
+
def __repr__(self):
""" Representation of the Week object when printed.
"""
diff --git a/fedocal/tests/test_fedocallib.py b/fedocal/tests/test_fedocallib.py
index 3e8feaa..601d261 100644
--- a/fedocal/tests/test_fedocallib.py
+++ b/fedocal/tests/test_fedocallib.py
@@ -208,7 +208,7 @@ class Fedocallibtests(Modeltests):
if meeting is not None:
for meet in meeting:
self.assertEqual(meet.meeting_name,
- 'Another test meeting')
+ 'Another test meeting')
else:
cnt = cnt + 1
self.assertEqual(cnt, 6)
@@ -309,7 +309,7 @@ class Fedocallibtests(Modeltests):
meetings = fedocallib.get_future_single_meeting_of_user(self.session,
'pingou,', from_date=TODAY)
self.assertNotEqual(meetings, None)
- self.assertEqual(len(meetings), 3)
+ self.assertEqual(len(meetings), 4)
self.assertEqual(meetings[0].meeting_name,
'Fedora-fr-test-meeting')
self.assertEqual(meetings[0].meeting_information,
@@ -340,7 +340,7 @@ class Fedocallibtests(Modeltests):
meetings = fedocallib.get_future_regular_meeting_of_user(
self.session, 'pingou', from_date=TODAY)
self.assertNotEqual(meetings, None)
- self.assertEqual(len(meetings), 4)
+ self.assertEqual(len(meetings), 5)
self.assertEqual(meetings[0].meeting_name,
'Another past test meeting')
self.assertEqual(meetings[0].meeting_information,
@@ -354,8 +354,12 @@ class Fedocallibtests(Modeltests):
self.assertEqual(meetings[2].meeting_information,
'This is a test meeting with recursion')
self.assertEqual(meetings[3].meeting_name,
- 'Test meeting with reminder and recursion')
+ 'Full-day meeting with recursion')
self.assertEqual(meetings[3].meeting_information,
+ 'Full day meeting with recursion')
+ self.assertEqual(meetings[4].meeting_name,
+ 'Test meeting with reminder and recursion')
+ self.assertEqual(meetings[4].meeting_information,
'This is a test meeting with recursion and reminder')
# pylint: disable=C0103
@@ -495,14 +499,14 @@ class Fedocallibtests(Modeltests):
meetings = fedocallib.get_future_single_meeting_of_user(
self.session, 'pingou,', from_date=TODAY)
self.assertNotEqual(meetings, None)
- self.assertEqual(len(meetings), 3)
+ self.assertEqual(len(meetings), 4)
fedocallib.add_meetings_to_vcal(calendar, meetings)
cnt = 0
for event in calendar.vevent_list:
self.assertTrue(event.summary.value in [
'Fedora-fr-test-meeting', 'Test meeting with reminder',
- 'test-meeting2'])
+ 'test-meeting2', 'Full-day meeting'])
self.assertTrue(event.organizer.value in [
'pingou,', 'pingou, shaiton,'])
cnt = cnt + 1
diff --git a/fedocal/tests/test_meeting.py b/fedocal/tests/test_meeting.py
index b236c5c..8377fa2 100644
--- a/fedocal/tests/test_meeting.py
+++ b/fedocal/tests/test_meeting.py
@@ -236,7 +236,42 @@ class Meetingtests(Modeltests):
meeting_information='This is a past meeting with recursion',
calendar_name='test_calendar',
recursion_frequency=7,
- recursion_ends=TODAY + timedelta(days=90))
+ recursion_ends=TODAY + timedelta(days=90),
+ full_day=False)
+ obj.save(self.session)
+ self.session.commit()
+ self.assertNotEqual(obj, None)
+
+ # Full day meeting
+ obj = model.Meeting( # id:13
+ meeting_name='Full-day meeting',
+ meeting_manager='pingou,',
+ meeting_date=TODAY + timedelta(days=3),
+ meeting_date_end=TODAY + timedelta(days=3),
+ meeting_time_start=time(0, 00),
+ meeting_time_stop=time(23, 59),
+ meeting_information='This is a full day meeting',
+ calendar_name='test_calendar',
+ recursion_frequency=None,
+ recursion_ends=None,
+ full_day=True)
+ obj.save(self.session)
+ self.session.commit()
+ self.assertNotEqual(obj, None)
+
+ # Full day meeting with recursion
+ obj = model.Meeting( # id:14
+ meeting_name='Full-day meeting with recursion',
+ meeting_manager='pingou,',
+ meeting_date=TODAY + timedelta(days=10),
+ meeting_date_end=TODAY + timedelta(days=10),
+ meeting_time_start=time(0, 00),
+ meeting_time_stop=time(23, 59),
+ meeting_information='Full day meeting with recursion',
+ calendar_name='test_calendar',
+ recursion_frequency=7,
+ recursion_ends=TODAY + timedelta(days=30),
+ full_day=True)
obj.save(self.session)
self.session.commit()
self.assertNotEqual(obj, None)
@@ -497,13 +532,15 @@ class Meetingtests(Modeltests):
meetings = model.Meeting.get_future_single_meeting_of_user(
self.session, 'pingou,', TODAY)
self.assertNotEqual(meetings, None)
- self.assertEqual(len(meetings), 3)
+ self.assertEqual(len(meetings), 4)
self.assertEqual(meetings[0].meeting_name,
'Fedora-fr-test-meeting')
self.assertEqual(meetings[1].meeting_name,
'test-meeting2')
self.assertEqual(meetings[2].meeting_name,
'Test meeting with reminder')
+ self.assertEqual(meetings[3].meeting_name,
+ 'Full-day meeting')
# pylint: disable=C0103
def test_get_future_single_meeting_of_user_fail(self):
@@ -531,7 +568,7 @@ class Meetingtests(Modeltests):
meetings = model.Meeting.get_future_regular_meeting_of_user(
self.session, 'pingou', TODAY)
self.assertNotEqual(meetings, None)
- self.assertEqual(len(meetings), 4)
+ self.assertEqual(len(meetings), 5)
self.assertEqual(meetings[0].meeting_name,
'Another past test meeting')
self.assertEqual(meetings[1].meeting_name,
@@ -539,6 +576,8 @@ class Meetingtests(Modeltests):
self.assertEqual(meetings[2].meeting_name,
'Another test meeting')
self.assertEqual(meetings[3].meeting_name,
+ 'Full-day meeting with recursion')
+ self.assertEqual(meetings[4].meeting_name,
'Test meeting with reminder and recursion')
# pylint: disable=C0103
diff --git a/fedocal/tests/test_week.py b/fedocal/tests/test_week.py
index 6fb77f9..2f8ca1f 100644
--- a/fedocal/tests/test_week.py
+++ b/fedocal/tests/test_week.py
@@ -111,6 +111,26 @@ class Weektests(Modeltests):
self.assertEqual(weekobj.meetings[1].meeting_information,
'This is a test meeting with recursion2')
+ def test_meeting_in_week(self):
+ """ Test that the meetings in the week are correct function. """
+ calendar = model.Calendar.by_id(self.session, 'test_calendar')
+ weekobj = week.Week(self.session, calendar, TODAY)
+
+ self.assertNotEqual(weekobj, None)
+ self.assertEqual(len(weekobj.full_day_meetings), 1)
+ self.assertNotEqual(weekobj.full_day_meetings[0], None)
+ self.assertEqual(weekobj.full_day_meetings[0].meeting_name,
+ 'Full-day meeting')
+
+ weekobj = week.Week(self.session, calendar, (TODAY + timedelta(
+ days=15)))
+
+ self.assertNotEqual(weekobj, None)
+ self.assertEqual(len(weekobj.full_day_meetings), 1)
+ self.assertNotEqual(weekobj.full_day_meetings[0], None)
+ self.assertEqual(weekobj.full_day_meetings[0].meeting_name,
+ 'Full-day meeting with recursion')
+
if __name__ == '__main__':
SUITE = unittest.TestLoader().loadTestsFromTestCase(Weektests)
11 years, 4 months
[fedocal] master: First column display (aca2b9a)
by trasher@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
>---------------------------------------------------------------
commit aca2b9af4c9cca23806b471d058da46609ab2abb
Author: Johan Cwiklinski <johan(a)x-tnd.be>
Date: Tue Dec 11 23:22:17 2012 +0100
First column display
>---------------------------------------------------------------
fedocal/templates/agenda.html | 63 ++++++++++++++++++++++++++--------------
1 files changed, 41 insertions(+), 22 deletions(-)
diff --git a/fedocal/templates/agenda.html b/fedocal/templates/agenda.html
index 2dd50be..298cf4f 100644
--- a/fedocal/templates/agenda.html
+++ b/fedocal/templates/agenda.html
@@ -31,6 +31,26 @@
</nav>
{% endif %}
<div id='agenda'>
+{% macro render_meetings(meeting_list, loopidx) -%}
+ {% if loopidx == day_index %}
+ <td class="today">
+ {% else %}
+ <td>
+ {% endif %}
+ {% if meeting_list %}
+ {% for meeting in meeting_list %}
+ <a class="event meeting_{{ meeting.meeting_id }}"
+ href="{{ url_for('view_meeting',
+ meeting_id=meeting.meeting_id) }}">
+ {{ meeting.meeting_name }}
+ </a>
+ {% if not loop.last %}
+ -
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+ </td>
+{%- endmacro %}
<table>
<tr>
<th>{{ tzone }} time</th>
@@ -38,35 +58,34 @@
<th> {{ day.strftime('%A %d') }}</th>
{% endfor %}
</tr>
+ <tr>
+ <th class="time" rowspan="2">00h00</th>
+ <td colspan="7" class="empty"></td>
+ </tr>
{% for time_entry in meetings |sort %}
+ {% if time_entry == '00h00' %}
+ {% set previous_time_entry = time_entry %}
+ {% else %}
<tr>
{% if time_entry.endswith('00') %}
- <th class="time">{{ time_entry }}</th>
- {% else %}
- <th></th>
+ <th rowspan="2" class="time">{{ time_entry }}</th>
{% endif %}
- {% for meeting_list in meetings[time_entry] %}
- {% if loop.index == day_index %}
- <td class="today">
- {% else %}
- <td>
- {% endif %}
- {% if meeting_list %}
- {% for meeting in meeting_list %}
- <a class="event meeting_{{ meeting.meeting_id }}"
- href="{{ url_for('view_meeting',
- meeting_id=meeting.meeting_id) }}">
- {{ meeting.meeting_name }}
- </a>
- {% if not loop.last %}
- -
- {% endif %}
- {% endfor %}
- {% endif %}
- </td>
+ {% for meeting_list in meetings[previous_time_entry] %}
+ {{ render_meetings(meeting_list, loop.index) }}
{% endfor %}
+ {% set previous_time_entry = time_entry %}
</tr>
+ {% endif %}
{% endfor %}
+ <tr>
+ <th rowspan="2" class="time">00h00</th>
+ {% for meeting_list in meetings['23h30'] %}
+ {{ render_meetings(meeting_list, loop.index) }}
+ {% endfor %}
+ </tr>
+ <tr>
+ <td colspan="7" class="empty"></td>
+ </tr>
</table>
</div>
</section>
11 years, 4 months
[fedocal] #22: Add a list view
by fedocal
#22: Add a list view
--------------------+-------------------------
Reporter: pingou | Owner:
Type: defect | Status: new
Priority: major | Milestone: 0.1.0
Component: WebUI | Version: development
Keywords: |
--------------------+-------------------------
At the moment we only have a calendar view but we need to have somewhere a
list view to see:
a) all the events that occurred a given month
b) all the events that occurred over a given year
Basically view all the event over a time period in a table.
--
Ticket URL: <https://fedorahosted.org/fedocal/ticket/22>
fedocal <https://fedorahosted.org/fedocal>
A web-based calendar application for Fedora
11 years, 4 months
[fedocal] master: If the agenda isn't free, break and do the time zone change before checking the agenda (426de57)
by pingou@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
>---------------------------------------------------------------
commit 426de57fa966e58677f2ed3e30d94ff7750e7946
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Dec 11 21:59:16 2012 +0100
If the agenda isn't free, break and do the time zone change before checking the agenda
When editing a recursive meeting and checking if the agenda is free in the future, we
should adjust the meeting time zone beforehand.
Fix fedocallib unit-test accordingly. Make more use of TODAY in the unit-tests and move
the time in the test_edit_meeting to prevent two meetings overlapping.
>---------------------------------------------------------------
fedocal/fedocallib/__init__.py | 30 +++++++++++++++++-------------
fedocal/tests/test_fedocallib.py | 20 ++++++++++----------
2 files changed, 27 insertions(+), 23 deletions(-)
diff --git a/fedocal/fedocallib/__init__.py b/fedocal/fedocallib/__init__.py
index 851bb5d..ceedcfb 100644
--- a/fedocal/fedocallib/__init__.py
+++ b/fedocal/fedocallib/__init__.py
@@ -501,15 +501,19 @@ def agenda_is_free_in_future(session, calendar, meeting_date,
if time_start <= meeting.meeting_time_start \
and meeting.meeting_time_start < time_stop:
agenda_free = False
+ break
elif time_start < meeting.meeting_time_stop \
and meeting.meeting_time_stop <= time_stop:
agenda_free = False
+ break
elif time_start < meeting.meeting_time_start \
and time_stop > meeting.meeting_time_stop:
agenda_free = False
+ break
elif time_start > meeting.meeting_time_start \
and time_stop < meeting.meeting_time_stop:
agenda_free = False
+ break
return agenda_free
@@ -822,10 +826,22 @@ def edit_meeting(session, meeting, calendarobj, fas_user,
raise InvalidMeeting(
'The start date of your meeting is later than the end date.')
+ meeting_time_start = convert_time(
+ datetime(meeting_date.year, meeting_date.month, meeting_date.day,
+ meeting_time_start.hour,
+ meeting_time_start.minute),
+ tzone, 'UTC')
+ meeting_time_stop = convert_time(
+ datetime(meeting_date_end.year, meeting_date_end.month,
+ meeting_date_end.day,
+ meeting_time_stop.hour,
+ meeting_time_stop.minute),
+ tzone, 'UTC')
+
if recursion_frequency and recursion_ends:
futur_meeting_at_time = agenda_is_free_in_future(session,
calendarobj, meeting_date, recursion_ends,
- meeting_time_start, meeting_time_stop)
+ meeting_time_start.time(), meeting_time_stop.time())
if not bool(calendarobj.calendar_multiple_meetings) and \
not(futur_meeting_at_time):
@@ -866,18 +882,6 @@ def edit_meeting(session, meeting, calendarobj, fas_user,
bool(free_time):
new_meeting.save(session)
- meeting_time_start = convert_time(
- datetime(meeting_date.year, meeting_date.month, meeting_date.day,
- meeting_time_start.hour,
- meeting_time_start.minute),
- tzone, 'UTC')
- meeting_time_stop = convert_time(
- datetime(meeting_date_end.year, meeting_date_end.month,
- meeting_date_end.day,
- meeting_time_stop.hour,
- meeting_time_stop.minute),
- tzone, 'UTC')
-
meeting.meeting_name = meeting_name
meeting.meeting_manager = '%s,' % fas_user.username
if comanager:
diff --git a/fedocal/tests/test_fedocallib.py b/fedocal/tests/test_fedocallib.py
index b76eb7f..3e8feaa 100644
--- a/fedocal/tests/test_fedocallib.py
+++ b/fedocal/tests/test_fedocallib.py
@@ -613,7 +613,7 @@ class Fedocallibtests(Modeltests):
output = fedocallib.get_by_date(self.session, calendarobj, TODAY,
TODAY + relativedelta(years=+1))
self.assertNotEqual(output, None)
- self.assertEqual(len(output), 45)
+ self.assertEqual(len(output), 43)
# pylint: disable=R0915
def test_add_meeting_fail(self):
@@ -926,7 +926,7 @@ class Fedocallibtests(Modeltests):
fedocallib.edit_meeting(
self.session, meeting, calendarobj, fasuser,
'Fedora-fr-meeting_edited2',
- date.today() + timedelta(days=1), None,
+ TODAY + timedelta(days=1), None,
time(23, 0), time(23, 59), 'pingou',
'Information2', 'EMEA', 'Europe/Paris',
None, None,
@@ -941,7 +941,7 @@ class Fedocallibtests(Modeltests):
fedocallib.edit_meeting(
self.session, meeting, calendarobj, fasuser,
'Fedora-fr-meeting_edited',
- date.today() + timedelta(days=1), None,
+ TODAY + timedelta(days=1), None,
time(23, 0), time(23, 59), None,
'Information', 'EMEA', 'Europe/Paris',
None, None,
@@ -957,18 +957,18 @@ class Fedocallibtests(Modeltests):
fedocallib.edit_meeting(
self.session, meeting, calendarobj, fasuser,
- 'Fedora-fr-meeting_edited',
- date.today() + timedelta(days=1), None,
- time(23, 0), time(23, 59), None,
+ 'Fedora-fr-meeting_edited2',
+ TODAY + timedelta(days=1), None,
+ time(22, 0), time(23, 0), None,
'Information', 'EMEA', 'Europe/Paris',
7, TODAY + timedelta(days=30),
None, None)
meeting = model.Meeting.by_id(self.session, 1)
self.assertNotEqual(meeting, None)
- self.assertEqual(meeting.meeting_name, 'Fedora-fr-meeting_edited')
+ self.assertEqual(meeting.meeting_name, 'Fedora-fr-meeting_edited2')
self.assertEqual(meeting.meeting_manager, 'username,')
self.assertEqual(meeting.meeting_information, 'Information')
- self.assertEqual(meeting.meeting_time_stop.minute, 59)
+ self.assertEqual(meeting.meeting_time_stop.minute, 0)
self.assertEqual(meeting.recursion_frequency, 7)
self.assertEqual(meeting.recursion_ends, TODAY + timedelta(days=30))
self.assertEqual(meeting.reminder, None)
@@ -977,7 +977,7 @@ class Fedocallibtests(Modeltests):
self.session, meeting, calendarobj, fasuser,
'Fedora-fr-meeting_edited2',
date.today() + timedelta(days=1), None,
- time(23, 0), time(23, 59), None,
+ time(21, 0), time(22, 00), None,
'Information2', None, 'Europe/Paris',
None, None,
None, None)
@@ -997,7 +997,7 @@ class Fedocallibtests(Modeltests):
'Test meeting with reminder-2',
date.today() + timedelta(days=1), date.today() + timedelta(
days=3),
- time(23, 0), time(23, 59), None,
+ time(20, 0), time(21, 00), None,
'Information2', None, 'Europe/Paris',
None, None,
'H-24', 'test(a)example.org')
11 years, 4 months
[fedocal] master: In list view we go year to year or month to month not week to week (526122c)
by pingou@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
>---------------------------------------------------------------
commit 526122cb811bcabea994d6b646cfe480b2c98536
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Dec 11 21:12:13 2012 +0100
In list view we go year to year or month to month not week to week
>---------------------------------------------------------------
fedocal/__init__.py | 11 ++---------
fedocal/templates/meeting_list.html | 14 +++++++-------
2 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/fedocal/__init__.py b/fedocal/__init__.py
index cf059da..bae9c9b 100644
--- a/fedocal/__init__.py
+++ b/fedocal/__init__.py
@@ -211,12 +211,7 @@ def calendar_list(calendar_name, year, month, day):
tzone = get_timezone()
meetings = fedocallib.get_by_date(SESSION, calendarobj, start_date,
end_date, tzone)
- week_start = fedocallib.get_start_week(inyear, inmonth, inday)
- weekdays = fedocallib.get_week_days(inyear, inmonth, inday)
- next_week = fedocallib.get_next_week(week_start.year,
- week_start.month, week_start.day)
- prev_week = fedocallib.get_previous_week(week_start.year,
- week_start.month, week_start.day)
+
month_name = datetime.date.today().strftime('%B')
auth_form = forms.LoginForm()
admin = is_admin()
@@ -230,9 +225,7 @@ def calendar_list(calendar_name, year, month, day):
month=month_name,
meetings=meetings,
tzone=tzone,
- weekdays=weekdays,
- next_week=next_week,
- prev_week=prev_week,
+ year=inyear,
auth_form=auth_form,
curmonth_cal=curmonth_cal,
admin=admin)
diff --git a/fedocal/templates/meeting_list.html b/fedocal/templates/meeting_list.html
index 146b359..f564f43 100644
--- a/fedocal/templates/meeting_list.html
+++ b/fedocal/templates/meeting_list.html
@@ -17,15 +17,15 @@
<p>{{ calendar.calendar_description }}</p>
</header>
<nav id="weeks">
- <a href="{{url_for('calendar',
- calendar_name=calendar.calendar_name, year=prev_week.year,
- month=prev_week.month, day=prev_week.day)}}" class="button">
+ <a href="{{url_for('calendar_list',
+ calendar_name=calendar.calendar_name, year=year - 1)}}"
+ class="button">
<
</a>
- {{ weekdays | WeekHeading }}
- <a href="{{url_for('calendar',
- calendar_name=calendar.calendar_name, year=next_week.year,
- month=next_week.month, day=next_week.day)}}" class="button">
+ {{ year }}
+ <a href="{{url_for('calendar_list',
+ calendar_name=calendar.calendar_name, year=year + 1)}}"
+ class="button">
>
</a>
</nav>
11 years, 4 months
[fedocal] master: Fix the list for recursive meeting which started before the start date and fix add meeting (ebdf3c3)
by pingou@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
>---------------------------------------------------------------
commit ebdf3c32d649456a43a51773575c30165b2ea88a
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Dec 11 21:10:45 2012 +0100
Fix the list for recursive meeting which started before the start date and fix add meeting
when we check free time in the future to add or edit a meeting the error is if the agenda
is *not* free!
Fix unit-test according to the changes made for the recursive meetings
>---------------------------------------------------------------
fedocal/fedocallib/__init__.py | 31 +++++++++++++++++--------------
fedocal/tests/test_fedocallib.py | 2 +-
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/fedocal/fedocallib/__init__.py b/fedocal/fedocallib/__init__.py
index 2f3b311..851bb5d 100644
--- a/fedocal/fedocallib/__init__.py
+++ b/fedocal/fedocallib/__init__.py
@@ -671,24 +671,27 @@ def get_by_date(session, calendarobj, start_date, end_date, tzone='UTC'):
"""
meetings_utc = Meeting.get_by_date(session, calendarobj, start_date,
end_date)
+ meetings_utc.extend(Meeting.get_active_regular_meeting(session,
+ calendarobj, start_date))
meetings = []
- for meeting in meetings_utc:
+ for meeting in list(set(meetings_utc)):
if meeting.recursion_frequency and meeting.recursion_ends:
meeting_date = meeting.meeting_date
cnt = 0
- while meeting_date >= start_date and meeting_date < end_date \
- and meeting_date <= meeting.recursion_ends:
+ while meeting_date < end_date and \
+ meeting_date <= meeting.recursion_ends:
recmeeting = meeting.copy()
- recmeeting.meeting_id = meeting.meeting_id
- recmeeting.meeting_date = recmeeting.meeting_date + timedelta(
- days=recmeeting.recursion_frequency * cnt)
- recmeeting.meeting_date_end = recmeeting.meeting_date_end \
- + timedelta(days=recmeeting.recursion_frequency * cnt)
- meeting_date = recmeeting.meeting_date + timedelta(
- days=recmeeting.recursion_frequency)
- meetings.append(convert_meeting_timezone(recmeeting,
- 'UTC', tzone))
+ if meeting_date >= start_date:
+ recmeeting.meeting_id = meeting.meeting_id
+ recmeeting.meeting_date = meeting.meeting_date + timedelta(
+ days=meeting.recursion_frequency * cnt)
+ recmeeting.meeting_date_end = meeting.meeting_date_end \
+ + timedelta(days=meeting.recursion_frequency * cnt)
+ meetings.append(convert_meeting_timezone(recmeeting,
+ 'UTC', tzone))
cnt = cnt + 1
+ meeting_date = meeting.meeting_date + timedelta(
+ days=meeting.recursion_frequency * cnt)
else:
meetings.append(convert_meeting_timezone(meeting, 'UTC',
tzone))
@@ -747,7 +750,7 @@ def add_meeting(session, calendarobj, fas_user,
meeting_time_start.time(), meeting_time_stop.time())
if not bool(calendarobj.calendar_multiple_meetings) and \
- futur_meeting_at_time:
+ not(futur_meeting_at_time):
raise InvalidMeeting(
'The start or end time you have entered is already '
'occupied in the future.')
@@ -825,7 +828,7 @@ def edit_meeting(session, meeting, calendarobj, fas_user,
meeting_time_start, meeting_time_stop)
if not bool(calendarobj.calendar_multiple_meetings) and \
- futur_meeting_at_time:
+ not(futur_meeting_at_time):
raise InvalidMeeting(
'The start or end time you have entered is already '
'occupied in the future.')
diff --git a/fedocal/tests/test_fedocallib.py b/fedocal/tests/test_fedocallib.py
index fb245d1..b76eb7f 100644
--- a/fedocal/tests/test_fedocallib.py
+++ b/fedocal/tests/test_fedocallib.py
@@ -613,7 +613,7 @@ class Fedocallibtests(Modeltests):
output = fedocallib.get_by_date(self.session, calendarobj, TODAY,
TODAY + relativedelta(years=+1))
self.assertNotEqual(output, None)
- self.assertEqual(len(output), 30)
+ self.assertEqual(len(output), 45)
# pylint: disable=R0915
def test_add_meeting_fail(self):
11 years, 4 months
[fedocal] master: Finish up the list view (256418f)
by pingou@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
>---------------------------------------------------------------
commit 256418f676483f3f259f8851f85d5af181ff109d
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Dec 11 20:48:13 2012 +0100
Finish up the list view
With this commit, recursive meetings are displayed in the list view as single meeting but
with the correct meeting_id so that links still work.
Meetings are ordered by date.
Tests have been adjusted accordingly
>---------------------------------------------------------------
fedocal/__init__.py | 6 +---
fedocal/fedocallib/__init__.py | 40 ++++++++++++++++++++++++++++++++++++++
fedocal/tests/test_fedocallib.py | 34 ++++++++++++++++++++++++++++++-
3 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/fedocal/__init__.py b/fedocal/__init__.py
index 74f72a3..cf059da 100644
--- a/fedocal/__init__.py
+++ b/fedocal/__init__.py
@@ -209,10 +209,8 @@ def calendar_list(calendar_name, year, month, day):
calendarobj = Calendar.by_id(SESSION, calendar_name)
tzone = get_timezone()
- meetings_utc = Meeting.get_by_date(SESSION, calendarobj, start_date,
- end_date)
- meetings = [fedocallib.convert_meeting_timezone(meeting, 'UTC', tzone)
- for meeting in meetings_utc]
+ meetings = fedocallib.get_by_date(SESSION, calendarobj, start_date,
+ end_date, tzone)
week_start = fedocallib.get_start_week(inyear, inmonth, inday)
weekdays = fedocallib.get_week_days(inyear, inmonth, inday)
next_week = fedocallib.get_next_week(week_start.year,
diff --git a/fedocal/fedocallib/__init__.py b/fedocal/fedocallib/__init__.py
index f2ff36d..2f3b311 100644
--- a/fedocal/fedocallib/__init__.py
+++ b/fedocal/fedocallib/__init__.py
@@ -16,6 +16,7 @@ license.
import vobject
import pytz
+import operator
from datetime import datetime
from datetime import date
@@ -656,6 +657,45 @@ def get_html_monthly_cal(day=None, month=None, year=None,
return curmonth_cal_nf
+def get_by_date(session, calendarobj, start_date, end_date, tzone='UTC'):
+ """ Returns all the meetings in a given time period.
+ Recursive meetings are expanded as if each was a single meeting.
+
+ :arg session: the database session to use
+ :arg calendarobj: the calendar (object) of interest.
+ :arg start_date: a Date object representing the beginning of the
+ period
+ :arg start_date: a Date object representing the ending of the period
+ :kwarg tzone: the timezone in which the meetings should be displayed
+ defaults to UTC.
+ """
+ meetings_utc = Meeting.get_by_date(session, calendarobj, start_date,
+ end_date)
+ meetings = []
+ for meeting in meetings_utc:
+ if meeting.recursion_frequency and meeting.recursion_ends:
+ meeting_date = meeting.meeting_date
+ cnt = 0
+ while meeting_date >= start_date and meeting_date < end_date \
+ and meeting_date <= meeting.recursion_ends:
+ recmeeting = meeting.copy()
+ recmeeting.meeting_id = meeting.meeting_id
+ recmeeting.meeting_date = recmeeting.meeting_date + timedelta(
+ days=recmeeting.recursion_frequency * cnt)
+ recmeeting.meeting_date_end = recmeeting.meeting_date_end \
+ + timedelta(days=recmeeting.recursion_frequency * cnt)
+ meeting_date = recmeeting.meeting_date + timedelta(
+ days=recmeeting.recursion_frequency)
+ meetings.append(convert_meeting_timezone(recmeeting,
+ 'UTC', tzone))
+ cnt = cnt + 1
+ else:
+ meetings.append(convert_meeting_timezone(meeting, 'UTC',
+ tzone))
+ meetings.sort(key=operator.attrgetter('meeting_date'))
+ return meetings
+
+
# pylint: disable=R0913,R0914
def add_meeting(session, calendarobj, fas_user,
meeting_name, meeting_date, # meeting_date_end,
diff --git a/fedocal/tests/test_fedocallib.py b/fedocal/tests/test_fedocallib.py
index ed90b45..fb245d1 100644
--- a/fedocal/tests/test_fedocallib.py
+++ b/fedocal/tests/test_fedocallib.py
@@ -39,6 +39,7 @@ from datetime import date
from datetime import time
from datetime import datetime
from datetime import timedelta
+from dateutil.relativedelta import relativedelta
from sqlalchemy.exc import IntegrityError
@@ -593,8 +594,29 @@ class Fedocallibtests(Modeltests):
output = fedocallib.get_week_day_index()
self.assertEqual(output, today.isoweekday())
+ def test_get_by_date_empty(self):
+ """ Test the get_by_date function. """
+ self.__setup_calendar()
+ calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
+ self.assertNotEqual(calendarobj, None)
+ output = fedocallib.get_by_date(self.session, calendarobj, TODAY,
+ TODAY + relativedelta(years=+1))
+ self.assertNotEqual(output, None)
+ self.assertEqual(len(output), 0)
+ self.assertEqual(output, [])
+
+ def test_get_by_date(self):
+ """ Test the get_by_date function. """
+ self.__setup_meeting()
+ calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
+ self.assertNotEqual(calendarobj, None)
+ output = fedocallib.get_by_date(self.session, calendarobj, TODAY,
+ TODAY + relativedelta(years=+1))
+ self.assertNotEqual(output, None)
+ self.assertEqual(len(output), 30)
+
# pylint: disable=R0915
- def test_add_meeting(self):
+ def test_add_meeting_fail(self):
""" Test the add_meeting function. """
self.__setup_calendar()
calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
@@ -652,6 +674,14 @@ class Fedocallibtests(Modeltests):
None, None)
self.session.rollback()
+ # pylint: disable=R0915
+ def test_add_meeting(self):
+ """ Test the add_meeting function. """
+ self.__setup_calendar()
+ calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
+ self.assertNotEqual(calendarobj, None)
+ fasuser = FakeUser(['fi-apprentice'])
+
fedocallib.add_meeting(
self.session, calendarobj, fasuser,
'Name', date.today() + timedelta(days=1),
@@ -1030,4 +1060,4 @@ class Fedocallibtests(Modeltests):
if __name__ == '__main__':
SUITE = unittest.TestLoader().loadTestsFromTestCase(Fedocallibtests)
- unittest.TextTestRunner(verbosity=2).run(SUITE)
+ unittest.TextTestRunner(verbosity=2, failfast=True).run(SUITE)
11 years, 4 months
[fedocal] master: Little code formatting change (4da756e)
by pingou@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
>---------------------------------------------------------------
commit 4da756ed85bc754eb4ca754fc56f067620d13a76
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Dec 11 19:51:49 2012 +0100
Little code formatting change
>---------------------------------------------------------------
fedocal/__init__.py | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/fedocal/__init__.py b/fedocal/__init__.py
index ea2f80b..74f72a3 100644
--- a/fedocal/__init__.py
+++ b/fedocal/__init__.py
@@ -190,18 +190,15 @@ def calendar_list(calendar_name, year, month, day):
:arg month: the month of the date one would like to consult.
:arg day: the day of the date one would like to consult.
"""
+ inyear = year
if not year:
inyear = datetime.date.today().year
- else:
- inyear = year
+ inmonth = month
if not month:
inmonth = 1
- else:
- inmonth = month
+ inday = day
if not day:
inday = 1
- else:
- inday = day
start_date = datetime.date(inyear, inmonth, inday)
if not month and not day:
end_date = start_date + relativedelta(years=+1)
11 years, 4 months
[fedocal] master: Update the README (92b4b46)
by pingou@fedorahosted.org
Repository : http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
>---------------------------------------------------------------
commit 92b4b46ecdd488d05b31dd395e935176998d512b
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Tue Dec 11 19:44:32 2012 +0100
Update the README
To avoid duplication of documentation, update the README to link to the official
documentation remove the deployement instructions, remove the alembic information
since both are in the documentation.
Keep the list of dependencies in there as this is useful to have within the sources.
>---------------------------------------------------------------
README.rst | 83 ++++++------------------------------------------------------
1 files changed, 8 insertions(+), 75 deletions(-)
diff --git a/README.rst b/README.rst
index bd76d66..f3b3874 100644
--- a/README.rst
+++ b/README.rst
@@ -11,6 +11,7 @@ Get this project:
-----------------
Source: https://github.com/pypingou/fedocal
+Documentation: http://fedocal.rtfd.org
Dependencies:
@@ -28,13 +29,15 @@ Dependencies:
.. _alembic: https://bitbucket.org/zzzeek/alembic
.. _python-alembic: http://pypi.python.org/pypi/alembic
.. _pytz: http://pytz.sourceforge.net/
+.. _dateutil: http://labix.org/python-dateutil
+.. _python-dateutil: http://pypi.python.org/pypi/python-dateutil
This project is a `Flask`_ application. The calendars and meetings are
stored into a relational database using `SQLAlchemy`_ as Object Relational
Mapper (ORM) and `alembic`_ to handle database scheme changes.
fedocal provides an `iCal`_ feed for each calendar and relies on
`python-vobject`_ for this. Finally, `pytz`_ is used to handle the timezone
-changes.
+changes and `dateutil`_ to allow date manipulation over months/years.
The dependency list is therefore:
@@ -48,6 +51,7 @@ The dependency list is therefore:
- `python-kitchen`_
- `python-alembic`_
- `pytz`_
+- `python-dateutil`_
Running a development instance:
@@ -76,61 +80,6 @@ Run the server::
You should be able to access the server at http://localhost:5000
-Deploying this project:
------------------------
-
-.. _Flask deployment documentation: http://flask.pocoo.org/docs/deploying/
-
-Instruction to deploy this application is available on the
-`Flask deployment documentation`_ page.
-
- **My approach.**
-
-Below is the approach I took to deploy the instance on a local (test) machine.
-
-
-Retrieve the sources::
-
- cd /srv/
- git clone <repo>
- cd fedocal
-
-
-Copy the configuration file::
-
- cp fedocal.cfg.sample fedocal.cfg
-
-Adjust the configuration file (secret key, database URL, admin group...)
-
-Create the database scheme::
-
- python fedocal/fedocallib/model.py
-
-
-Then configure apache::
-
- sudo vim /etc/httd/conf.d/wsgi.conf
-
-and put in this file::
-
- WSGIScriptAlias /fedocal /var/www/wsgi/fedocal.wsgi
- <Directory /var/www/wsgi/>
- Order deny,allow
- Allow from all
- </Directory>
-
-Then create the file /var/www/wsgi/fedocal.wsgi with::
-
- import sys
- sys.path.insert(0, '/srv/fedocal/')
-
- import fedocal
- application = fedocal.APP
-
-
-Then restart apache and you should be able to access the website on
-http://localhost/fedocal
-
Testing:
--------
@@ -142,27 +91,11 @@ To run them::
./run_tests.sh
+.. note:: To stop the test at the first error or failure you can try:
-Database changes:
------------------
-.. _alembic tutorial: http://alembic.readthedocs.org/en/latest/tutorial.html
-
-The database changes are handled via `alembic`.
-
-
-If you are deploying fedocal for the first time, you will not need this,
-however, if you already have a running fedocal but the database scheme
-is not up to date, then you will have to run::
-
-
- alembic upgrade head
-
-.. note:: If this is the first time you are running ``alembic``, you will
- need to copy file ``alembic.ini.sample`` to ``alembic.ini`` and setup
- the ``sqlalchemy.url`` variable in the latest
-
+ ::
-If you are a developer, you probably want to have a look at the `alembic tutorial`_
+ ./run_tests.sh -x
License:
11 years, 4 months