~coalwater/lernid/fix-916629

« back to all changes in this revision

Viewing changes to lernid/Sessions.py

  • Committer: John S Gruber
  • Date: 2011-07-06 04:06:51 UTC
  • mfrom: (225.1.15 lernid-proposed)
  • Revision ID: johnsgruber@gmail.com-20110706040651-ag2p8sjk5rd6v9oq
Tags: 0.8.1.4
Set for release
Add John S Gruber to AUTHOR file
Correct classroom and chatroom labels if lernid was invoked with the
   the --chatroom or --classroom option.
Fix traceback where appindicator is turned off by preference.
Correct handling of unusual case where a calendar start or stop time is
    missing.
Change maintainer to John S Gruber and add copyrights. Set new version.
In the schedule add italicized event names to the titles of sessions.
Use checkbox rather than a button to allow the user to prepend "Question:"
    to their contribution to the chatroom.

Let the user know about Question: in the session notification.
    Fixes: LP: #793029
When classroom and chatroom are joined change their widgets from inactive to
    active so it is more obvious. Fixes LP: #604658
Switch to the session tab at the beginning of the event. Suggest in session
    notification that the user keep the tab selected to see all visual
    materials. Use an eyecatcher, with color, to point out that additional
    slides or web material are in the session tab. Add a status
    message suggesting the user switch to the session tab. LP: #793788
Warn in the connection dialog that connecting can take a minute.
    LP: #604773
See that only an instructor or helper can change what the browser displays.
    LP: #530185. Add option to override this for testing.
    (--unsafe-override).

Emphasize messages from an instructor, helper, or classbot. LP: #794126

Add a --chatroom option so that the user can specify both the classroom and
    chatroom they want.

Remove nicknames saying <???> by rechecking with telepathy when a nickname
    is unknown. LP: #793048

Fix mispelling of "event" in in lernid/Sessions.py code.
Change format of slide progress message to ease translation.
    LP: #792364
Delay setting pane positions until the system has resized the 
    window. Sort of hackish. LP: #801547
Don't specify that "lernid" should be translated in LernidWindow.ui
    and other locations. Addresses LP: #682807
Add classroom and chatroom names to their widgets.
Address LP: #493316 adding extensions to make Lernid more robust when a
    connection doesn't exist, the config site, calendar, or irc server
    cannot be reached, or the connection is dropped. Also addresses
    LP: #528935, LP: #603248, LP: #795339 Supplies default configs or
    calendar as needed. Session entries without complete information are
    noted in the schedule.
Merge Chris Coulson's changes to remove the dependency on gtkmozembed.
    LP: #799211.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
### BEGIN LICENSE
4
4
# Copyright (C) 2009 Jono Bacon <jono@ubuntu.com>
5
5
# Copyright (C) 2010 Michael Budde <mbudde@gmail.com>
 
6
# Copyright (c) 2011 John S Gruber <johnsgruber@gmail.com>
6
7
#
7
8
#This program is free software: you can redistribute it and/or modify it
8
9
#under the terms of the GNU General Public License version 3, as published
19
20
 
20
21
import re
21
22
import vobject
22
 
import urllib
 
23
import urllib2
 
24
import logging
23
25
 
24
26
import lernid.DateTime as dt
 
27
import io
25
28
 
26
29
class Session(object):
27
30
 
29
32
 
30
33
    def __init__(self, **kwargs):
31
34
        for k, v in kwargs.iteritems():
32
 
            if k in ('title', 'description', 'instructors', 'local_start', 'local_end', 'slides', 'event'):
 
35
            if k in ('title', 'description', 'instructors', 'helpers', 'local_start', 'local_end', 'slides', 'event'):
33
36
                setattr(self, '_'+k, v)
34
37
 
35
38
    @property
42
45
 
43
46
    @property
44
47
    def instructors(self):
45
 
        return self._instructors
 
48
        return getattr(self, '_instructors', [])
 
49
 
 
50
    @property
 
