]> git.parisson.com Git - teleforma.git/commitdiff
WIP notelemeta
authorYoan Le Clanche <yoanl@pilotsystems.net>
Tue, 30 Jun 2020 15:24:32 +0000 (17:24 +0200)
committerYoan Le Clanche <yoanl@pilotsystems.net>
Wed, 17 Nov 2021 14:26:17 +0000 (15:26 +0100)
23 files changed:
teleforma/4.0.5.zip [new file with mode: 0644]
teleforma/locale/fr/LC_MESSAGES/django.po
teleforma/models/core.py
teleforma/models/profile.py [deleted file]
teleforma/models/profile.py.bak [new file with mode: 0644]
teleforma/static/django_tinymce/init_tinymce.js [new file with mode: 0644]
teleforma/static/teleforma/css/teleforma.css
teleforma/static/teleforma/images/text-speak.png [new file with mode: 0644]
teleforma/static/teleforma/js/application.js
teleforma/static/teleforma/js/locale.js [new file with mode: 0644]
teleforma/templates/teleforma/base.html
teleforma/templates/teleforma/course.html
teleforma/templates/teleforma/course_media_transcoded.html [new file with mode: 0644]
teleforma/templates/teleforma/flatpage.html [new file with mode: 0644]
teleforma/templates/teleforma/inc/media_list.html
teleforma/templatetags/teleforma_tags.py
teleforma/urls.py
teleforma/views/__init__.py
teleforma/views/core.py
teleforma/views/home.py [new file with mode: 0644]
teleforma/views/pages.py [new file with mode: 0644]
teleforma/views/profile.py
wsgi.py [new file with mode: 0644]

diff --git a/teleforma/4.0.5.zip b/teleforma/4.0.5.zip
new file mode 100644 (file)
index 0000000..db83dbe
Binary files /dev/null and b/teleforma/4.0.5.zip differ
index 31388ce5b28c1ec143f85ac7d3bae19375b8c63c..ae65bd9d114cff1b52241e5660f74a8890dc945c 100644 (file)
@@ -1675,6 +1675,9 @@ msgstr "date de modification"
 #: templates/teleforma/inc/seminar_description.html:21
 msgid "preview"
 msgstr ""
+#: templates/telemeta/base.html:159
+msgid "Sign out"
+msgstr "Se déconnecter"
 
 #: templates/teleforma/inc/seminar_description.html:21
 msgid "play"
@@ -1923,11 +1926,11 @@ msgstr ""
 
 #: templates/telemeta/login.html:29
 msgid "Password forgotten"
-msgstr ""
+msgstr "Mot de passe oublié ?"
 
 #: templates/telemeta/login.html:30
 msgid "Sign in"
-msgstr ""
+msgstr "Connexion"
 
 #: templates/telemeta/profile_detail.html:6
 #, fuzzy
@@ -1998,16 +2001,21 @@ msgid "Email"
 msgstr ""
 
 #: templates/telemeta/profile_detail.html:85
+#: templates/telemeta/profile_detail.html:80
+msgid "WiFi password"
+msgstr "Mot de passe WiFi"
+
+#: templates/telemeta/profile_detail.html:84
 msgid "Expiration date"
 msgstr "Date d'expiration"
 
 #: templates/telemeta/profile_detail.html:86
 msgid "Last login"
-msgstr ""
+msgstr "Dernière connexion"
 
 #: templates/telemeta/profile_detail.html:97
 msgid "Apply"
-msgstr ""
+msgstr "Appliquer"
 
 #: templates/telemeta/profile_detail.html:108
 msgid "Password reset"
@@ -2020,7 +2028,7 @@ msgstr ""
 
 #: templates/telemeta/search_criteria.html:69
 msgid "Search"
-msgstr ""
+msgstr "Recherche"
 
 #: templates/telemeta/search_criteria.html:113
 msgid "Year of recording"
index 921e53edc82c8dcf5c8993fc7179ebb0d61d01ff..79745814978ae996b36b6b162c96316d49c4036c 100755 (executable)
@@ -577,6 +577,11 @@ class Media(MediaBase):
         self.set_mime_type()
 
 
+    def poster_url(self, geometry='640'):
+        url = ''
+        if self.poster_file:
+            url = sorl_default.backend.get_thumbnail(self.poster_file, geometry).url
+        return url
 
     class Meta(MetaCore):
         db_table = app_label + '_' + 'media'
