]> git.parisson.com Git - teleforma.git/commitdiff
V1 webclass
authorYoan Le Clanche <yoanl@pilotsystems.net>
Wed, 17 Jun 2020 12:35:05 +0000 (14:35 +0200)
committerYoan Le Clanche <yoanl@pilotsystems.net>
Wed, 17 Jun 2020 12:35:05 +0000 (14:35 +0200)
14 files changed:
teleforma/management/commands/teleforma-webclass-send-notifications.py
teleforma/static/teleforma/css/teleforma.css
teleforma/templates/teleforma/course_detail.html
teleforma/templates/teleforma/courses.html
teleforma/views/core.py
teleforma/webclass/forms.py
teleforma/webclass/migrations/0003_auto__add_field_webclassrecord_bbb_server.py [new file with mode: 0644]
teleforma/webclass/models.py
teleforma/webclass/templates/webclass/appointments.html
teleforma/webclass/templates/webclass/appointments_professor.html
teleforma/webclass/templates/webclass/inc/webclass_list.html
teleforma/webclass/templates/webclass/record.html [new file with mode: 0644]
teleforma/webclass/urls.py
teleforma/webclass/views.py

index 80546f7af417b78b965d13331e882292d886c214..2630e186bcbaae3d98db6f39afcf656c94b08c35 100644 (file)
@@ -21,7 +21,7 @@ class Command(BaseCommand):
         dow = now.weekday()
         begin = now + datetime.timedelta(minutes=WARN_DELAY_MIN)
         end = now + datetime.timedelta(minutes=WARN_DELAY_MAX)
-        slots = WebclassSlot.objects.filter(day = dow,
+        slots = WebclassSlot.published.filter(day = dow,
                                             start_hour__gte = begin.time(),
                                             start_hour__lt = end.time())
         site = Site.objects.all()[0]
index 47f049c845f68579f997129d000850d4e993a613..7f4787e1ae8ffa4ea3223dc677369109974b88ec 100644 (file)
@@ -198,6 +198,20 @@ margin-bottom: 0em;
     padding: 2px 5px 7px 5px;
 }
 
