Repository :
http://git.fedorahosted.org/cgit/fedocal.git
On branch : master
---------------------------------------------------------------
commit fe70a4e1a8354d7813c01e9de56de90641c81fd9
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Thu Nov 8 17:23:03 2012 +0100
Start implementing the user's timezone for logged user
---------------------------------------------------------------
fedocal/__init__.py | 55 +++++++++++++++++++++++++++--------
fedocal/fedocallib/__init__.py | 36 +++++++++++++++++------
fedocal/templates/add_meeting.html | 4 +-
fedocal/templates/agenda.html | 2 +-
4 files changed, 71 insertions(+), 26 deletions(-)
diff --git a/fedocal/__init__.py b/fedocal/__init__.py
index e67c86c..c73b9db 100644
--- a/fedocal/__init__.py
+++ b/fedocal/__init__.py
@@ -59,6 +59,10 @@ SESSION = fedocallib.create_session(CONFIG.get('fedocal',
'db_url'))
@APP.context_processor
def inject_calendars():
+ """ With this decorator we add the list of all the calendars
+ available to all the function, so the variable calendars is available
+ in all templates.
+ """
calendars = Calendar.get_all(SESSION)
return dict(calendars=calendars)
@@ -75,8 +79,11 @@ def reverse_filter(weekdays):
@APP.teardown_request
def shutdown_session(exception=None):
+ """ Remove the DB session at the end of each request.
"""
SESSION.remove()
+
+## Local function
def is_admin():
""" Return wether the user is admin for this application or not.
"""
if not flask.g.fas_user:
@@ -87,6 +94,16 @@ def is_admin():
return False
+def get_timezone():
+ """ Return the user's timezone, default to UTC.
"""
+ tzone = 'UTC'
+ if flask.g.fas_user:
+ if flask.g.fas_user['timezone']:
+ tzone = flask.g.fas_user['timezone']
+ return tzone
+
+
+## Flask application
@APP.route('/')
def index():
""" Displays the index page with containing the first calendar (by
@@ -129,8 +146,9 @@ def calendar_fullday(calendar_name, year, month, day):
week_start = fedocallib.get_start_week(year, month, day)
weekdays = fedocallib.get_week_days(year, month, day)
day_index = fedocallib.get_week_day_index(year, month, day)
+ tzone = get_timezone()
meetings = fedocallib.get_meetings(SESSION, calendarobj, year,
- month, day)
+ month, day, tzone=tzone)
next_week = fedocallib.get_next_week(week_start.year,
week_start.month, week_start.day)
prev_week = fedocallib.get_previous_week(week_start.year,
@@ -146,6 +164,7 @@ def calendar_fullday(calendar_name, year, month, day):
weekdays=weekdays,
day_index=day_index,
meetings=meetings,
+ tzone=tzone,
next_week=next_week,
prev_week=prev_week,
auth_form=auth_form,
@@ -260,6 +279,7 @@ def add_meeting(calendar_name):
if not flask.g.fas_user:
return flask.redirect(flask.url_for('index'))
form = forms.AddMeetingForm()
+ tzone = get_timezone()
calendarobj = Calendar.by_id(SESSION, calendar_name)
if form.validate_on_submit():
if not fedocallib.is_user_managing_in_calendar(SESSION,
@@ -271,13 +291,14 @@ def add_meeting(calendar_name):
form.meeting_time_start.data):
flask.flash('The date you entered is in the past')
return flask.redirect(flask.url_for('add_meeting',
- calendar_name=calendarobj.calendar_name))
+ calendar_name=calendarobj.calendar_name, form=form,
+ tzone=tzone))
elif int(form.meeting_time_start.data) > \
int(form.meeting_time_stop.data):
flask.flash('The start time you have entered is later than'\
' the stop time.')
flask.render_template('add_meeting.html',
- calendar=calendarobj, form=form)
+ calendar=calendarobj, form=form, tzone=tzone)
elif bool(calendarobj.calendar_multiple_meetings) or \
(not bool(calendarobj.calendar_multiple_meetings) and \
fedocallib.agenda_is_free(SESSION,
@@ -299,16 +320,24 @@ def add_meeting(calendar_name):
region = None
meeting_end_date = form.meeting_date_end.data
if not meeting_end_date:
- meeting_end_date = form.meeting_date.date
+ meeting_end_date = form.meeting_date.data
+
+ tzone = get_timezone()
+ meeting_time_start = fedocallib.convert_time(
+ datetime.datetime(2000, 1, 1,
+ int(form.meeting_time_start.data), 0),
+ tzone, 'UTC')
+ meeting_time_stop = fedocallib.convert_time(
+ datetime.datetime(2000, 1, 1,
+ int(form.meeting_time_stop.data), 0),
+ tzone, 'UTC')
meeting = Meeting(
meeting_name=form.meeting_name.data,
meeting_manager=manager,
meeting_date=form.meeting_date.data,
meeting_date_end=meeting_end_date,
- meeting_time_start=datetime.time(int(
- form.meeting_time_start.data)),
- meeting_time_stop=datetime.time(int(
- form.meeting_time_stop.data)),
+ meeting_time_start=meeting_time_start.time(),
+ meeting_time_stop=meeting_time_stop.time(),
meeting_information=form.information.data,
calendar_name=calendarobj.calendar_name,
reminder_id=None,
@@ -322,7 +351,7 @@ def add_meeting(calendar_name):
print 'add_meeting:', err
flask.flash('Could not add this meeting to this calendar')
return flask.render_template('add_meeting.html',
- calendar=calendarobj, form=form)
+ calendar=calendarobj, form=form, tzone=tzone)
if form.remind_when.data and form.remind_who.data:
reminder = Reminder(form.remind_when.data,
@@ -337,7 +366,7 @@ def add_meeting(calendar_name):
print 'add_meeting:', err
flask.flash('Could not add this reminder to this meeting')
return flask.render_template('add_meeting.html',
- calendar=calendarobj, form=form)
+ calendar=calendarobj, form=form, tzone=tzone)
try:
SESSION.commit()
@@ -345,7 +374,7 @@ def add_meeting(calendar_name):
flask.flash(
'Something went wrong while commiting to the DB.')
flask.render_template('add_meeting.html',
- calendar=calendarobj, form=form)
+ calendar=calendarobj, form=form, tzone=tzone)
flask.flash('Meeting added')
return flask.redirect(flask.url_for('calendar',
@@ -354,9 +383,9 @@ def add_meeting(calendar_name):
flask.flash(
'The start time you have entered is already occupied.')
return flask.render_template('add_meeting.html',
- calendar=calendarobj, form=form)
+ calendar=calendarobj, form=form, tzone=tzone)
return flask.render_template('add_meeting.html',
- calendar=calendarobj, form=form)
+ calendar=calendarobj, form=form, tzone=tzone)
# CLA + 1
diff --git a/fedocal/fedocallib/__init__.py b/fedocal/fedocallib/__init__.py
index 220fe5b..d69cbe0 100644
--- a/fedocal/fedocallib/__init__.py
+++ b/fedocal/fedocallib/__init__.py
@@ -15,6 +15,7 @@ license.
"""
import vobject
+import pytz
from datetime import datetime
from datetime import date
@@ -36,6 +37,21 @@ HOURS = ['00', '01', '02', '03',
'04', '05', '06', '07', '08', '09',
'20', '21', '22', '23', '24']
+def convert_time(timeobj, tzfrom, tzto):
+ """ Convert a given datetime object from a specified timezone to
+ the other specified.
+
+ :arg timeobj: a datetime object to convert
+ :arg tzfrom: the timezone from which to convert
+ :arg tzto: the timezone to which to convert
+ """
+ timez_from = pytz.timezone(tzfrom)
+ timez_to = pytz.timezone(tzto)
+ timeobj_from = timez_from.localize(timeobj)
+ timeobj_to = timeobj_from.astimezone(timez_to)
+ return timeobj_to
+
+
def create_session(db_url, debug=False, pool_recycle=3600):
""" Create the Session object to use to query the database.
@@ -193,7 +209,8 @@ def get_week_day_index(year=None, month=None, day=None):
return date(year, month, day).isoweekday()
-def get_meetings(session, calendar, year=None, month=None, day=None):
+def get_meetings(session, calendar, year=None, month=None, day=None,
+ tzone='UTC'):
""" Return a hash of {time: [meeting]} for the asked week. The week
is returned based either on the current utc week or based on the
information provided.
@@ -203,14 +220,15 @@ def get_meetings(session, calendar, year=None, month=None,
day=None):
:kwarg year: year to consider when searching a week.
:kwarg month: month to consider when searching a week.
:kwarg day: day to consider when searching a week.
+ :kwarg tzone: the timezone in which the meetings should be displayed
+ defaults to UTC.
"""
week = get_week(session, calendar, year, month, day)
meetings = {}
- cnt = 1
+ fmt = '%Hh%M'
for hour in HOURS[:-1]:
- key = '%sh - %sh' % (hour, HOURS[cnt])
+ key = '%sh00' % (hour)
meetings[key] = [None for cnt2 in range(0, 7)]
- cnt = cnt + 1
for meeting in week.meetings:
start = meeting.meeting_time_start.hour
stop = meeting.meeting_time_stop.hour
@@ -220,12 +238,10 @@ def get_meetings(session, calendar, year=None, month=None,
day=None):
cnt = 0
for item in order:
start_time = start + item
- stop_time = stop - invorder[cnt]
- if len(str(start_time)) == 1:
- start_time = '0%i' % start_time
- if len(str(stop_time)) == 1:
- stop_time = '0%i' % stop_time
- key = '%sh - %sh' % (start_time, stop_time)
+ key = convert_time(
+ datetime(2000, 01, 01, int(start_time), 0, 0),
+ 'UTC',
+ tzone).strftime(fmt)
day = meeting.meeting_date.weekday()
if key in meetings:
if meetings[key][day]:
diff --git a/fedocal/templates/add_meeting.html b/fedocal/templates/add_meeting.html
index c5b2b07..10043ee 100644
--- a/fedocal/templates/add_meeting.html
+++ b/fedocal/templates/add_meeting.html
@@ -14,8 +14,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.information) }}
{% if calendar.calendar_regional_meetings %}
{{ render_field_in_row(form.meeting_region) }}
diff --git a/fedocal/templates/agenda.html b/fedocal/templates/agenda.html
index a22d63b..42d5b50 100644
--- a/fedocal/templates/agenda.html
+++ b/fedocal/templates/agenda.html
@@ -33,7 +33,7 @@
<div id='agenda'>
<table>
<tr>
- <th></th>
+ <th>{{ tzone }} time</th>
{% for day in weekdays %}
<th> {{ day.strftime('%A %d') }}</th>
{% endfor %}