diff --git a/teleforma/models/profile.py b/teleforma/models/profile.py
deleted file mode 100644 (file)
index 501e4d0..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from django.db import models
-from django.contrib.auth.models import User
-from teleforma.models.core import MetaCore
-from django.utils.translation import ugettext_lazy as _
-
-class UserProfile(models.Model):
-    "User profile extension"
-
-    user            = models.ForeignKey(User, unique=True, related_name="profile")
-    institution     = models.CharField(_('Institution'))
-    department      = models.CharField(_('Department'))
-    attachment      = models.CharField(_('Attachment'))
-    function        = models.CharField(_('Function'))
-    address         = models.TextField(_('Address'))
-    telephone       = models.CharField(_('Telephone'))
-    expiration_date = models.DateField(_('Expiration_date'))
-
-    class Meta(MetaCore):
-        db_table = 'profiles'
-        permissions = (("can_not_view_users_and_profiles", "Cannot view other users and any profile"),)
diff --git a/teleforma/models/profile.py.bak b/teleforma/models/profile.py.bak
new file mode 100644 (file)
index 0000000..501e4d0
--- /dev/null
@@ -0,0 +1,20 @@
+from django.db import models
+from django.contrib.auth.models import User
+from teleforma.models.core import MetaCore
+from django.utils.translation import ugettext_lazy as _
+
+class UserProfile(models.Model):
+    "User profile extension"
+
+    user            = models.ForeignKey(User, unique=True, related_name="profile")
+    institution     = models.CharField(_('Institution'))
+    department      = models.CharField(_('Department'))
+    attachment      = models.CharField(_('Attachment'))
+    function        = models.CharField(_('Function'))
+    address         = models.TextField(_('Address'))
+    telephone       = models.CharField(_('Telephone'))
+    expiration_date = models.DateField(_('Expiration_date'))
+
+    class Meta(MetaCore):
+        db_table = 'profiles'
+        permissions = (("can_not_view_users_and_profiles", "Cannot view other users and any profile"),)
diff --git a/teleforma/static/django_tinymce/init_tinymce.js b/teleforma/static/django_tinymce/init_tinymce.js
new file mode 100644 (file)
index 0000000..99c141a
--- /dev/null
@@ -0,0 +1,38 @@
+(function ($) {
+  function initTinyMCE($e) {
+    if ($e.parents('.empty-form').length == 0) {  // Don't do empty inlines
+      var mce_conf = $.parseJSON($e.attr('data-mce-conf'));
+      var id = $e.attr('id');
+      if ('elements' in mce_conf && mce_conf['mode'] == 'exact') {
+        mce_conf['elements'] = id;
+      }
+      if ($e.attr('data-mce-gz-conf')) {
+        tinyMCE_GZ.init($.parseJSON($e.attr('data-mce-gz-conf')));
+      }
+      if (!tinyMCE.editors[id]) {
+        tinyMCE.init(mce_conf);
+      }
+    }
+  }
+
+  $(function () {
+    // initialize the TinyMCE editors on load
+    $('.tinymce').each(function () {
+      initTinyMCE($(this));
+    });
+
+    // initialize the TinyMCE editor after adding an inline
+    // XXX: We don't use jQuery's click event as it won't work in Django 1.4
+    document.body.addEventListener("click", function(ev) {
+      if(!ev.target.parentNode || ev.target.parentNode.className.indexOf("add-row") === -1) {
+        return;
+      }
+      var $addRow = $(ev.target.parentNode);
+      setTimeout(function() {  // We have to wait until the inline is added
+        $('textarea.tinymce', $addRow.parent()).each(function () {
+          initTinyMCE($(this));
+        });
+      }, 0);
+    }, true);
+  });
+}(jQuery));
index c66bd554de5b68064666c6fc66ac37e28308fb1f..7b4d6eb5f4a2ff4f03203534ab7007393f305574 100644 (file)
@@ -665,8 +665,6 @@ color:#FFF;
 }
 #footer :link, #footer :visited { color: #FFF; }
 #footer hr { display: none }
-#footer #telemeta_powered { border: 0; float: left }
-#footer #telemeta_powered:hover { background: transparent }
 #footer p { margin: 0; }
 #footer p.left {
     float: left;
