Repository :
http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
---------------------------------------------------------------
commit 86c8fc2bd7fdcce3bc331cad16f4eca58e00cd0d
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Fri Nov 23 23:17:48 2012 +0100
Add time-zone to meeting edition and finish moving the editing to the backend
With this commit editing finally takes time-zone into account and we finish to move
to
the backend the logic to edit a meeting.
This brings us unit-tests coverage for the editing code.
---------------------------------------------------------------
fedocal/__init__.py | 92 +++++++---------------
fedocal/fedocallib/__init__.py | 139 ++++++++++++++++++++++++++++-----
fedocal/forms.py | 26 +++++-
fedocal/templates/edit_meeting.html | 4 +-
fedocal/tests/test_fedocallib.py | 146 ++++++++++++++++++++++++++++++++++-
5 files changed, 318 insertions(+), 89 deletions(-)
diff --git a/fedocal/__init__.py b/fedocal/__init__.py
index ac0b947..1c0ceb5 100644
--- a/fedocal/__init__.py
+++ b/fedocal/__init__.py
@@ -347,84 +347,52 @@ def edit_meeting(meeting_id):
'you are not allowed to edit it.')
return flask.redirect(flask.url_for('index'))
meeting = Meeting.by_id(SESSION, meeting_id)
- calendarobj = Calendar.by_id(SESSION, meeting.calendar_name)
if not fedocallib.is_date_in_future(meeting.meeting_date,
meeting.meeting_time_start.hour):
flask.flash('This meeting has already occured, you may not '\
'change it anymore')
- return flask.redirect(flask.url_for('index'))
+ calendarobj = Calendar.by_id(SESSION, meeting.calendar_name)
+ tzone = get_timezone()
form = forms.AddMeetingForm()
# pylint: disable=E1101
if form.validate_on_submit():
try:
- meeting.meeting_name = form.meeting_name.data
- meeting.meeting_manager = '%s,%s' % (
- flask.g.fas_user.username, form.comanager.data)
- meeting.meeting_date = form.meeting_date.data
- meeting_end_date = form.meeting_date_end.data
- if not meeting_end_date:
- meeting_end_date = form.meeting_date.data
- meeting.meeting_end_date = meeting_end_date
- meeting.meeting_time_start = form.meeting_time_start.data
- meeting.meeting_time_stop = form.meeting_time_stop.data
- meeting.meeting_information = form.information.data
-
- region = form.meeting_region.data
- if not region:
- region = None
- meeting.meeting_region = region
-
- frequency = form.frequency.data
- if not frequency:
- frequency = None
- meeting.recursion_frequency = frequency
-
- ends_date = form.end_repeats.data
- if not ends_date:
- ends_date = datetime.date(2025, 12, 31)
- meeting.recursion_ends = ends_date
-
- if form.remind_when.data and form.remind_who.data:
- if meeting.reminder_id:
- meeting.reminder.reminder_offset = form.remind_when.data
- meeting.reminder.reminder_to = form.remind_who.data
- meeting.reminder.save(SESSION)
- else:
- reminder = Reminder(form.remind_when.data,
- form.remind_who.data,
- None)
- reminder.save(SESSION)
- try:
- SESSION.flush()
- meeting.reminder = reminder
- SESSION.flush()
- except SQLAlchemyError, err:
- print 'edit_meeting:', err
- flask.flash('Could not edit the reminder of '\
- 'this meeting')
- return flask.render_template('edit_meeting.html',
- meeting=meeting, calendar=calendarobj,
- form=form)
- elif meeting.reminder_id:
- try:
- meeting.reminder.delete(SESSION)
- except SQLAlchemyError, err:
- print 'edit_meeting:', err
-
- meeting.save(SESSION)
- SESSION.commit()
+ fedocallib.edit_meeting(session=SESSION,
+ meeting=meeting,
+ calendarobj=calendarobj,
+ fas_user=flask.g.fas_user,
+ meeting_name=form.meeting_name.data,
+ meeting_date=form.meeting_date.data,
+ # meeting_date_end,
+ meeting_time_start=form.meeting_time_start.data,
+ meeting_time_stop=form.meeting_time_stop.data,
+ comanager=form.comanager.data,
+ meeting_information=form.information.data,
+ meeting_region=form.meeting_region.data,
+ tzone=get_timezone(),
+ frequency=form.frequency.data,
+ end_repeats=form.end_repeats.data,
+ remind_when=form.remind_when.data,
+ remind_who=form.remind_who.data)
+ except FedocalException, err:
+ flask.flash(err)
+ return flask.render_template('edit_meeting.html',
+ meeting=meeting, calendar=calendarobj, form=form,
+ tzone=tzone)
except SQLAlchemyError, err:
print 'edit_meeting:', err
flask.flash('Could not update this meeting.')
- return flask.redirect(flask.url_for('edit_meeting',
- meeting_id=meeting_id))
+ return flask.render_template('edit_meeting.html',
+ meeting=meeting, calendar=calendarobj, form=form,
+ tzone=tzone)
+
flask.flash('Meeting updated')
return flask.redirect(flask.url_for('view_meeting',
meeting_id=meeting_id))
else:
- form = forms.AddMeetingForm(meeting=meeting)
+ form = forms.AddMeetingForm(meeting=meeting, tzone=get_timezone())
return flask.render_template('edit_meeting.html', meeting=meeting,
- calendar=calendarobj, form=form)
+ calendar=calendarobj, form=form, tzone=tzone)
@APP.route('/meeting/<int:meeting_id>/', methods=('GET',
'POST'))
diff --git a/fedocal/fedocallib/__init__.py b/fedocal/fedocallib/__init__.py
index 1863c85..b6b4aa8 100644
--- a/fedocal/fedocallib/__init__.py
+++ b/fedocal/fedocallib/__init__.py
@@ -236,29 +236,41 @@ def get_meetings(session, calendar, year=None, month=None,
day=None,
# pylint: disable=W0612
meetings[key] = [None for cnt2 in range(0, 7)]
for meeting in week.meetings:
- start_minute = meeting.meeting_time_start.minute
- stop_minute = meeting.meeting_time_stop.minute
- if start_minute != 0 and start_minute != 30:
- if start_minute - 30 > 0:
- start_minute = 30
- else:
- start_minute = 0
- if stop_minute != 0 and stop_minute != 30:
- if stop_minute - 30 > 0:
- stop_minute = 30
- else:
- stop_minute = 0
- startdt = datetime(2000, 01, 01, meeting.meeting_time_start.hour,
- start_minute, 0)
- stopdt = datetime(2000, 01, 01, meeting.meeting_time_stop.hour,
- stop_minute, 0)
+
+ start_delta = 0
+ if meeting.meeting_time_start.minute < 15:
+ start_delta = meeting.meeting_time_start.minute - 30
+ elif 15 <= meeting.meeting_time_start.minute <= 45:
+ start_delta = 30 - meeting.meeting_time_start.minute
+ elif meeting.meeting_time_start.minute > 45:
+ start_delta = 60 - meeting.meeting_time_start.minute
+
+ stop_delta = 0
+ if meeting.meeting_time_stop.minute < 15:
+ stop_delta = meeting.meeting_time_stop.minute - 30
+ elif 15 <= meeting.meeting_time_stop.minute <= 45:
+ stop_delta = 30 - meeting.meeting_time_stop.minute
+ elif meeting.meeting_time_stop.minute > 45:
+ stop_delta = 60 - meeting.meeting_time_stop.minute
+
+ startdt = datetime(meeting.meeting_date.year,
+ meeting.meeting_date.month, meeting.meeting_date.day,
+ meeting.meeting_time_start.hour,
+ meeting.meeting_time_start.minute, 0) + timedelta(
+ minutes=start_delta)
+ stopdt = datetime(meeting.meeting_date.year,
+ meeting.meeting_date.month, meeting.meeting_date.day,
+ meeting.meeting_time_stop.hour,
+ meeting.meeting_time_stop.minute, 0) + timedelta(
+ minutes=stop_delta)
startdt = convert_time(startdt, 'UTC', tzone)
stopdt = convert_time(stopdt, 'UTC', tzone)
+
t_time = startdt
while t_time < stopdt:
- day = meeting.meeting_date.weekday()
+ day = startdt.weekday()
key = t_time.strftime(fmt)
if key in meetings:
if meetings[key][day]:
@@ -561,11 +573,13 @@ def add_meeting(session, calendarobj, fas_user,
'The start time of your meeting is later than the stop time.')
meeting_time_start = convert_time(
- datetime(2000, 1, 1, meeting_time_start.hour,
+ 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(2000, 1, 1, meeting_time_stop.hour,
+ datetime(meeting_date.year, meeting_date.month, meeting_date.day,
+ meeting_time_stop.hour,
meeting_time_stop.minute),
tzone, 'UTC')
@@ -599,7 +613,7 @@ def add_meeting(session, calendarobj, fas_user,
dbaction.add_meeting(session=session,
meeting_name=meeting_name,
meeting_manager=managers,
- meeting_date=meeting_date,
+ meeting_date=meeting_time_start.date(),
meeting_date_end=None,
meeting_time_start=meeting_time_start,
meeting_time_stop=meeting_time_stop,
@@ -611,3 +625,88 @@ def add_meeting(session, calendarobj, fas_user,
recursion_ends=end_repeats)
session.commit()
+
+def edit_meeting(session, meeting, calendarobj, fas_user,
+ meeting_name, meeting_date, # meeting_date_end,
+ meeting_time_start, meeting_time_stop, comanager,
+ meeting_information,
+ meeting_region, tzone,
+ frequency, end_repeats,
+ remind_when, remind_who):
+ """ When a user wants to edit a meeting to the database, we need to
+ perform a number of test first checking that the input is valid
+ and then edit the desired meeting.
+ """
+ if not is_user_managing_in_calendar(session,
+ calendarobj.calendar_name, fas_user):
+ raise UserNotAllowed('You are not allowed to add'\
+ ' a meeting to this calendar')
+
+ if not is_date_in_future(meeting_date, meeting_time_start):
+ raise InvalidMeeting('The date you entered is in '\
+ 'the past')
+
+ if meeting_time_start > meeting_time_stop:
+ raise InvalidMeeting(
+ 'The start time of your meeting is later than the stop time.')
+
+ 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.year, meeting_date.month, meeting_date.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:
+ meeting.meeting_manager = '%s%s,' % (meeting.meeting_manager,
+ comanager)
+
+ meeting.meeting_date = meeting_time_start.date()
+ meeting_end_date = None # meeting_date_end
+ if not meeting_end_date:
+ meeting_end_date = meeting_time_start.date()
+ meeting.meeting_end_date = meeting_end_date
+ meeting.meeting_time_start = meeting_time_start.time()
+ meeting.meeting_time_stop = meeting_time_stop.time()
+ meeting.meeting_information = meeting_information
+
+ region = meeting_region
+ if not region:
+ region = None
+ meeting.meeting_region = region
+
+ frequency = frequency
+ if not frequency:
+ frequency = None
+ meeting.recursion_frequency = frequency
+
+ ends_date = end_repeats
+ if not ends_date:
+ ends_date = date(2025, 12, 31)
+ meeting.recursion_ends = ends_date
+
+ if remind_when and remind_who:
+ if meeting.reminder_id:
+ meeting.reminder.reminder_offset = remind_when
+ meeting.reminder.reminder_to = remind_who
+ meeting.reminder.save(session)
+ else:
+ reminder = Reminder(remind_when,
+ remind_who,
+ None)
+ reminder.save(session)
+ session.flush()
+ meeting.reminder = reminder
+ session.flush()
+ elif meeting.reminder_id:
+ meeting.reminder.delete(session)
+ meeting.reminder_id = None
+
+ meeting.save(session)
+ session.commit()
diff --git a/fedocal/forms.py b/fedocal/forms.py
index b777350..3b7f13f 100644
--- a/fedocal/forms.py
+++ b/fedocal/forms.py
@@ -26,8 +26,9 @@
import flask
from flask.ext import wtf
from datetime import time
+from datetime import datetime
-from fedocallib import HOURS
+import fedocallib
def validate_time(form, field):
@@ -107,11 +108,28 @@ class AddMeetingForm(wtf.Form):
super(AddMeetingForm, self).__init__(*args, **kwargs)
if 'meeting' in kwargs:
meeting = kwargs['meeting']
+ tzone = 'UTC'
+ if 'tzone' in kwargs:
+ tzone = kwargs['tzone']
+
+ # Convert time to user's timezone
+ startdt = datetime(meeting.meeting_date.year,
+ meeting.meeting_date.month, meeting.meeting_date.day,
+ meeting.meeting_time_start.hour,
+ meeting.meeting_time_start.minute, 0)
+ stopdt = datetime(meeting.meeting_date.year,
+ meeting.meeting_date.month, meeting.meeting_date.day,
+ meeting.meeting_time_stop.hour,
+ meeting.meeting_time_stop.minute, 0)
+
+ startdt = fedocallib.convert_time(startdt, 'UTC', tzone)
+ stopdt = fedocallib.convert_time(stopdt, 'UTC', tzone)
+
self.meeting_name.data = meeting.meeting_name
- self.meeting_date.data = meeting.meeting_date
+ self.meeting_date.data = startdt.date()
self.meeting_date_end.data = meeting.meeting_date_end
- self.meeting_time_start.data = meeting.meeting_time_start
- self.meeting_time_stop.data = meeting.meeting_time_stop
+ self.meeting_time_start.data = startdt.time()
+ self.meeting_time_stop.data = stopdt.time()
self.information.data = meeting.meeting_information
# You are not allowed to remove yourself from the managers.
meeting_manager = meeting.meeting_manager.replace(
diff --git a/fedocal/templates/edit_meeting.html b/fedocal/templates/edit_meeting.html
index 7dc93c9..62d1a41 100644
--- a/fedocal/templates/edit_meeting.html
+++ b/fedocal/templates/edit_meeting.html
@@ -16,8 +16,8 @@
<table>
{{ render_field_in_row(form.meeting_name) }}
{{ render_field_in_row(form.meeting_date) }}
- {{ render_field_in_row(form.meeting_time_start) }}
- {{ render_field_in_row(form.meeting_time_stop) }}
+ {{ render_field_in_row(form.meeting_time_start, after="%s time" %
tzone) }}
+ {{ render_field_in_row(form.meeting_time_stop, after="%s time" %
tzone) }}
{{ render_field_in_row(form.comanager) }}
{{ render_field_in_row(form.information) }}
{% if calendar.calendar_regional_meetings %}
diff --git a/fedocal/tests/test_fedocallib.py b/fedocal/tests/test_fedocallib.py
index 0227e45..a75c65b 100644
--- a/fedocal/tests/test_fedocallib.py
+++ b/fedocal/tests/test_fedocallib.py
@@ -201,7 +201,7 @@ class Fedocallibtests(Modeltests):
new_day.year, new_day.month, new_day.day)
self.assertNotEqual(meetings, None)
cnt = 0
- for meeting in meetings['14h00']:
+ for meeting in meetings['14h30']:
if meeting is not None:
for meet in meeting:
self.assertEqual(meet.meeting_name, 'test-meeting2')
@@ -839,6 +839,150 @@ class Fedocallibtests(Modeltests):
self.assertEqual(meeting.meeting_information, 'Information')
self.assertEqual(meeting.meeting_time_stop.minute, 59)
+ def test_edit_meeting(self):
+ """ Test the edit_meeting function. """
+ self.__setup_meeting()
+ calendarobj = model.Calendar.by_id(self.session, 'test_calendar')
+ self.assertNotEqual(calendarobj, None)
+
+ meeting = model.Meeting.by_id(self.session, 1)
+ self.assertEqual(meeting.meeting_name, 'Fedora-fr-test-meeting')
+
+ fasuser = FakeUser(['test'])
+ self.assertRaises(UserNotAllowed, fedocallib.edit_meeting,
+ self.session, meeting, calendarobj, fasuser,
+ 'Fedora-fr-meeting_edited',
+ date.today() + timedelta(days=1),
+ time(23, 0), time(23, 59), None,
+ 'Information', 'EMEA', 'Europe/Paris',
+ None, None,
+ None, None)
+ self.session.rollback()
+
+ fasuser = FakeUser(['fi-apprentice'])
+
+ self.assertRaises(InvalidMeeting, fedocallib.edit_meeting,
+ self.session, meeting, calendarobj, fasuser,
+ 'Fedora-fr-meeting_edited',
+ date.today() - timedelta(days=1),
+ time(23, 0), time(23, 59), None,
+ 'Information', 'EMEA', 'Europe/Paris',
+ None, None,
+ None, None)
+ self.session.rollback()
+
+ self.assertRaises(InvalidMeeting, fedocallib.edit_meeting,
+ self.session, meeting, calendarobj, fasuser,
+ 'Fedora-fr-meeting_edited',
+ date.today() + timedelta(days=1),
+ time(23, 0), time(21, 59), None,
+ 'Information', 'EMEA', 'Europe/Paris',
+ None, None,
+ None, None)
+ self.session.rollback()
+
+ fedocallib.edit_meeting(
+ self.session, meeting, calendarobj, fasuser,
+ 'Fedora-fr-meeting_edited',
+ date.today() + timedelta(days=1),
+ time(23, 0), time(23, 59), None,
+ 'Information', 'EMEA', 'Europe/Paris',
+ None, None,
+ 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_manager, 'username,')
+ self.assertEqual(meeting.meeting_information, 'Information')
+ self.assertEqual(meeting.meeting_time_stop.minute, 59)
+
+ fedocallib.edit_meeting(
+ self.session, meeting, calendarobj, fasuser,
+ 'Fedora-fr-meeting_edited2',
+ date.today() + timedelta(days=1),
+ time(23, 0), time(23, 59), 'pingou',
+ 'Information2', 'EMEA', 'Europe/Paris',
+ None, None,
+ None, None)
+ meeting = model.Meeting.by_id(self.session, 1)
+ self.assertNotEqual(meeting, None)
+ self.assertEqual(meeting.meeting_name, 'Fedora-fr-meeting_edited2')
+ self.assertEqual(meeting.meeting_manager, 'username,pingou,')
+ self.assertEqual(meeting.meeting_information, 'Information2')
+ self.assertEqual(meeting.meeting_time_stop.minute, 59)
+
+ fedocallib.edit_meeting(
+ self.session, meeting, calendarobj, fasuser,
+ 'Fedora-fr-meeting_edited',
+ date.today() + timedelta(days=1),
+ time(23, 0), time(23, 59), None,
+ 'Information', 'EMEA', 'Europe/Paris',
+ None, None,
+ 'H-24', 'test(a)example.org')
+ 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_manager, 'username,')
+ self.assertEqual(meeting.meeting_information, 'Information')
+ self.assertEqual(meeting.meeting_time_stop.minute, 59)
+ self.assertEqual(meeting.reminder.reminder_offset, 'H-24')
+ self.assertEqual(meeting.reminder.reminder_to, 'test(a)example.org')
+
+ fedocallib.edit_meeting(
+ self.session, meeting, calendarobj, fasuser,
+ 'Fedora-fr-meeting_edited',
+ date.today() + timedelta(days=1),
+ time(23, 0), time(23, 59), 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_manager, 'username,')
+ self.assertEqual(meeting.meeting_information, 'Information')
+ self.assertEqual(meeting.meeting_time_stop.minute, 59)
+ self.assertEqual(meeting.recursion_frequency, 7)
+ self.assertEqual(meeting.recursion_ends, TODAY + timedelta(days=30))
+ self.assertEqual(meeting.reminder, None)
+
+ fedocallib.edit_meeting(
+ self.session, meeting, calendarobj, fasuser,
+ 'Fedora-fr-meeting_edited2',
+ date.today() + timedelta(days=1),
+ time(23, 0), time(23, 59), None,
+ 'Information2', None, 'Europe/Paris',
+ None, None,
+ None, None)
+ meeting = model.Meeting.by_id(self.session, 1)
+ self.assertNotEqual(meeting, None)
+ self.assertEqual(meeting.meeting_name, 'Fedora-fr-meeting_edited2')
+ self.assertEqual(meeting.meeting_manager, 'username,')
+ self.assertEqual(meeting.meeting_information, 'Information2')
+ self.assertEqual(meeting.meeting_region, None)
+ self.assertEqual(meeting.recursion_frequency, None)
+ self.assertEqual(meeting.recursion_ends, date(2025, 12, 31))
+ self.assertEqual(meeting.reminder, None)
+
+ meeting = model.Meeting.by_id(self.session, 9)
+ fedocallib.edit_meeting(
+ self.session, meeting, calendarobj, fasuser,
+ 'Test meeting with reminder-2',
+ date.today() + timedelta(days=1),
+ time(23, 0), time(23, 59), None,
+ 'Information2', None, 'Europe/Paris',
+ None, None,
+ 'H-24', 'test(a)example.org')
+ meeting = model.Meeting.by_id(self.session, 9)
+ self.assertNotEqual(meeting, None)
+ self.assertEqual(meeting.meeting_name,
+ 'Test meeting with reminder-2')
+ self.assertEqual(meeting.meeting_manager, 'username,')
+ self.assertEqual(meeting.meeting_information, 'Information2')
+ self.assertEqual(meeting.reminder.reminder_offset, 'H-24')
+ self.assertEqual(meeting.reminder.reminder_to, 'test(a)example.org')
+
+
if __name__ == '__main__':
SUITE = unittest.TestLoader().loadTestsFromTestCase(Fedocallibtests)
unittest.TextTestRunner(verbosity=2).run(SUITE)