+.block {
+    background-color: #FFF;
+    -moz-border-radius: 8px 0px 8px 8px;
+    -webkit-border-radius: 8px 0px 8px 8px;
+    border-radius: 8px 0px 8px 8px;
+    padding: 0em 0em 0em 0.8em;
+    margin-top: 0.8em;
+    margin-bottom: 0.8em;
+    border: 1px solid #dfdfdf;
+}
+
+.important {
+    background-color: rgb(255, 240, 240);
+}
 
 .exporter {
     background-color: #fff;
index 9e8d65e624ff80b05b952a87beac52ff8180c8b4..575f3095496e0b6cb44588e65298e3dd185a7f94 100644 (file)
 
 {% block extra_javascript %}
 <script type="text/javascript">
-$(document).ready(function(){
+  $(document).ready(function () {
     InitChatWindow("{% url jqchat_ajax room.id %}", null);
-    });
+  });
 </script>
 {% endblock extra_javascript %}
 
 {% block courses %}
 {% for c in all_courses %}
-  {% with c.course as course %}
-   <li><a href="{% url teleforma-desk-period-course period.id course.id %}">{{ course.title }}</a></li>
-  {% endwith %}
- {% endfor %}
+{% with c.course as course %}
+<li><a href="{% url teleforma-desk-period-course period.id course.id %}">{{ course.title }}</a></li>
+{% endwith %}
+{% endfor %}
 {% endblock courses %}
 
 {% block course %}
 
 <div class="desk_center">
 
-<section id="webclass-registering">
   {% if webclass and not webclass_slot %}
-  Vous n'êtes pas inscrit à la webconférence de cette matière. <a href="{% url teleforma-webclass-appointments webclass.id %}">Cliquez-ici pour choisir un créneau horaire</a>.
+  <div class="block important">
+    <p>
+      <strong>Vous n'êtes pas inscrit à la webclass de cette matière. </strong><a
+        href="{% url teleforma-webclass-appointments webclass.id %}"
+        class="conference-big-button component_icon button icon_next">Cliquez-ici pour choisir un créneau horaire</a>
+    </p>
+  </div>
   {% endif %}
-</section>
 
 
-<br/><br/>
-    {% for c in courses %}
-     {% with c.course as course %}
-      {% for type in c.types %}
-      <div class="course">
-        <div class="course_title">{{ course.title }} - {{ type }}{% if course.description %} - {{ course.description }}{% endif %}
-        </div>
+  <br /><br />
+  {% for c in courses %}
+  {% with c.course as course %}
+  {% for type in c.types %}
+  <div class="course">
+    <div class="course_title">{{ course.title }} - {{ type }}{% if course.description %} -
+      {{ course.description }}{% endif %}
+    </div>
 
-          {% if type.name == 'Quiz' %}
-          <div class="course_content">
-              {% if course.quiz.all %}
-              <table class="listing" width="100%">
-                  <tbody>
-                  {% for quiz in course.quiz.all %}
-                  <td class="border-top"><a href="{% url quiz_start_page slug=quiz.url %}">{{quiz.title}}</a></td>
-                  <td class="border-top">{{quiz.description}}</td>
-                  {% endfor %}
-                  </tbody>
-              </table>
-              {% else %}
-              <p>Aucun quiz</p>
-              {% endif %}
-          </div>
+    {% if type.name == 'Quiz' %}
+    <div class="course_content">
+      {% if course.quiz.all %}
+      <table class="listing" width="100%">
+        <tbody>
+          {% for quiz in course.quiz.all %}
+          <td class="border-top"><a href="{% url quiz_start_page slug=quiz.url %}">{{quiz.title}}</a></td>
+          <td class="border-top">{{quiz.description}}</td>
+          {% endfor %}
+        </tbody>
+      </table>
+      {% else %}
+      <p>Aucun quiz</p>
+      {% endif %}
+    </div>
 
-        {% else %}
-          {% if show_media %}
-          {% block conference %}
-           {% include "teleforma/inc/conference_list.html" %}
-          {% endblock %}
+    {% else %}
+    {% if show_media %}
+    {% block conference %}
+    {% include "teleforma/inc/conference_list.html" %}
+    {% endblock %}
 
-          {% block media %}
-           {% include "teleforma/inc/media_list.html" %}
-          {% endblock %}
-          {% endif %}
+    {% block media %}
+    {% include "teleforma/inc/media_list.html" %}
+    {% endblock %}
+    {% endif %}
 
-          {% block document %}
-           {% with forloop.counter as type_counter %}
-            {% include "teleforma/inc/document_list.html" %}
-           {% endwith %}
-          {% endblock %}
-        {% endif %}
+    {% block document %}
+    {% with forloop.counter as type_counter %}
+    {% include "teleforma/inc/document_list.html" %}
+    {% endwith %}
+    {% endblock %}
+    {% endif %}
 
-        </div>
-      {% endfor %}
-      
-      <div class="course">
-        <div class="course_title">{{ course.title }} - Webclass{% if course.description %} - {{ course.description }}{% endif %}
-        </div>
-        {% block webclass %}
-        TEST
-          {% include "webclass/inc/webclass_list.html" %}
-        {% endblock %}
-      </div>
-     {% endwith %}
-    {% endfor %}
+  </div>
+  {% endfor %}
+
+  <div class="course">
+    <div class="course_title">{{ course.title }} - Webclass{% if course.description %} -
+      {{ course.description }}{% endif %}
+    </div>
+    {% block webclass %}
+    {% include "webclass/inc/webclass_list.html" %}
+    {% endblock %}
+  </div>
+  {% endwith %}
+  {% endfor %}
 </div>
 {% endblock course %}
 
 {% block chat %}
 {% if course.title_tweeter %}
 {% if room %}
- {% if 'site' in room.name %}
-  {% with "General tweeter" as title %}
-   {% include "teleforma/inc/chat_room.html" %}
-  {% endwith %}
- {% else %}
-  {% with "Tweeter"|add:" "|add:course.title_tweeter as title %}
-   {% include "teleforma/inc/chat_room.html" %}
-  {% endwith %}
- {% endif %}
+{% if 'site' in room.name %}
+{% with "General tweeter" as title %}
+{% include "teleforma/inc/chat_room.html" %}
+{% endwith %}
+{% else %}
+{% with "Tweeter"|add:" "|add:course.title_tweeter as title %}
+{% include "teleforma/inc/chat_room.html" %}
+{% endwith %}
+{% endif %}
 {% endif %}
 {% endif %}
 
 {% newsitems_portlet course_id=course.id period_id=period.id %}
-{% endblock chat %}
-
+{% endblock chat %}
\ No newline at end of file
index 5ee3435aa4fc9d29f345ecf551554faa7206928e..112cd3ae670645713f52c8bdc4a44a6bca0ca15c 100644 (file)
@@ -7,9 +7,9 @@
 
 {% block extra_javascript %}
 <script type="text/javascript">
-$(document).ready(function(){
+  $(document).ready(function () {
     InitChatWindow("{% url jqchat_ajax room.id %}", null);
-    });
+  });
 </script>
 {% endblock extra_javascript %}
 
@@ -18,42 +18,45 @@ $(document).ready(function(){
 
 <div id="module-set-left" style="width: 18%">
 
-{% block modules %}
-<div class="module">
-
-<h3><img src="/static/telemeta/images/module_playlist.png" alt="playlists" style="vertical-align:middle" />{{ period }}</h3>
-<div style="background: white;">
-<ul>
-{% block courses %}
-{% for c in all_courses %}
-  {% with c.course as course %}
-   <li><a href="{% url teleforma-desk-period-course period.id course.id %}">{{ course.title }}</a></li>
-  {% endwith %}
- {% endfor %}
-{% endblock courses %}
-</ul>
-</div>
-
-</div>
-
-{% block module-action %}
-{% get_telecaster as telecaster %}
-{%  if telecaster %}
-<div class="module_action">
-<a href="{% url teleforma-conference-record %}" class="component_icon button" id="action_red">{% trans "New conference" %}</a>
-</div>
-{% endif %}
-
-{% if user.is_staff %}
-<div class="module_action">
-<a href="{% url teleforma-desk-period-pending period.id %}" class="component_icon button" id="action_red">{% trans "Pending" %}</a>
-</div>
-{% endif %}
-
-{% endblock module-action %}
-
-{% block notes %}
-<!--<div class="module">
+  {% block modules %}
+  <div class="module">
+
+    <h3><img src="/static/telemeta/images/module_playlist.png" alt="playlists"
+        style="vertical-align:middle" />{{ period }}</h3>
+    <div style="background: white;">
+      <ul>
+        {% block courses %}
+        {% for c in all_courses %}
+        {% with c.course as course %}
+        <li><a href="{% url teleforma-desk-period-course period.id course.id %}">{{ course.title }}</a></li>
+        {% endwith %}
+        {% endfor %}
+        {% endblock courses %}
+      </ul>
+    </div>
+
+  </div>
+
+  {% block module-action %}
+  {% get_telecaster as telecaster %}
+  {%  if telecaster %}
+  <div class="module_action">
+    <a href="{% url teleforma-conference-record %}" class="component_icon button"
+      id="action_red">{% trans "New conference" %}</a>
+  </div>
+  {% endif %}
+
+  {% if user.is_staff %}
+  <div class="module_action">
+    <a href="{% url teleforma-desk-period-pending period.id %}" class="component_icon button"
+      id="action_red">{% trans "Pending" %}</a>
+  </div>
+  {% endif %}
+
+  {% endblock module-action %}
+
+  {% block notes %}
+  <!--<div class="module">
 <h3><img src="/static/telemeta/images/view-pim-notes.png" alt="playlists" style="vertical-align:middle" />{% trans "My notes" %}</h3>
 <div style="background: white;">
 <ul>
@@ -66,9 +69,9 @@ $(document).ready(function(){
 <div class="module_action">
 <a href="#" class="component_icon button" id="action_violet">{% trans "New note" %}</a>
 </div>-->
-{% endblock notes %}
+  {% endblock notes %}
 
-{% endblock modules %}
+  {% endblock modules %}
 </div>
 
 
@@ -76,102 +79,155 @@ $(document).ready(function(){
 
 <div class="desk_center home">
 
-    {% if hasAppointment %}
-        <div class="appointment">
-            <a href="{% url teleforma-appointments period.id %}"><button>Rendez-vous individuels aux simulations du grand-oral</button></a>
-        </div>
-        <br/>
-    {% endif %}
+  {% if hasAppointment %}
+  <div class="appointment">
+    <a href="{% url teleforma-appointments period.id %}"><button>Rendez-vous individuels aux simulations du
+        grand-oral</button></a>
+  </div>
+  <br />
+  {% endif %}
 
+  <div class="block">
     {% autoescape off %}
     {{ home_text }}
     {% endautoescape %}
-
-    {% if home_video.type == 'webm' %}
-    <h3>{% if home_video.title %}{{ home_video.title }}{% else %}{{ home_video.course.title }}{% endif %}</h3>
-        <div class="video" style="width:400px">
-         <a href="{% url teleforma-media-detail period.id home_video.id %}" title="{% trans "Play" %}">
-          {% if home_video.item.related.all %}
-             {% for related in home_video.item.related.all %}
-              {% if related.title == "preview" %}
-               {% thumbnail related.file "168x96" as im %}
-                <div style="background: no-repeat url('{{ im.url }}') 0 1px; background-size: 100%; background-color: #dfdfdf;">
-                 <img src="/static/teleforma/images/play_168.png" width="100%" alt="{% trans 'Click here' %}" />
-                </div>
-               {% endthumbnail %}
+  </div>
+
+  {% if home_video.type == 'webm' %}
+  <div class="block">
+
+    <div class="course_subtitle">
+      <h3>{% if home_video.title %}{{ home_video.title }}{% else %}{{ home_video.course.title }}{% endif %}</h3>
+    </div>
+
+    <div class="video" style="width:400px">
+      <a href="{% url teleforma-media-detail period.id home_video.id %}" title="{% trans "Play" %}">
+        {% if home_video.item.related.all %}
+        {% for related in home_video.item.related.all %}
+        {% if related.title == "preview" %}
+        {% thumbnail related.file "168x96" as im %}
+        <div style="background: no-repeat url('{{ im.url }}') 0 1px; background-size: 100%; background-color: #dfdfdf;">
+          <img src="/static/teleforma/images/play_168.png" width="100%" alt="{% trans 'Click here' %}" />
+        </div>
+        {% endthumbnail %}
+        {% endif %}
+        {% endfor %}
+        {% else %}
+        {% trans 'Click here' %}
+        {% endif %}
+      </a>
+    </div>
+  </div>
+  {% endif %}
+
+  {% if webclass_slots or webclass_to_subscribe %}
+  <div class="course_title">
+    Webclasse
+  </div>
+  <div class="block important">
+    <table class="listing" style="width:100%">
+      <tbody>
+
+        {% for slot in webclass_slots %}
+        <tr>
+          <td>
+            <p>
+              {% if slot.status == 'ingoing' %}
+              La webclasse <strong>"{{slot.webclass.course.title}}"</strong> est en cours.
+              {% elif slot.status == 'almost' %}
+              La webclasse <strong>"{{slot.webclass.course.title}}"</strong> va démarrer bientôt.
               {% endif %}
-             {% endfor %}
-            {% else %}
-              {% trans 'Click here' %}
-            {% endif %}
-          </a>
-         </div>
-    {% endif %}
+              <a href="{% url teleforma-webclass-join slot.id %}" target="_blank"
+                class="conference-big-button component_icon button icon_next">Cliquez ici pour rejoindre la
+                webclasse</a>
+            </p>
+          </td>
+        </tr>
+        {% endfor %}
+        {% for webclass in webclass_to_subscribe %}
+        <tr>
+          <td>
+            <p>
+              <strong>Vous n'êtes pas inscrit à la webclasse "{{webclass.course.title}}".</strong> <a
+                class="conference-big-button component_icon button icon_next"
+                href="{% url teleforma-webclass-appointments webclass.id %}">Cliquez-ici pour choisir un créneau
+                horaire</a>
+            </p>
+          </td>
+        </tr>
+        {% endfor %}
+      </tbody>
+    </table>
+  </div>
+  {% endif %}
+
+
+  {% for c in courses %}
+  {% with c.course as course %}
+  {% for type in c.types %}
+  <div class="course">
+    <div class="course_title">
+      <a href="{% url teleforma-desk-period-course period.id course.id %}">{{ course.title }} -
+        {{ type }}{% if course.description %} - {{ course.description }}{% endif %}</a>
+    </div>
+
+    {% if show_media %}
+
+    {% block conference %}
+    {% include "teleforma/inc/conference_list.html" %}
+    {% endblock %}
+
+    {% block media %}
+    {% with "Passed conferences" as title %}
+    {% include "teleforma/inc/media_list.html" with show_only=1 %}
+    {% endwith %}
+    {% endblock %}
 
-    {% for c in courses %}
-     {% with c.course as course %}
-      {% for type in c.types %}
-      <div class="course">
-        <div class="course_title">
-         <a href="{% url teleforma-desk-period-course period.id course.id %}">{{ course.title }} - {{ type }}{% if course.description %} - {{ course.description }}{% endif %}</a>
-        </div>
+    {% comment %}
+    {% block webclass %}
+    {% with "Web class" as title %}
+    {% include "teleforma/inc/media_list.html" with show_only=1 %}
+    {% endwith %}
+    {% endblock %}
+    {% endcomment %}
+
+    {% endif %}
 
-        {% if show_media %}
-        
-        {% block conference %}
-         {% include "teleforma/inc/conference_list.html" %}
-        {% endblock %}
-
-        {% block media %}
-            {% with "Passed conferences" as title %}
-                {% include "teleforma/inc/media_list.html" with show_only=1 %}
-            {% endwith %}
-        {% endblock %}
-
-        {% comment %}
-        {% block webclass %}
-            {% with "Web class" as title %}
-                {% include "teleforma/inc/media_list.html" with show_only=1 %}
-            {% endwith %}
-        {% endblock %}
-        {% endcomment %}
-
-       {% endif %}
-
-        {% block document %}
-         {% with forloop.counter as type_counter %}
-          {% include "teleforma/inc/document_list.html" %}
-         {% endwith %}
-        {% endblock %}
-      </div>
-     {% endfor %}
+    {% block document %}
+    {% with forloop.counter as type_counter %}
+    {% include "teleforma/inc/document_list.html" %}
     {% endwith %}
-   {% endfor %}
+    {% endblock %}
+  </div>
+  {% endfor %}
+  {% endwith %}
+  {% endfor %}
 </div>
 {% endblock course %}
 
 
 <div id="module-set" style="width: 22%">
 
-{% block status %}
-{% get_telecaster as telecaster %}
-{%  if telecaster %}
-<div class="module">
-  <h3><img src="/static/teleforma/images/status.png" alt="status" style="vertical-align:middle" /> {% trans "Status" %}</h3>
-  <div id="server_status_table_wrapper" class="status"></div>
-</div>
-<script type="text/javascript">server_status_callback();</script>
-{% endif %}
-{% endblock status %}
-
-{% block chat %}
-{% if room %}
-{% with "General tweeter" as title %}
-{% include "teleforma/inc/chat_room.html" %}
-{% endwith %}
-{% endif %}
-{% endblock chat %}
+  {% block status %}
+  {% get_telecaster as telecaster %}
+  {%  if telecaster %}
+  <div class="module">
+    <h3><img src="/static/teleforma/images/status.png" alt="status" style="vertical-align:middle" />
+      {% trans "Status" %}</h3>
+    <div id="server_status_table_wrapper" class="status"></div>
+  </div>
+  <script type="text/javascript">server_status_callback();</script>
+  {% endif %}
+  {% endblock status %}
+
+  {% block chat %}
+  {% if room %}
+  {% with "General tweeter" as title %}
+  {% include "teleforma/inc/chat_room.html" %}
+  {% endwith %}
+  {% endif %}
+  {% endblock chat %}
 
 </div>
 
-{% endblock content %}
+{% endblock content %}
\ No newline at end of file
index 887683f7c1af7821fd0d8683b4e6e0f872b795e0..f56174c7f559fd57951833d778f125316b53b350 100644 (file)
@@ -342,7 +342,8 @@ class CourseListView(CourseAccessMixin, ListView):
         context['room'] = get_room(name='site', period=context['period'].name)
         context['list_view'] = True
         context['courses'] = sorted(context['all_courses'], key=lambda k: k['date'], reverse=True)[:1]
-        is_student = self.request.user.student.all().count()
+        user = self.request.user
+        is_student = user.student.all().count()
         appointments = AppointmentPeriod.objects.filter(periods=context['period'])
         appointments_open = False
         for appointment in appointments:
@@ -356,6 +357,23 @@ class CourseListView(CourseAccessMixin, ListView):
                 context['home_text'] = home.text
                 context['home_video'] = home.video
                 break
+               
+        if is_student:
+            student = user.student.all()[0]
+            slots = []
+            to_subscribe = []
+            student_courses = [course['course'] for course in get_courses(user)]
+            for webclass in Webclass.published.filter(period=self.period, iej=student.iej, course__in=student_courses):
+                # if webclass.course not in student_courses:
+                #     continue
+                slot = webclass.get_slot(user)
+                if slot and slot.status in ('almost', 'ingoing'):
+                    slots.append(slot)
+                if not slot:
+                    to_subscribe.append(webclass)
+            context['webclass_slots'] = slots
+            context['webclass_to_subscribe'] = to_subscribe
+        
         return context
 
     @method_decorator(login_required)
@@ -422,15 +440,19 @@ class CourseView(CourseAccessMixin, DetailView):
         
         if student:
             try:
-                webclass = Webclass.objects.get(period=self.period, course=course, iej=student.iej)
-            except Webclass.DoesNotExist:
+                webclass = Webclass.published.filter(period=self.period, course=course, iej=student.iej)[0]
+            except IndexError:
                 pass
             if webclass:
                 webclass_slot = webclass.get_slot(self.request.user)
         context['webclass'] = webclass
         context['webclass_slot'] = webclass_slot
 
-        print(WebclassRecord.get_records(context['period'], course))
+        try:
+            context['webclass_records'] = WebclassRecord.get_records(context['period'], course)
+        except Exception, e:
+            print(e)
+            context['webclass_error'] = True
         return context
 
     @method_decorator(login_required)
index 2878a09083abbd3c10d5c31216692679c3447b5d..627c3529838c3f9ae5166cc583048c6a97bac168 100644 (file)
@@ -3,7 +3,7 @@
 from datetime import datetime
 from django.forms import Form, ModelChoiceField, ChoiceField
 from teleforma.models.core import Course, Period
-from teleforma.webclass.models import get_records, WebclassSlot, WebclassRecord
+from teleforma.webclass.models import get_records, WebclassSlot, WebclassRecord, BBBServer
 from django.core.exceptions import ValidationError
 
 class WebclassRecordsForm(Form):
@@ -22,10 +22,10 @@ class WebclassRecordsForm(Form):
         courses = Course.objects.all()
         all_records = self.get_records_by_course()
         for course in courses:
-            webclass = course.webclass.count()
-            if course.webclass.count():
+            webclasses = course.webclass.filter(period=self.period).all()
+            if webclasses:
                 rooms = []
-                for webclass in course.webclass.all():
+                for webclass in webclasses:
                     for slot in webclass.slots.all():
                         rooms.append(slot.room_id)
 
@@ -34,10 +34,9 @@ class WebclassRecordsForm(Form):
 
                 vocabulary = [('none', 'Aucun')]
                 for record in records:
-                    print(record)
-                    webclass_slot = WebclassSlot.objects.get(pk=record['slot_id'])
+                    webclass_slot = WebclassSlot.objects.get(pk=record['slot'].id)
                     label = u"%s à %s - %s" % (record['start_date'].strftime('%d/%m/%Y %H:%M'), record['end_date'].strftime('%H:%M'), webclass_slot.professor.user.last_name)
-                    vocabulary.append((record['id'], label))
+                    vocabulary.append((str(record['id']) + ";" + str(record['server_id']), label))
                 self.fields[field_name] = ChoiceField(label=course.title,  choices=vocabulary, required=False)
     
     def get_records_by_course(self):
@@ -50,7 +49,9 @@ class WebclassRecordsForm(Form):
     def save_records(self):
         for key, value in self.data.items():
             if key.startswith('course') and value != 'none':
+                record_id, server_id = value.split(';')
                 course_id = key.replace('course_', '')
                 course = Course.objects.get(pk=course_id)
-                record = WebclassRecord(course=course, period=self.period, record_id=value)
+                server = BBBServer.objects.get(pk=server_id)
+                record = WebclassRecord(course=course, period=self.period, record_id=record_id, bbb_server=server)
                 record.save()
diff --git a/teleforma/webclass/migrations/0003_auto__add_field_webclassrecord_bbb_server.py b/teleforma/webclass/migrations/0003_auto__add_field_webclassrecord_bbb_server.py
new file mode 100644 (file)
index 0000000..07d4042
--- /dev/null
@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'WebclassRecord.bbb_server'
+        db.add_column('teleforma_webclass_record', 'bbb_server',
+                      self.gf('django.db.models.fields.related.ForeignKey')(default=1, related_name='webclass_records', to=orm['webclass.BBBServer']),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'WebclassRecord.bbb_server'
+        db.delete_column('teleforma_webclass_record', 'bbb_server_id')
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'quiz.category': {
+            'Meta': {'object_name': 'Category'},
+            'category': ('django.db.models.fields.CharField', [], {'max_length': '250', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+        },
+        'quiz.quiz': {
+            'Meta': {'object_name': 'Quiz'},
+            'answers_at_end': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['quiz.Category']", 'null': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'draft': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'exam_paper': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'fail_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'max_questions': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'pass_mark': ('django.db.models.fields.SmallIntegerField', [], {'default': '0', 'blank': 'True'}),
+            'random_order': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'single_attempt': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'success_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '60'}),
+            'url': ('django.db.models.fields.SlugField', [], {'max_length': '60'})
+        },
+        'teleforma.course': {
+            'Meta': {'ordering': "['number']", 'object_name': 'Course'},
+            'code': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}),
+            'department': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'course'", 'to': "orm['teleforma.Department']"}),
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'has_exam_scripts': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_professor_sent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['teleforma.Professor']", 'null': 'True', 'blank': 'True'}),
+            'magistral': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'obligation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'oral_1': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'oral_2': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'oral_speciality': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'periods': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'courses'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['teleforma.Period']"}),
+            'procedure': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'quiz': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['quiz.Quiz']", 'null': 'True', 'blank': 'True'}),
+            'synthesis_note': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'title_tweeter': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'written_speciality': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+        },
+        'teleforma.department': {
+            'Meta': {'object_name': 'Department'},
+            'default_period': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'departments'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['teleforma.Period']"}),
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'domain': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'organization': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'department'", 'to': "orm['teleforma.Organization']"})
+        },
+        'teleforma.iej': {
+            'Meta': {'ordering': "['name']", 'object_name': 'IEJ'},
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'teleforma.organization': {
+            'Meta': {'object_name': 'Organization'},
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'teleforma.period': {
+            'Meta': {'ordering': "['name']", 'object_name': 'Period'},
+            'date_begin': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'date_close_accounts': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'date_end': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'date_exam_end': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'date_inscription_end': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'date_inscription_start': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'date_password_init': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'department': ('telemeta.models.core.ForeignKey', [], {'default': 'None', 'related_name': "'period'", 'null': 'True', 'blank': 'True', 'to': "orm['teleforma.Department']"}),
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_open': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'message_local': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'message_platform': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'nb_script': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['teleforma.Period']"})
+        },
+        'teleforma.professor': {
+            'Meta': {'ordering': "['user__last_name']", 'object_name': 'Professor'},
+            'courses': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'professor'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['teleforma.Course']"}),
+            'department': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'professor'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['teleforma.Department']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'professor'", 'unique': 'True', 'to': "orm['auth.User']"})
+        },
+        'webclass.bbbserver': {
+            'Meta': {'object_name': 'BBBServer', 'db_table': "'teleforma_bbb_server'"},
+            'api_key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'url': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'webclass.webclass': {
+            'Meta': {'object_name': 'Webclass', 'db_table': "'teleforma_webclass'"},
+            'bbb_server': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'webclass'", 'to': "orm['webclass.BBBServer']"}),
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'webclass'", 'to': "orm['teleforma.Course']"}),
+            'department': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'webclass'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['teleforma.Department']"}),
+            'duration': ('telemeta.models.core.DurationField', [], {'default': "'0'", 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'iej': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'webclass'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['teleforma.IEJ']"}),
+            'max_participants': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'period': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'webclass'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['teleforma.Period']"}),
+            'status': ('django.db.models.fields.IntegerField', [], {'default': '2'})
+        },
+        'webclass.webclassrecord': {
+            'Meta': {'object_name': 'WebclassRecord', 'db_table': "'teleforma_webclass_record'"},
+            'bbb_server': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'webclass_records'", 'to': "orm['webclass.BBBServer']"}),
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'webclass_records'", 'to': "orm['teleforma.Course']"}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'period': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['teleforma.Period']"}),
+            'record_id': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'webclass.webclassslot': {
+            'Meta': {'object_name': 'WebclassSlot', 'db_table': "'teleforma_webclass_slot'"},
+            'day': ('django.db.models.fields.IntegerField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'participants': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'webclass_slot'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}),
+            'professor': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'webclass_slot'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['teleforma.Professor']"}),
+            'room_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'room_password': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'start_hour': ('django.db.models.fields.TimeField', [], {}),
+            'webclass': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'slots'", 'to': "orm['webclass.Webclass']"})
+        }
+    }
+
+    complete_apps = ['webclass']
\ No newline at end of file
index 8616b7c6815b2708c264c111540d9b64477a7d34..cacbbf00aec9f2a1ce26a43b99325eda6e03fbb0 100644 (file)
@@ -8,7 +8,6 @@ from unidecode import unidecode
 from django.db.models import *
 from telemeta.models import *
 from teleforma.fields import *
-from teleforma.models.core import STATUS_CHOICES
 import django.db.models as models
 from django.utils.translation import ugettext_lazy as _
 from django.utils import translation
@@ -25,6 +24,10 @@ app_label = 'teleforma'
 DAYS_CHOICES = [(i, _(calendar.day_name[i])) for i in range(7)]
 # BBB_SERVER = "https://bbb.parisson.com/bigbluebutton/"
 # BBB_SECRET = "uOzkrTnWly1jusr0PYcrlwhvKhZG1ZYDOrSvxgP70"
+STATUS_CHOICES = (
+        (2, _('Draft')),
+        (3, _('Public')),
+    )
 
 
 class MetaCore:
@@ -35,9 +38,10 @@ def get_records_from_bbb(**kwargs):
     """get records info from bbb xml"""
     records = []
     for server in BBBServer.objects.all():
-        recordings_xml = server.get_instance().get_recordings(**kwargs).get_field('recordings')
-        if hasattr(recordings_xml, 'get'):
-            recordings = recordings_xml['recording']
+        recordings = server.get_instance().get_recordings(**kwargs).get_field('recordings')
+        # import pdb;pdb.set_trace()
+        if hasattr(recordings, 'get'):
+            recordings = recordings['recording']
         if type(recordings) is XMLDictNode:
             recordings = [recordings]
         for recording in recordings:
@@ -45,21 +49,25 @@ def get_records_from_bbb(**kwargs):
             url = recording.get('playback', {}).get('format', {}).get('url')
             if url:
                 url = url.decode()
+            else:
+                continue
             if not recording['metadata'].get('periodid'):
                 continue
             start = int(recording['startTime'].decode()[:-3])
             end = int(recording['endTime'].decode()[:-3])
             data = {
                 'id': recording['recordID'].decode(),
+                'server_id': server.id,
                 'start': start,
                 'start_date': datetime.datetime.fromtimestamp(start),
                 'end': end,
                 'end_date': datetime.datetime.fromtimestamp(end),
                 'url': url,
+                'preview': recording.get('playback', {}).get('format', {}).get('preview', {}).get('images', {}).get('image', [])[0].decode(),
                 'state': recording['state'].decode(),
                 'period_id': int(recording['metadata'].get('periodid').decode()),
                 'course_id': int(recording['metadata'].get('courseid').decode()),
-                'slot_id': int(recording['metadata'].get('slotid').decode()),
+                'slot': WebclassSlot.objects.get(pk=int(recording['metadata'].get('slotid').decode()))
             }
             data['duration'] = data['end'] - data['start']
             records.append(data)
@@ -104,6 +112,9 @@ class BBBServer(models.Model):
     def __unicode__(self):
         return "Serveur %d" % self.id
 
+class PublishedManager(models.Manager):
+    def get_query_set(self):
+        return super(PublishedManager, self).get_query_set().filter(status=3)
 
 class Webclass(models.Model):
     
@@ -112,10 +123,12 @@ class Webclass(models.Model):
     course                  = models.ForeignKey('teleforma.Course', related_name='webclass', verbose_name=_('course'))
     iej                     = models.ManyToManyField('teleforma.IEJ', related_name='webclass', verbose_name=_('iej'), blank=True, null=True)
     bbb_server              = models.ForeignKey('BBBServer', related_name='webclass', verbose_name='Serveur BBB')
-    duration                = DurationField('Durée de la conférence')
-    max_participants        = models.IntegerField('Nombre maxium de participants par créneau', blank=True, null=True)
+    duration                = DurationField('Durée de la conférence', default="00:30:00")
+    max_participants        = models.IntegerField('Nombre maxium de participants par créneau', blank=True, null=True, default=80)
     status                  = models.IntegerField(_('status'), choices=STATUS_CHOICES, default=2)
 
+    published = PublishedManager()
+    objects = models.Manager()
 
     class Meta(MetaCore):
         db_table = app_label + '_' + 'webclass'
@@ -128,11 +141,13 @@ class Webclass(models.Model):
     def get_slot(self, user):
         """ return webclass slot or None if user is not subscribed """
         try:
-            return WebclassSlot.objects.get(webclass=self, participants=user)
+            return WebclassSlot.published.get(webclass=self, participants=user)
         except WebclassSlot.DoesNotExist:
             return None
 
-
+class SlotPublishedManager(models.Manager):
+    def get_query_set(self):
+        return super(SlotPublishedManager, self).get_query_set().filter(webclass__status=3)
 
 class WebclassSlot(models.Model):
     """ Webclass slot """
@@ -146,6 +161,9 @@ class WebclassSlot(models.Model):
     room_id         = models.CharField('id de la conférence BBB (généré automatiquement)', blank=True, null=True, max_length=255)
     room_password   = models.CharField('password du modérateur (généré automatiquement)', blank=True, null=True, max_length=255)
 
+    published = SlotPublishedManager()
+    objects = models.Manager()
+
     class Meta(MetaCore):
         db_table = app_label + '_' + 'webclass_slot'
         verbose_name = _('webclass slot')
@@ -153,13 +171,21 @@ class WebclassSlot(models.Model):
     def __unicode__(self):
         return "Webclass slot : " + str(self.id)
 
+
+    @property
+    def remaining_participant_slot(self):
+        """
+        get remaining participant slot 
+        """
+        nb_participants = self.participants.count()
+        return self.webclass.max_participants - nb_participants
+
     @property
     def participant_slot_available(self):
         """
         is there any slot available for another participants
         """
-        nb_participants = self.participants.count()
-        return nb_participants < self.webclass.max_participants
+        return self.remaining_participant_slot > 0
 
     @property
     def end_hour(self):
@@ -204,7 +230,7 @@ class WebclassSlot(models.Model):
                     # 'autoStartRecording':True,
                     'muteOnStart':True,
                     'allowModsToUnmuteUsers':True,
-                    'logo':'https://e-learning.crfpa.pre-barreau.com/static/teleforma/images/logo_pb.png',
+                    'logo':'https://e-learning.crfpa.pre-barreau.com/static/teleforma/images/logo_pb.png',
                     'copyright': "© %d Pré-Barreau" % year,
                     # 'guestPolicy':'ALWAYS_ACCEPT'
                     'bannerText': "Pré-Barreau",
@@ -217,7 +243,7 @@ class WebclassSlot(models.Model):
                         'courseid': webclass.course.id,
                         'webclassid': webclass.id,
                         'slotid': self.id,
-                        'professor': self.professor.last_name,
+                        'professor': self.professor.user.username,
                     }
                 print params
                 try:
@@ -344,7 +370,9 @@ class WebclassRecord(models.Model):
     
     period                  = models.ForeignKey('teleforma.Period', verbose_name=_('period'))
     course                  = models.ForeignKey('teleforma.Course', related_name='webclass_records', verbose_name=_('course'))
-    record_id                     = models.CharField("Enregistrement BBB", max_length=255)
+    record_id               = models.CharField("Enregistrement BBB", max_length=255)
+    # not used for now, but may be handy if we need to optimize performance
+    bbb_server              = models.ForeignKey('BBBServer', related_name='webclass_records', verbose_name='Serveur BBB')
     created                 = models.DateTimeField("Date de la conférence", auto_now_add=True)
 
     class Meta(MetaCore):
@@ -355,15 +383,13 @@ class WebclassRecord(models.Model):
     def __unicode__(self):
         return "Enregistrement webclass %d" % self.id
 
-
     @staticmethod
     def get_records(period, course):
-        records = []
+        record_ids = set()
         for record in WebclassRecord.objects.filter(period=period, course=course):
-            records.append(record.record_id)
-
-        records = get_records_from_bbb(recording_id=','.join(records))
+            record_ids.add(record.record_id)
+        if not record_ids:
+            return []
+        records = get_records_from_bbb(recording_id=','.join(record_ids))
         print(records)
         return records
-
-
index c30374fd6313874107b50e93e47caaa83a175841..ee24c41379b13b626fc99a2dcd3010887f7c4d2a 100644 (file)
         <strong id="date_placeholder"></strong>
     </div>
 
-    
-    {% for slot in slots %}
-        <form class="booking_form" method="POST">
-            <span class="booking_date">{{slot.day}} de {{slot.start_hour|date:"H\hi"}} à {{slot.end_hour|date:"H\hi"}}</span>
-            {% csrf_token %}
-            <input type="hidden" name="slot_id" value="{{slot.id}}" />
-            <input type="submit" value="Sélectionner" />
-        </form>
-    {% endfor %}
+
+    <h1>Inscription à la Webclasse "{{webclass.course.title}}"</h1>
+    <br/><br/>
+
+    <table class="webclass-appointment listing" width="100%">
+        <thead>
+            <tr>
+                <th>Horaire</th>
+                <th>Professeur</th>
+                <th>Places restantes</th>
+                <th>Inscription</th>
+            </tr>
+        </thead>
+        <tbody>
+        {% for slot in slots %}
+            <tr>
+                <td>
+                <span class="booking_date"><strong>{{slot.get_day_display}}</strong> de <strong>{{slot.start_hour|date:"H\hi"}}</strong> à <strong>{{slot.end_hour|date:"H\hi"}}</strong></span>
+                </td>
+                <td>
+                {{slot.professor}}
+                </td>
+                <td>
+                {{slot.remaining_participant_slot}}
+                </td>
+
+                <td>
+                    <form class="booking_form" method="POST">
+                        <span class="booking_date" style="display:none"><strong>{{slot.day}}</strong> de <strong>{{slot.start_hour|date:"H\hi"}}</strong> à <strong>{{slot.end_hour|date:"H\hi"}}</strong></span>
+                        {% csrf_token %}
+                        <input type="hidden" name="slot_id" value="{{slot.id}}" />
+                        {% if slot.participant_slot_available %}
+                            <input type="submit" value="Sélectionner" />
+                        {% else %}
+                            <span style="color:red">Complet</span>
+                        {% endif %}
+                    </form>
+                </td>
+            </tr>
+        {% endfor %}
+        </tbody>
+    </table>
         
 
 {% endblock content %}
index 7dbe5615d305a7124f50b667876f5a1b17b542c4..9998f8ddfc5752efa530738f552a236025f95c23 100644 (file)
@@ -14,14 +14,46 @@ Calendrier des Webclass
 {% endblock infra_javascript %}
 
 {% block content %}
-<div>
+<table class="webclass-appointment listing" width="100%">
+    <thead>
+    <tr>
+        <th>Horaire</th>
+        <th>Période</th>
+        <th>Cours</th>
+        {% comment %} <th>IEJ</th> {% endcomment %}
+        <th>Participants</th>
+        <th>Salon</th>
+    </tr>
+    </thead>
+    <tbody>
     {% for slot in slots %}
-    <div class="webclass-appointment" style="margin-bottom:10px">
-        <span><strong>{{slot.get_day_display}}</strong> de <strong>{{slot.start_hour|date:"H\hi"}}</strong> à <strong>{{slot.end_hour|date:"H\hi"}}</strong></span> : {{slot.participants.count}} participant{{slot.participants.count|pluralize}}
-        <a href="{% url teleforma-webclass-join slot.id %}" target="_blank" class="conference-big-button component_icon button icon_next">Rejoindre la conférence</a>
-    </div>
+    <tr>
+        <td>
+            <span><strong>{{slot.get_day_display}}</strong> de <strong>{{slot.start_hour|date:"H\hi"}}</strong> à <strong>{{slot.end_hour|date:"H\hi"}}</strong></span>
+        </td>
+        <td>
+        {{slot.webclass.period.name}}
+        </td>
+        <td>
+        {{slot.webclass.course.title}}
+        </td>
+        {% comment %} <td>
+        {% for iej in slot.webclass.iej.all %}
+        {{iej.name}}
+        {% endfor %}
+        </td> {% endcomment %}
+        <td>
+         {{slot.participants.count}}
+        </td>
+        <td>
+            <a href="{% url teleforma-webclass-join slot.id %}" target="_blank" class="conference-big-button component_icon button icon_next">Rejoindre la conférence</a>
+        </td>
+    </tr>
     {% empty %}
-    <p>Aucune webclasse programmée.</p>
+    <tr>
+    <td colspan="5">Aucune webclasse programmée.</td>
+    </tr>
     {% endfor %}
-</div>
+    </tbody>
+</table>
 {% endblock content %}
index e5aba91cec63a1e019f53c4d61a2d145b4a2e2d8..3c600e3cdce8077046d48b3103766dc1ac6bba22 100644 (file)
@@ -1,73 +1,73 @@
 {% load teleforma_tags %}
 {% load i18n %}
 
-{% if webclass_slot %}
+{% if webclass_slot or webclass_records %}
 <div class="course_content content_video">
-<div class="course_subtitle">
-    <h3><img src="/static/telemeta/images/item_title.png" width="10px" alt="" /> Webclass live</h3>
-</div>
+    <div class="course_subtitle">
+        <h3><img src="/static/telemeta/images/item_title.png" width="10px" alt="" /> Webclasse live</h3>
+    </div>
     <table class="listing" width="100%">
-    <tbody>
-        {% if webclass_slot %}
-        <tr>
-            <td>
-            <p>Vous êtes inscrit pour les webconférence du 
-            <strong>{{webclass_slot.get_day_display}} de 
-            {{webclass_slot.start_hour|date:"H\hi"}} à 
-            {{webclass_slot.end_hour|date:"H\hi"}}</strong> 
-            avec le professeur <strong>{{webclass_slot.professor.user.last_name}}</strong>.</p>
-            {{webclass_slot.status}}
-            {% if webclass_slot.status == 'past' %}
-                <p>La webconférence est terminée.</p>
-            {% elif webclass_slot.status == 'ingoing' %}
-                <p>La webconférence est en cours.</p>
-                <a href="{% url teleforma-webclass-join webclass_slot.id %}" target="_blank" class="conference-big-button component_icon button icon_next">Cliquez ici pour rejoindre la conférence</a>
-            {% elif webclass_slot.status == 'almost' %}
-                <p>Le webconférence est accessible mais elle n'a pas encore démarré.</p>
-                <a href="{% url teleforma-webclass-join webclass_slot.id %}" target="_blank" class="conference-big-button component_icon button icon_next">Cliquez ici pour rejoindre la conférence</a>
-            {% endif %}
-            </td>
-        </tr>
-        {% endif %}
-
-       {% for conference in conferences|from_period:period %}
-        {% for stream in conference.livestream.all %}
-         {% if stream.stream_type == 'webm' %}
+        <tbody>
+            {% if webclass_slot %}
             <tr>
-            {% if stream.streaming %}
-            <td {% if forloop.first %}class="border-top"{% endif %} width="230px">
-               <a href="{% url teleforma-conference-detail period.id stream.conference.id %}" title="{% trans "View" %}">
-               <img id="snapshot-{{ stream.course.code }}-{{ stream.course_type }}" src="{{ stream.snapshot_url }}" width="100%" alt="{% trans 'Click here' %}" />
-               </a>
-            </td>
-            <td {% if forloop.first %}class="border-top"{% endif %} width="60%" style="padding-left: 1em;">
-                <div>
-                    <dl class="listing" style="font-size: 1.2em;">
-                    <dt>{% trans "Title" %}</dt><dd>{{ stream.conference.course.title }}</dd>
-                    <dt>{% trans "Session" %}</dt><dd>{{ stream.conference.session }}</dd>
-                    {% if stream.conference.professor.user.username %}
-                    <dt>{% trans "Professor" %}</dt><dd><a href="{% url telemeta-profile-detail stream.conference.professor.user.username %}" target="_blank">{{ stream.conference.professor }}</a></dd>
+                <td colspan="2">
+                    <p>Vous êtes inscrit pour les webclasses du
+                        <strong>{{webclass_slot.get_day_display}} de
+                            {{webclass_slot.start_hour|date:"H\hi"}} à
+                            {{webclass_slot.end_hour|date:"H\hi"}}</strong>
+                        avec le professeur <strong>{{webclass_slot.professor.user.last_name}}</strong>.</p>
+
+                    {% if webclass_slot.status == 'past' %}
+                    <p>
+                        La webclasse est terminée.
+                    </p>
+                    {% elif webclass_slot.status == 'ingoing' %}
+                    <p>
+                        La webclasse est en cours.
+                        <a href="{% url teleforma-webclass-join webclass_slot.id %}" target="_blank"
+                            class="conference-big-button component_icon button icon_next">Cliquez ici pour rejoindre la
+                            conférence</a>
+                    </p>
+                    {% elif webclass_slot.status == 'almost' %}
+                    <p>
+                        La webclasse est accessible mais elle n'a pas encore démarré.
+                        <a href="{% url teleforma-webclass-join webclass_slot.id %}" target="_blank"
+                            class="conference-big-button component_icon button icon_next">Cliquez ici pour rejoindre la
+                            conférence</a>
+                    </p>
+                    {% endif %}
+                    {% if webclass_error %}<p>Impossible d'afficher la liste des webclasse : le serveur a rencontré une
+                        erreur, veuillez réessayer plus tard.</p>
                     {% endif %}
-                    <dt>{% trans "Begin" %}</dt><dd>{{ stream.conference.date_begin }}</dd>
-                    </dl>
-                 </div>
-            </td>
-            <td {% if forloop.first %}class="border-top"{% endif %} width="10%" align="center">
-                {% if stream.streaming %}
-                <img src="/static/teleforma/images/network-wireless.png" style="vertical-align:middle" title="streaming" />
-                <img src="/static/telemeta/images/media-record.png" style="vertical-align:middle" title="recording" />
-              {% endif %}
-            </td>
-            {% else %}
-            <div style="padding-left: 1em;">
 
-            </div>
-             {% endif %}
+                </td>
             </tr>
             {% endif %}
-        {% endfor %}
-        {% endfor %}
-    </tbody>
+            {% for record in webclass_records %}
+            <tr>
+                <td {% if forloop.first %}class="border-top" {% endif %} style="width:200px">
+                    <a href="{% url teleforma-webclass-record %}?url={{record.url}}" title="{% trans "View" %}">
+                        <img src="{{ record.preview }}" style="width:176px" alt="{% trans 'Click here' %}" />
+                        <div>Cliquez-ici</div>
+                    </a>
+                </td>
+                <td {% if forloop.first %}class="border-top" {% endif %} style="padding-left: 1em;">
+                    <div>
+                        <dl class="listing" style="font-size: 1.2em;">
+                            <dt>{% trans "Professor" %}</dt>
+                            <dd><a href="{% url telemeta-profile-detail record.slot.professor.user.username %}"
+                                    target="_blank">{{ record.slot.professor }}</a></dd>
+                            <dt>{% trans "Begin" %}</dt>
+                            <dd>{{ record.start_date }}</dd>
+                        </dl>
+                    </div>
+                </td>
+                <div style="padding-left: 1em;">
+
+                </div>
+            </tr>
+            {% endfor %}
+        </tbody>
     </table>
 </div>
-{% endif %}
+{% endif %}
\ No newline at end of file
diff --git a/teleforma/webclass/templates/webclass/record.html b/teleforma/webclass/templates/webclass/record.html
new file mode 100644 (file)
index 0000000..73a55e2
--- /dev/null
@@ -0,0 +1,28 @@
+{% extends "telemeta/base.html" %}
+{% load telemeta_utils %}
+{% load teleforma_tags %}
+{% load i18n %}
+
+
+{% block extra_stylesheets %}
+
+<style>
+iframe {
+    position: fixed;
+    background: #000;
+    border: none;
+    top: 40px; right: 0;
+    bottom: 100px; left: 0;
+    width: 100%;
+    height: 90%;
+}
+</style>
+
+{% endblock extra_stylesheets %}
+
+
+
+{% block content %}
+<iframe src="{{record_url}}" width="100%"></iframe>
+{% endblock content %}
+
index 4a8a702f5e7b3b17f9356c839ef0d363b54d385f..87d77617ae86bd702668f49eaadedbee8215fc32 100644 (file)
@@ -41,6 +41,7 @@ urlpatterns = patterns('',
     url(r'^desk/webclass_appointments/(?P<pk>.*)$', WebclassAppointment.as_view(),
        name="teleforma-webclass-appointments"),
     url(r'^desk/webclass_calendar/$', WebclassProfessorAppointments.as_view(), name="teleforma-webclass-professor"),
+    url(r'^desk/webclass_record$', WebclassRecordView.as_view(), name="teleforma-webclass-record"),
     url(r'^admin/periods/(?P<period_id>.*)/webclass_records_form/$', WebclassRecordsFormView.as_view(), name="teleforma-webclass-records-form"),
     url(r'^desk/webclass/(?P<pk>.*)/join/$',
         join_webclass,
index 99395fe42f7bc6d426d274acc69539e81c602876..eca42ed5614f75473666fbb86e3d88c9dec2066c 100644 (file)
@@ -1,7 +1,9 @@
 # -*- coding: utf-8 -*-
 
 from django.views.generic import View, TemplateView, FormView
+from django.utils.decorators import method_decorator
 from django.contrib import messages
+from django.contrib.auth.decorators import login_required, permission_required
 from django.http import HttpResponse
 from django.shortcuts import redirect, get_object_or_404, render
 from django.template.loader import render_to_string
@@ -28,7 +30,7 @@ class WebclassProfessorAppointments(TemplateView):
         user = self.request.user
         if not user.professor:
             return HttpResponse('Unauthorized', status=401)
-        context['slots'] = WebclassSlot.objects.filter(professor=user.professor.get(), webclass__status=3).order_by('day', 'start_hour')
+        context['slots'] = WebclassSlot.published.filter(professor=user.professor.get(), webclass__status=3).order_by('day', 'start_hour')
         print(context['slots'])
         return context
 
@@ -62,18 +64,7 @@ class WebclassAppointment(View):
         user = request.user
         student = user.student.all()[0]
         
-        # Get info
-        slots = []
-        for slot in webclass.slots.order_by('day', 'start_hour'):
-            slots.append({
-                'id': slot.id,
-                'day': slot.get_day_display(),
-                'start_hour':slot.start_hour,
-                'end_hour': slot.end_hour,
-                'professor': slot.professor,
-                'available': slot.participant_slot_available
-            })
-        return render(request, self.template_name, {'slots': slots})
+        return render(request, self.template_name, {'slots': webclass.slots.order_by('day', 'start_hour'), 'webclass': webclass})
 
     def check_slot_validity(self, user, slot):
         """
@@ -98,7 +89,7 @@ class WebclassAppointment(View):
 
         user = request.user
         slot_id = int(request.POST.get('slot_id'))
-        slot = WebclassSlot.objects.get(pk=slot_id)
+        slot = WebclassSlot.published.get(pk=slot_id)
 
         msg = self.check_slot_validity(user, slot)
 
@@ -143,6 +134,15 @@ class WebclassAppointment(View):
     #               fail_silently=False)
     #     return data
 
+class WebclassRecordView(TemplateView):
+    template_name = 'webclass/record.html'
+
+    def get_context_data(self, **kwargs):
+        """ """
+        context = super(WebclassRecordView, self).get_context_data(**kwargs)
+        context['record_url'] = self.request.GET.get('url')
+        return context
+
 
 class WebclassRecordsFormView(FormView):
     template_name = 'webclass/records_form.html'
@@ -157,10 +157,14 @@ class WebclassRecordsFormView(FormView):
     def form_valid(self, form):
         form.save_records()
         return super(WebclassRecordsFormView, self).form_valid(form)
-
+        
+    @method_decorator(permission_required('is_superuser'))
+    @method_decorator(login_required)
+    def dispatch(self, *args, **kwargs):
+        return super(WebclassRecordsFormView, self).dispatch(*args, **kwargs)
 
 def join_webclass(request, pk):
-    webclass_slot = WebclassSlot.objects.get(pk=int(pk))
+    webclass_slot = WebclassSlot.published.get(pk=int(pk))
     # webclass = webclass_slot.webclass
     # fake debug links
     # username = request.GET.get('username')