diff --git a/teleforma/static/teleforma/images/text-speak.png b/teleforma/static/teleforma/images/text-speak.png
new file mode 100644 (file)
index 0000000..b31ebac
Binary files /dev/null and b/teleforma/static/teleforma/images/text-speak.png differ
index 81668290cc334beb310a529b04429553236a1e7a..4287d43d8f95ed6f8995517ba7be17bb5a5524bd 100644 (file)
@@ -123,7 +123,7 @@ function getCookie(name) {
  */
 
 /**
- * Class for telemeta global functions.
+ * Class for teleforma global functions.
  * Note that the dollar sign is a reserved keyword in some browsers
  * (see http://davidwalsh.name/dollar-functions)
  * which might be in conflict with jQuery dollar sign.
@@ -158,7 +158,7 @@ function foldInfoBlocks() {
 }
 
 /**
- * Global telemeta function which sets the current selected menu according to the current url
+ * Global teleforma function which sets the current selected menu according to the current url
  */
 function setSelectedMenu(){
     var $J = jQuery;
diff --git a/teleforma/static/teleforma/js/locale.js b/teleforma/static/teleforma/js/locale.js
new file mode 100644 (file)
index 0000000..3f73753
--- /dev/null
@@ -0,0 +1,50 @@
+var localeStrings = {
+    'title': gettext('title'),
+    'description': gettext('description'),
+    'delete the marker permanently?': gettext('delete the marker permanently?'),
+    'marker added to the selected playlist': gettext('marker added to the selected playlist'),
+    'item added to the selected playlist': gettext('item added to the selected playlist'),
+    'collection added to the selected playlist': gettext('collection added to the selected playlist'),
+    'resource added to the selected playlist': gettext('resource added to the selected playlist'),
+    'there are unsaved or modified markers': gettext('there are unsaved or modified markers'),
+    'If you exit the page you will loose your changes' : gettext('If you exit the page you will loose your changes'),
+    'author' : gettext('author'),
+    'Paste HTML to embed player in website': gettext('Paste HTML to embed player in website'),
+    'delete the item permanently?' : gettext('delete the item permanently?'),
+    'delete the collection permanently?' : gettext('delete the collection permanently?'),
+    'delete the playlist permanently?' : gettext('delete the playlist permanently?'),
+    'delete the resource from the playlist permanently?' : gettext('delete the resource from the playlist permanently?'),
+};
+
+function gettrans(str){
+    var loc = localeStrings; //instantiate once for faster lookup
+    return str in loc ? loc[str] : str;
+}
+
+/*
+ * Copyright (C) 2007-2011 Parisson
+ * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ * 
+ * This file is part of TimeSide.
+ *
+ * TimeSide is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * TimeSide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ */
+
+/**
+ * Class for managing translations in telemeta.
+ */
+
+
index f92d860b5b7a4f80de96d38f8208fc3a63c00a7e..188a6a9ea8cc9ca861a96ce7b217073517028336 100644 (file)
@@ -47,7 +47,7 @@
   <script src="/static/teleforma/js/messi.min.js" type="text/javascript"></script>
   <script src="/static/teleforma/js/rainbowvis.js" type="text/javascript"></script>
   <script src="/static/jqchat/jqchat.js" type="text/javascript"></script>
-  <!-- <script src="/static/telemeta/js/locale.js" type="text/javascript"></script> -->
+  <script src="/static/teleforma/js/locale.js" type="text/javascript"></script>
   <script src="/static/teleforma/js/application.js" type="text/javascript"></script>
 
   {% if user.is_authenticated %}
           <td>
             <p class="right">
               Copyright &copy; {% current_year %} {% organization %} |
-              TODO : missing link <!-- <a href="{ url telemeta-flatpage "legal_notices" }">{% trans "Legal notices" %}</a> -->
+              <a href="{% url teleforma-flatpage "legal_notices" %}">{% trans "Legal notices" %}</a>
             </p>
           </td>
         </tr>
index 589539cf99d72d3a88b27d6191e2f813578b48ff..7985d01ee02056765381f94b440a9e8ee3cfb1df 100644 (file)
@@ -36,8 +36,8 @@
 </tr>
 {% for media in course.media.all %}
 <tr {% if not forloop.counter0|divisibleby:"2" %}class="odd"{% endif %}>
-<td><a href="{% url teleforma-item-detail media.item.public_id %}">{{ media.item.title }}</a></td>
-<td>{{ media.item.description }}</td>
+<td><a href="{% url teleforma-item-detail media.id %}">{{ media.title }}</a></td>
+<td>{{ media.description }}</td>
 <td>{{ media.date_added }}</td>
 </tr>
 {% endfor %}
diff --git a/teleforma/templates/teleforma/course_media_transcoded.html b/teleforma/templates/teleforma/course_media_transcoded.html
new file mode 100644 (file)
index 0000000..5374132
--- /dev/null
@@ -0,0 +1,120 @@
+{% extends "teleforma/course_detail.html" %}
+{% load teleforma_tags %}
+{% load i18n %}
+{% load thumbnail %}
+
+{% block extra_javascript %}
+
+{% if "video" in media.mime_type %}
+<script src="/static/teleforma/video-js/video.js"></script>
+<link href="/static/teleforma/video-js/video-js.css" rel="stylesheet">
+{% endif %}
+
+<script type="text/javascript">
+$(document).ready(function(){
+    InitChatWindow("{% url jqchat_ajax room.id %}", null);
+    $('#my_video_1').bind('contextmenu',function() { return false; });
+    });
+</script>
+
+{% endblock extra_javascript %}
+
+{% block module-action %}
+{% if media_transcoded.file and media.is_published or user.is_superuser or user.is_staff %}
+ {% if not "video" in media.mime_type or request.user_agent.os.family == 'iOS' %}
+  <div class="module_action">
+   <a href="{% url teleforma-media-transcoded-download period.id media.id %}" class="component_icon button" id="action_red"><img src="/static/teleforma/images/download_media.png" alt="" style="vertical-align:middle" />&nbsp;{% trans "Download" %}</a>
+  </div>
+ {% endif %}
+{% endif %}
+{% endblock module-action %}
+
+{% block course %}
+<div class="course_media">
+
+<div class="course_title">
+    <div style="float: right; font-size: 0.9em;">
+        {% if "video" in media_transcoded.mime_type %}
+        <a href="{% url teleforma-media-transcoded period.id media|get_audio_id %}" class="component_icon button icon_speaker">&nbsp;{% trans "Audio" %}</a>
+        {% endif %}
+        {% if "audio" in media_transcoded.mime_type %}
+        <a href="{% url teleforma-media-detail period.id media|get_video_id %}" class="component_icon button icon_clap">&nbsp;{% trans "Video" %}</a>
+        {% endif %}
+    </div>
+
+    <a href="{% url teleforma-desk-period-course period.id course.id %}">{{ course.title }} - {{ type }}{% if media.conference.session %} - {% trans "Session" %} {{ media.conference.session }}{% endif %}</a>
+
+</div>
+
+{% if access_error %}
+  <p>{{ access_error }}</p>
+  <p>{{ message }}</p>
+
+{% else %}
+<div class="media">
+
+    
+{% if "video" in media_transcoded.mime_type %}
+<div class="video">
+    <video id="my_video_1" class="video-js vjs-default-skin" width="864" height="480" controls preload="auto" data-setup='{}' {% if media.poster_file %}{% thumbnail media.poster_file "640" as im %}poster="{{ im.url }}"{% endthumbnail %}{% endif %}>
+        <source src="{{ MEDIA_URL }}{{ media.media_transcoded }}" type="{{ media.mime_type }}" />
+    </video>
+</div>
+
+{% elif "audio" in media_transcoded.mime_type %}
+
+
+<div style="margin-top:1em;">
+{% if media.poster_file %}
+
+   {% thumbnail media.poster_file "300" as im %}
+    <img src="{{ im.url }}" width="300px" alt="preview" />
+   {% endthumbnail %}
+
+{% else %}
+ snapshot
+{% endif %}
+
+</div>
+<div class="audio">
+    <audio controls preload="auto">
+        <source src="{{ MEDIA_URL }}{{ media.media_transcoded }}" type="{{ media.mime_type }}" />
+    </audio>
+</div>
+{% endif %}
+
+</div>
+{% endif %}
+
+{% block general_info %}
+<div class="course_content" id="media_infos">
+<dl class="listing">
+
+{% if media.conference %}
+<dt>{% trans "Course" %}</dt><dd><a href="{% url teleforma-desk-period-course period.id course.id %}">{{ media.course.title }} - {{ media.course_type }}</a></dd>
+<dt>{% trans "Session" %}</dt><dd>{{ media.conference.session }}</dd>
+{% if media.conference.professor %}
+<dt>{% trans "Professor" %}</dt>
+    <dd><a href="{% url teleforma-profile-detail media.conference.professor.user.username %}" target="_blank">{{ media.conference.professor }}</a></dd>
+{% endif %}
+{% if media.conference.comment %}<dt>{% trans "Comment" %}</dt><dd>{{ media.conference.comment }}</dd>{% endif %}
+<dt>{% trans "Begin date" %}</dt><dd>{{ media.conference.date_begin }}</dd>
+<dt>{% trans "End date" %}</dt><dd>{{ media.conference.date_end }}</dd>
+{% if media.conference.room %}<dt>{% trans "Room" %}</dt><dd>{{ media.conference.room }}</dd>{% endif %}
+{% if user.is_staff or user.is_superuser %}
+<dt>{% trans "Mime type" %}</dt><dd>{{ media.mime_type }}</dd>
+<dt>{% trans "Date added" %}</dt><dd>{{ media.date_added }}</dd>
+<dt>{% trans "Date modified" %}</dt><dd>{{ media.date_modified }}</dd>
+<dt>{% trans "Media ID" %}</dt><dd>{{ media.id }}</dd>
+<dt>{% trans "Conference ID" %}</dt><dd>{{ media.conference.public_id }}</dd>
+<dt>{% trans "Web class group" %}</dt><dd>{{ media.conference.web_class_group }}</dd>
+{% endif %}
+{% endif %}
+
+</dl>
+</div>
+
+{% endblock general_info %}
+
+</div>
+{% endblock course %}
diff --git a/teleforma/templates/teleforma/flatpage.html b/teleforma/templates/teleforma/flatpage.html
new file mode 100644 (file)
index 0000000..a9ee2cf
--- /dev/null
@@ -0,0 +1,5 @@
+{% extends "teleforma/base.html" %}
+{% load teleforma_tags %}
+{% block content %}
+{{ page_content|render_flatpage }}
+{% endblock %}
index 98f2a72714260a8c0b3c2b4ffa79ff17c31b024e..2a136ecfbe848ada41d453c45063101c3936b73a 100644 (file)
             <tr>
             <td {% if forloop.first %}class="border-top"{% endif %} width="230px" style="vertical-align:middle">
             <a href="{% url teleforma-media-detail media.id %}" title="{% trans "Play" %}">
-            {% if media.item.related.all %}
-             {% for related in media.item.related.all %}
-              {% if related.title == "preview" %}
+            {% if media.poster_file %}
                {% thumbnail related.file "168x96" as im %}
                 <div style="background: no-repeat url('{{ im.url|set_host:HOST }}') 0 1px; background-size: 100%; background-color: #dfdfdf;">
                  <img src="{{ STATIC_URL }}teleforma/images/play_168.png" width="100%" alt="{% trans 'Click here' %}" />
                 </div>
                {% endthumbnail %}
-              {% endif %}
-             {% endfor %}
             {% else %}
               {% trans 'Click here' %}
             {% endif %}
@@ -51,8 +47,8 @@
             {% elif not media.is_published and user.is_staff %}
              <img src="{{ STATIC_URL }}teleforma/images/delete.png" style="vertical-align:middle" alt="" title="{% trans ' rejected' %}" />
             {% endif %}
-            {% if media.item.file and user.is_staff %}
-             <a href="{{ MEDIA_URL|set_host:HOST }}{{ media.item.file }}">
+            {% if media.file and user.is_staff %}
+             <a href="{{ MEDIA_URL|set_host:HOST }}{{ media.file }}">
               <img src="{{ STATIC_URL }}teleforma/images/download_media.png" style="vertical-align:middle" alt="" title="{% trans "Download" %}" />
              </a>
             {% endif %}
index 0c02df4bb7925e93e12e9607326bb41d35280072..8d98c9e6b447be53497829af78fbf652f00fa8ea 100644 (file)
@@ -51,6 +51,12 @@ from django.conf import settings
 from django.template.defaultfilters import stringfilter
 import django.utils.timezone as timezone
 from django.utils.translation import ugettext_lazy as _
+from urlparse import urlparse
+from docutils.core import publish_parts
+from django.utils.encoding import smart_str, force_unicode
+from django.utils.safestring import mark_safe
+
+from teleforma.models.crfpa import Course
 from teleforma.views import get_courses
 from teleforma.context_processors import *
 from urlparse import urlparse
@@ -388,4 +394,33 @@ def organization():
 
 @register.simple_tag
 def current_year():
-    return datetime.datetime.now().strftime("%Y")
\ No newline at end of file
+    return datetime.datetime.now().strftime("%Y")
+
+@register.filter
+def render_flatpage(content):
+    parsed = ""
+    path = getattr(content, 'path', '')
+    if isinstance(content, basestring):
+        content = content.split("\n")
+
+    for line in content:
+        match = re.match('^(\.\. *(?:_[^:]*:|(?:\|\w+\|)? *image::) *)([^ ]+) *$', line)
+        if match:
+            directive, urlname = match.groups()
+            line = directive
+            try:
+                i = urlname.index('telemeta-')
+            except ValueError:
+                i = -1
+            if i == 0:
+                line += reverse(urlname)
+            elif urlname[:1] != '/':
+                line += reverse('telemeta-flatpage', args=[path + '/../' + urlname])
+            else:
+                line += urlname
+
+        parsed += line + "\n"
+
+    parts = publish_parts(source=smart_str(parsed), writer_name="html4css1", settings_overrides={})
+    return mark_safe('<div class="rst-content">\n' + force_unicode(parts["html_body"]) + '</div>')
+render_flatpage.is_safe = True
\ No newline at end of file
index 6d8fa13bdb1d08d7505eed273770ee7bf6199ef3..82b9bd0e1c02c15959999262376b71c7f4b47058 100644 (file)
@@ -49,14 +49,16 @@ user_export = UsersXLSExport()
 profile_view = ProfileView()
 document = SeminarDocumentView()
 media = MediaView()
+home_view = HomeView()
+media_transcoded = MediaTranscodedView
 
 urlpatterns = patterns('',
-#    url(r'^$', HomeView.as_view(), name='teleforma-home'),
-    url(r'^$', SeminarsView.as_view(), name="home"),
-    url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'telemeta/login.html', 'authentication_form': AuthenticationForm },
+
+    # login / logout
+    url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'teleforma/login.html'},
+        name="telemeta-login"),
+    url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'registration/login.html'},
         name="teleforma-login"),