51
    def helpers(self):
 
52
        return getattr(self, '_helpers', [])
46
53
 
47
54
    @property
48
55
    def start_local_date(self):
72
79
        return getattr(self, '_slides', None)
73
80
 
74
81
    @property
75
 
    def evenet(self):
76
 
        return self._event
 
82
    def event(self):
 
83
        return getattr(self, '_event', None)
77
84
 
78
85
    @property
79
86
    def state(self):
88
95
 
89
96
def parse_ical(event):
90
97
    """Parse iCal schedule for event and generate a list of Session objects"""
91
 
 
92
 
    ical = urllib.urlopen(event.icalurl)
93
 
    cal = vobject.readOne(ical)
 
98
    default_cal_error = (
 
99
u"""BEGIN:VCALENDAR
 
100
BEGIN:VEVENT
 
101
DTSTART:20100101T000000Z
 
102
DTEND:20100101T000000Z
 
103
DESCRIPTION:CalendarError
 
104
SUMMARY: """ +   _('Unable to load calendar %s\n') + 
 
105
u"""END:VEVENT
 
106
END:VCALENDAR""")   % event.icalurl
 
107
    default_cal_error2 = (
 
108
u"""BEGIN:VCALENDAR
 
109
BEGIN:VEVENT
 
110
DTSTART:20100101T000000Z
 
111
DTEND:20100101T000000Z
 
112
DESCRIPTION:CalendarError
 
113
SUMMARY: """ + _('Unable to parse calendar %s\n') + 
 
114
u"""END:VEVENT
 
115
END:VCALENDAR""") % event.icalurl
 
116
    try:
 
117
        ical = urllib2.urlopen(event.icalurl, None, 30)
 
118
    except IOError:
 
119
        logging.error('Unable to open calendar %s' % event.icalurl)
 
120
        ical = io.StringIO(default_cal_error)
 
121
    try:
 
122
        cal = vobject.readOne(ical)
 
123
    except:
 
124
        logging.critical('Error parsing calendar at %s' % event.icalurl)
 
125
        cal = vobject.readOne(io.StringIO(default_cal_error2))
94
126
 
95
127
    sessions = []
96
128
 
98
130
    eventend_local = dt.parse_time(event.eventend, '%Y-%m-%d %H:%M:%S')
99
131
 
100
132
    for session in cal.vevent_list:
101
 
        local_start = dt.as_local(session.dtstart.value)
102
 
        local_end = dt.as_local(session.dtend.value)
103
 
 
104
 
        if eventstart_local < local_start < eventend_local:
 
133
        session_data = {}
 
134
        if not hasattr(session, "dtstart") or not hasattr(session, "dtend"):
 
135
            logging.debug("Missing or invalid time for event")
 
136
            local_start = eventend_local
 
137
            local_end = eventend_local
 
138
        else:
 
139
            local_start = dt.as_local(session.dtstart.value)
 
140
            local_end = dt.as_local(session.dtend.value)
105
141
            if hasattr(session, "description"):
 
142
                if session.description.value == "CalendarError":
 
143
                    local_start = eventend_local
 
144
                    local_end = eventend_local
106
145
                session_data = parse_ical_description(session.description.value)
 
146
        if hasattr(session, "summary"):
 
147
            summary = session.summary.value
 
148
        else:
 
149
            summary = _('Missing Session Name')
 
150
        if eventstart_local <= local_start <= eventend_local:
107
151
            sessions.append(Session(
108
 
                title = session.summary.value,
 
152
                title = summary,
109
153
                local_start = local_start,
110
154
                local_end = local_end,
111
155
                **session_data))
127
171
        elif key == 'instructor' or key == 'instructors':
128
172
            instructors = [s.strip() for s in value.split(',')]
129
173
            session['instructors'] = instructors
 
174
        elif key == 'helper' or key == 'helpers':
 
175
            helpers = [s.strip() for s in value.split(',')]
 
176
            session['helpers'] = helpers
130
177
    return session