-    url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'teleforma/login.html'},
-        name="auth_login"),
     url(r'^logout/$', 'django.contrib.auth.views.logout', name="teleforma-logout"),
 
     url(r'^users/(?P<username>[A-Za-z0-9+@._-]+)/profile/$', profile_view.profile_detail,
index 4308dbaffe4a9e6fe1b02a36e8d96fcc328395e0..1727a72857295721aa841bc6b5f154ed9cc3709c 100644 (file)
@@ -2,4 +2,4 @@ from core import *
 from crfpa import *
 from ae import *
 from pro import *
-from profile import *
\ No newline at end of file
+from profile import *
index b40edb6ada0fe47de2ad6c300469bca73c9a7ac4..de57004c47ed0a3a5d16bdda55714fa7410a4495 100644 (file)
@@ -82,6 +82,7 @@ from teleforma.models import *
 from teleforma.forms import *
 from telemeta.views import *
 from teleforma.context_processors import *
+import pages
 import jqchat.models
 from xlwt import Workbook
 
@@ -283,6 +284,17 @@ class CourseView(DetailView):
     def dispatch(self, *args, **kwargs):
         return super(CourseView, self).dispatch(*args, **kwargs)
 
+    @jsonrpc_method('teleforma.get_course_media_urls')
+    def get_course_media_urls(request, id):
+        course = Course.objects.get(code=id)
+        media_list = []
+        for media in course.media.all():
+            if media.is_published and media.file and media.conference and 'video' in media.mime_type:
+                urls = [ {'url': settings.MEDIA_URL + unicode(media.file), 'mime_type': media.mime_type} ]
+                for transcoded in media.transcoded.all():
+                    urls.append({'url':settings.MEDIA_URL + unicode(transcoded.file), 'mime_type': transcoded.mime_type})
+                media_list.append({'session': media.conference.session, 'urls': urls, 'poster': media.poster_url()})
+        return media_list
 
 
 class CoursesView(ListView):
@@ -325,7 +337,6 @@ class MediaView(DetailView):
         context['media'] = media
         context['mime_type'] = media.mime_type
         context['course'] = media.course
-        context['item'] = media.item
         context['type'] = media.course_type
         context['notes'] = media.notes.all().filter(author=self.request.user)
         content_type = ContentType.objects.get(app_label="teleforma", model="media")
@@ -375,6 +386,86 @@ class MediaView(DetailView):
         media.is_published = False
         media.save()
 
+    def stream(self, request, period_id, pk, streaming=True):
+        courses = get_courses(request.user)
+        media = Media.objects.get(id=pk)
+        if get_access(media, courses):
+            media_path = media.file.path
+            return serve_media(media_path, content_type=media.mime_type, streaming=streaming)
+        else:
+            raise Http404("You don't have access to this media.")
+
+    def download(self, request, period_id, pk):
+        return self.stream(request, period_id, pk, streaming=False)
+
+class MediaTranscodedView(CourseAccessMixin, DetailView):
+
+    model = MediaTranscoded
+    template_name='teleforma/course_media_transcoded.html'
+
+    def get_context_data(self, **kwargs):
+        context = super(MediaTranscodedView, self).get_context_data(**kwargs)
+        media_transcoded = self.get_object()
+        media = media_transcoded.item
+        if not media_transcoded.mime_type:
+            media_transcoded.set_mime_type()
+        context['media'] = media
+        context['media_transcoded'] = media_transcoded
+        context['mime_type'] = media_transcoded.mime_type
+        context['course'] = media.course
+        context['type'] = media.course_type
+        # context['notes'] = media.notes.all().filter(author=self.request.user)
+        content_type = ContentType.objects.get(app_label="teleforma", model="course")
+
+        room_name = media.course.code
+        if media.conference.web_class_group:
+            room_name += '_' + media.conference.public_id
+
+        context['room'] = get_room(name=room_name,period=context['period'].name,
+                                   content_type=content_type,
+                                   id=media.course.id)
+
+        access = get_access(media, context['all_courses'])
+        if not access:
+            context['access_error'] = access_error
+            context['message'] = contact_message
+
+        return context
+
+    @method_decorator(login_required)
+    def dispatch(self, *args, **kwargs):
+        return super(MediaTranscodedView, self).dispatch(*args, **kwargs)
+
+    def stream(self, request, period_id, pk, streaming=True):
+        courses = get_courses(request.user)
+        media = MediaTranscoded.objects.get(id=pk)
+        if get_access(media, courses):
+            media_path = media.file.path
+            return serve_media(media_path, content_type=media.mime_type, streaming=streaming)
+        else:
+            raise Http404("You don't have access to this media.")
+
+    def download(self, request, period_id, pk):
+        return self.stream(request, period_id, pk, streaming=False)
+
+
+class MediaPendingView(ListView):
+
+    model = Media
+    template_name='teleforma/media_pending.html'
+
+    def get_queryset(self):
+        return Media.objects.filter(is_published=False)
+
+    def get_context_data(self, **kwargs):
+        context = super(MediaPendingView, self).get_context_data(**kwargs)
+        return context
+
+    @method_decorator(permission_required('is_superuser'))
+    @method_decorator(login_required)
+    def dispatch(self, *args, **kwargs):
+        return super(MediaPendingView, self).dispatch(*args, **kwargs)
+
 
 class DocumentView(DetailView):
 
diff --git a/teleforma/views/home.py b/teleforma/views/home.py
new file mode 100644 (file)
index 0000000..b549b43
--- /dev/null
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2010 Samalyse SARL
+# Copyright (C) 2010-2012 Parisson SARL
+
+# This software is a computer program whose purpose is to backup, analyse,
+# transcode and stream any audio content with its metadata over a web frontend.
+
+# This software is governed by the CeCILL  license under French law and
+# abiding by the rules of distribution of free software.  You can  use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability.
+
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and,  more generally, to use and operate it in the
+# same conditions as regards security.
+
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+# Authors: Olivier Guilyardi <olivier@samalyse.com>
+#          Guillaume Pellerin <yomguy@parisson.com>
+
+import pages
+from django.shortcuts import render, redirect
+from django.contrib import auth
+from django.http import HttpResponse
+
+class HomeView(object):
+    """Provide general web UI methods"""
+
+    def render_flatpage(self, request, path):
+        try:
+            content = pages.get_page_content(request, path)
+        except pages.MalformedPagePath:
+            return redirect(request.path + '/')
+
+        if isinstance(content, pages.PageAttachment):
+            return HttpResponse(content, content.mimetype())
+        else:
+            return render(request, 'teleforma/flatpage.html', {'page_content': content })
+
+    def logout(self, request):
+        auth.logout(request)
+        return redirect('teleforma-home')
+
diff --git a/teleforma/views/pages.py b/teleforma/views/pages.py
new file mode 100644 (file)
index 0000000..f805f5b
--- /dev/null
@@ -0,0 +1,118 @@
+from django.conf import settings
+import re
+import os
+import mimetypes
+import teleforma
+
+PAGES_ROOT = os.path.join(os.path.dirname(teleforma.__file__), 'pages')
+
+class PageTextContent(object):
+    def __init__(self, filename, path):
+        self.filename = filename
+        self.path = path
+
+    def __iter__(self):
+        file = open(self.filename, 'r')
+        for line in file:
+            yield line.rstrip('\r\n')
+        file.close()
+
+    def __unicode__(self):
+        file = open(self.filename, 'r')
+        data = file.read()
+        file.close()
+        return data
+
+class PageAttachment(object):
+    def __init__(self, filename, path):
+        self.filename = filename
+        self.path     = path
+
+    def mimetype(self):
+        type, encoding = mimetypes.guess_type(self.filename)
+        return type
+
+    def __iter__(self):
+        file = open(self.filename, 'rb')
+        buffer_size = 0x10000
+        while True:
+            chunk = file.read(buffer_size)
+            yield chunk
+            if len(chunk) < buffer_size:
+                break
+
+        file.close()
+
+def language_code(request=None):
+    code = (request and getattr(request, 'LANGUAGE_CODE', None)) or settings.LANGUAGE_CODE
+    cut = re.split('[_-]', code)
+    code = cut[0]
+    return code.lower()
+
+def project_dir():
+    import settings as settings_mod
+    if '__init__.py' in settings_mod.__file__:
+        p = os.path.dirname(settings_mod.__file__)
+    else:
+        p = settings_mod.__file__
+    project_directory, settings_filename = os.path.split(p)
+    if project_directory == os.curdir or not project_directory:
+        project_directory = os.getcwd()
+
+    return project_directory
+
+def resolve_page_file(root, relative_path, ignore_slash_issue=False):
+    root = os.path.realpath(root)
+    filename = None
+    current = root
+    is_attachment = False
+    for node in relative_path.split('/'):
+        if not node:
+            continue
+        current = os.path.join(current, node)
+        rst = current + '.rst'
+        if os.path.isfile(rst):
+            filename = rst
+            break
+        elif os.path.isfile(current):
+            filename      = current
+            is_attachment = True
+        elif not os.path.isdir(current):
+            break
+
+    if not filename and os.path.isdir(current):
+        rst = os.path.join(current, 'index.rst')
+        if os.path.isfile(rst):
+            if not ignore_slash_issue and relative_path[-1:] != '/':
+                raise MalformedPagePath("The relative page os.path must end with a slash when "
+                                        "resolving an implicit directory index")
+            filename = rst
+
+    if filename:
+        filename = os.path.realpath(filename)
+        if filename.index(root) != 0:
+            filename = None
+
+    if filename:
+        if is_attachment:
+            return PageAttachment(filename, relative_path)
+        else:
+            return PageTextContent(filename, relative_path)
+
+    return None
+
+def get_page_content(request, relative_path, ignore_slash_issue=False):
+    lang = language_code(request)
+    userroot = os.path.join(project_dir(), 'telemeta-pages')
+    rootlist = [os.path.join(userroot, lang), os.path.join(userroot, 'default'),
+                os.path.join(PAGES_ROOT, lang), os.path.join(PAGES_ROOT, 'default')]
+    for root in rootlist:
+        content = resolve_page_file(root, relative_path, ignore_slash_issue=ignore_slash_issue)
+        if content:
+            return content
+
+    return None
+
+class MalformedPagePath(Exception):
+    pass
+
index 5e5015d788b2ec67cd5809557b3df957296b0858..0a077ff1edc3636ab572216ba41f43cdd0e0eaa0 100644 (file)
@@ -1,44 +1,44 @@
-# -*- coding: utf-8 -*-
-# Copyright (C) 2007-2010 Samalyse SARL
-# Copyright (C) 2010-2012 Parisson SARL
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2010 Samalyse SARL
+# Copyright (C) 2010-2012 Parisson SARL
 
-# This software is a computer program whose purpose is to backup, analyse,
-# transcode and stream any audio content with its metadata over a web frontend.
+# This software is a computer program whose purpose is to backup, analyse,
+# transcode and stream any audio content with its metadata over a web frontend.
 
-# This software is governed by the CeCILL  license under French law and
-# abiding by the rules of distribution of free software.  You can  use,
-# modify and/ or redistribute the software under the terms of the CeCILL
-# license as circulated by CEA, CNRS and INRIA at the following URL
-# "http://www.cecill.info".
+# This software is governed by the CeCILL  license under French law and
+# abiding by the rules of distribution of free software.  You can  use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
 
-# As a counterpart to the access to the source code and  rights to copy,
-# modify and redistribute granted by the license, users are provided only
-# with a limited warranty  and the software's author,  the holder of the
-# economic rights,  and the successive licensors  have only  limited
-# liability.
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability.
 
-# In this respect, the user's attention is drawn to the risks associated
-# with loading,  using,  modifying and/or developing or reproducing the
-# software by the user in light of its specific status of free software,
-# that may mean  that it is complicated to manipulate,  and  that  also
-# therefore means  that it is reserved for developers  and  experienced
-# professionals having in-depth computer knowledge. Users are therefore
-# encouraged to load and test the software's suitability as regards their
-# requirements in conditions enabling the security of their systems and/or
-# data to be ensured and,  more generally, to use and operate it in the
-# same conditions as regards security.
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and,  more generally, to use and operate it in the
+# same conditions as regards security.
 
-# The fact that you are presently reading this means that you have had
-# knowledge of the CeCILL license and that you accept its terms.
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
 
-# Authors: Olivier Guilyardi <olivier@samalyse.com>
-#          Guillaume Pellerin <yomguy@parisson.com>
+# Authors: Olivier Guilyardi <olivier@samalyse.com>
+#          Guillaume Pellerin <yomguy@parisson.com>
 
 from django.contrib.auth.models import User
 from django.contrib.auth.forms import UserChangeForm
 from django.utils.decorators import method_decorator
 from django.contrib.auth.decorators import login_required
-from teleforma.models.profile import UserProfile
+from teleforma.models.crfpa import Profile as UserProfile
 from teleforma.forms import UserProfileForm
 
 class ProfileView(object):
diff --git a/wsgi.py b/wsgi.py
new file mode 100644 (file)
index 0000000..e69de29