setuptools
django==1.4.19
telemeta==1.4.6
-south
-django-pagination==1.0.7
+south # a supprimer
+django-pagination==1.0.7 # a supprimer
django-postman==3.2.0
django-extensions==0.9
-django-notes
+django-notes # a supprimer
django-timezones==0.2
django-jqchat
-crocodoc
+crocodoc # a supprimer
django-registration==0.8
-django-extra-views==0.6.5
-django-simple-captcha
-django-suit
+django-extra-views==0.6.5 # a supprimer
+django-simple-captcha # a maj
+django-suit # a maj
django-nvd3
django-user-agents
xhtml2pdf
html5lib==0.95
django-tinymce==1.5.4
-django-quiz
+django-quiz # a supprimer
from captcha.fields import CaptchaField
from teleforma.models.core import Course, Professor
-from teleforma.models.profile import UserProfile
+from teleforma.models.crfpa import Profile as UserProfile
from tinymce.widgets import TinyMCE
from itertools import cycle
from django.core.files.images import get_image_dimensions
#: templates/telemeta/base.html:159
msgid "Sign out"
-msgstr ""
+msgstr "Se déconnecter"
#: templates/telemeta/base.html:201
msgid "Powered by"
#: 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
msgid "User Profile"
#: templates/telemeta/profile_detail.html:80
msgid "WiFi password"
-msgstr ""
+msgstr "Mot de passe WiFi"
#: templates/telemeta/profile_detail.html:84
msgid "Expiration date"
#: templates/telemeta/profile_detail.html:85
msgid "Last login"
-msgstr ""
+msgstr "Dernière connexion"
#: templates/telemeta/profile_detail.html:96
msgid "Apply"
-msgstr ""
+msgstr "Appliquer"
#: templates/telemeta/search_criteria.html:5
#: templates/telemeta/search_criteria.html:76
#: templates/telemeta/search_criteria.html:69
msgid "Search"
-msgstr ""
+msgstr "Recherche"
#: templates/telemeta/search_criteria.html:113
msgid "Year of recording"
def poster_url(self, geometry='640'):
url = ''
- for related in self.item.related.all():
- if 'preview' in related.title:
- url = sorl_default.backend.get_thumbnail(related.file, geometry).url
+ if self.poster_file:
+ url = sorl_default.backend.get_thumbnail(self.poster_file, geometry).url
return url
class Meta(MetaCore):
+++ /dev/null
-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"),)
--- /dev/null
+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"),)
--- /dev/null
+(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));
}
#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;
*/
/**
- * 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.
}
/**
- * 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;
--- /dev/null
+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.
+ */
+
+
*/
/**
- * 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.
{% load i18n %}
{% block title %}{% if account %}{% trans "Activation complete" %}{% else %}{% trans "Activation problem" %}{% endif %}{% endblock %}
{% block content %}
-{% url auth_login as auth_login_url %}
+{% url teleforma-login as auth_login_url %}
{% if account %}
{% blocktrans %}
Thanks {{ account }}, activation complete!
{% load i18n %}
{% block title %}{% trans "Activation complete" %}{% endblock %}
{% block content %}
-{% url auth_login as auth_login_url %}
+{% url teleforma-login as auth_login_url %}
{% blocktrans %}
Thanks, activation complete! You may now <a href='{{ auth_login_url }}'>login</a> using the username and password you set at registration.
{% endblocktrans %}
<p>{% blocktrans %}Your username and password didn't match. Please try again.{% endblocktrans %}</p>
{% endif %}
-<form method="post" action="{% url auth_login %}">{% csrf_token %}
+<form method="post" action="{% url teleforma-login %}">{% csrf_token %}
<table>
<tr>
<td>{% trans form.username.label_tag %}</td>
<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 © {% 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>
</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 %}
{% endblock extra_javascript %}
{% block module-action %}
-{% if media.item.file and media.is_published or user.is_superuser or user.is_staff %}
- {% if not "video" in media.mime_type or perms.telemeta.can_play_all_items or request.user_agent.os.family == 'iOS' %}
+{% if media.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-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" /> {% trans "Download" %}</a>
</div>
<div class="course_title">
<div style="float: right; font-size: 0.9em;">
{% if "video" in media.mime_type %}
- <a href="{% url teleforma-media-detail period.id media|get_audio_id %}" class="component_icon button icon_speaker"> {% trans "Audio" %}</a>
+ <a href="{% url teleforma-media-transcoded period.id media|get_audio_id %}" class="component_icon button icon_speaker"> {% trans "Audio" %}</a>
{% endif %}
{% if "audio" in media.mime_type %}
<a href="{% url teleforma-media-detail period.id media|get_video_id %}" class="component_icon button icon_clap"> {% trans "Video" %}</a>
{% if "video" in media.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.item.related.all %}{% for related in media.item.related.all %}{% if related.title == "preview" %}{% thumbnail related.file "640" as im %}poster="{{ im.url }}"{% endthumbnail %}{% endif %}{% endfor %}{% endif %}>
- <source src="{{ MEDIA_URL }}{{ media.item.file }}" type="{{ media.mime_type }}" />
+ <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.file }}" type="{{ media.mime_type }}" />
</video>
</div>
{% elif "audio" in media.mime_type %}
<div style="margin-top:1em;">
-{% if media.item.related.all %}
+{% if media.poster_file %}
- {% for related in media.item.related.all %}
- {% if related.title == "preview" %}
- {% thumbnail related.file "300" as im %}
+ {% thumbnail media.poster_file "300" as im %}
<img src="{{ im.url }}" width="300px" alt="preview" />
{% endthumbnail %}
- {% endif %}
- {% endfor %}
{% else %}
snapshot
</div>
<div class="audio">
<audio controls preload="auto">
- <source src="{{ MEDIA_URL }}{{ media.item.file }}" type="{{ media.mime_type }}" />
+ <source src="{{ MEDIA_URL }}{{ media.file }}" type="{{ media.mime_type }}" />
</audio>
</div>
{% endif %}
--- /dev/null
+{% 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" /> {% 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"> {% 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"> {% 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 %}
{% block layout %}
-{% if media.item.file and media.is_published or user.is_superuser or user.is_staff %}
+{% if media.file and media.is_published or user.is_superuser or user.is_staff %}
<div class="video">
-<video id="my_video_1" class="video-js vjs-default-skin" width="640" height="360" controls preload="auto" data-setup='{}' {% if media.item.related.all %}{% for related in media.item.related.all %}{% if related.title == "preview" %}{% thumbnail related.file "640" as im %}poster="{{ im.url }}"{% endthumbnail %}{% endif %}{% endfor %}{% endif %}>
-<source src="{{ MEDIA_URL }}{{ media.item.file }}" type="{{ media.mime_type }}" />
+<video id="my_video_1" class="video-js vjs-default-skin" width="640" height="360" 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.file }}" type="{{ media.mime_type }}" />
</video>
</div>
{% endif %}
<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 %}
+ {% if home_video.poster_file %}
+ {% thumbnail home_video.poster_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 %}
--- /dev/null
+{% extends "teleforma/base.html" %}
+{% load teleforma_tags %}
+{% block content %}
+{{ page_content|render_flatpage }}
+{% endblock %}
<tr>
<td {% if forloop.first %}class="border-top"{% endif %} width="230px" style="vertical-align:middle">
<a href="{% url teleforma-media-detail period.id media.id %}" title="{% trans "Play" %}">
- {% if media.item.related.all %}
- {% for related in media.item.related.all %}
- {% if related.title == "preview" %}
- {% thumbnail related.file "168x96" as im %}
+ {% if media.poster_file %}
+ {% thumbnail media.poster_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 %}
- {% else %}
- {% trans 'Click here' %}
- {% endif %}
- {% endfor %}
{% else %}
<div>{% trans 'Click here' %}</div>
{% endif %}
{% elif not media.is_published and user.is_staff %}
<img src="/static/teleforma/images/delete.png" style="vertical-align:middle" alt="" title="{% trans ' rejected' %}" />
{% endif %}
- {% if media.item.file and media.is_published or user.is_superuser or user.is_staff %}
- {% if not "video" in media.mime_type or perms.telemeta.can_play_all_items or request.user_agent.os.family == 'iOS' %}
+ {% if media.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' %}
<a href="{% url teleforma-media-download period.id media.id %}">
<img src="/static/teleforma/images/download_media.png" style="vertical-align:middle" alt="" title="{% trans "Download" %}" />
</a>
<tr>
<td {% if forloop.first %}class="border-top"{% endif %} width="230px" style="vertical-align:middle">
<a href="{% url teleforma-media-detail period.id media.id %}" title="{% trans "Play" %}">
- {% if media.item.related.all %}
- {% for related in media.item.related.all %}
- {% if related.title == "preview" %}
- {% thumbnail related.file "168x96" as im %}
+ {% if media.poster_file %}
+ {% thumbnail media.poster_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 %}
{% elif not media.is_published and user.is_staff %}
<img src="/static/teleforma/images/delete.png" style="vertical-align:middle" alt="" title="{% trans ' rejected' %}" />
{% endif %}
- {% if media.item.file %}
- <a href="{{ MEDIA_URL }}{{ media.item.file }}">
+ {% if media.file %}
+ <a href="{{ MEDIA_URL }}{{ media.file }}">
<img src="/static/teleforma/images/download_media.png" style="vertical-align:middle" alt="" title="{% trans "Download" %}" />
</a>
{% endif %}
from timezones.utils import localtime_for_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.core import Document
from teleforma.models.crfpa import Course, NewsItem
@register.filter
def get_audio_id(media):
- if media.conference:
- medias = media.conference.media.all()
- for m in medias:
- if 'audio' in m.mime_type:
- return m.id
+ for m in media.transcoded.all():
+ if 'audio' in m.mime_type:
+ return m.id
return
@register.filter
@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
profile_view = CRFPAProfileView()
document = DocumentView()
media = MediaView()
+home_view = HomeView()
+media_transcoded = MediaTranscodedView
urlpatterns = patterns('',
# 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"),
# (r'^accounts/register0/$', RegistrationView.as_view(), {'form_class':CustomRegistrationForm}),
# Home
url(r'^$', HomeRedirectView.as_view(), name="teleforma-home"),
+ # Flat pages
+ url(r'^pages/(?P<path>.*)$', home_view.render_flatpage, name="teleforma-flatpage"),
+
# Desk
url(r'^desk/$', HomeRedirectView.as_view(), name="teleforma-desk"),
url(r'^desk/periods/(?P<period_id>.*)/courses/$', CourseListView.as_view(), name="teleforma-desk-period-list"),
url(r'^desk/periods/(?P<period_id>.*)/courses/(?P<pk>.*)/detail/$', CourseView.as_view(),
name="teleforma-desk-period-course"),
+
+ url(r'^desk/periods/(?P<period_id>.*)/medias/transcode/(?P<pk>.*)/detail/$', MediaTranscodedView.as_view(), name="teleforma-media-transcoded"),
+ url(r'^desk/periods/(?P<period_id>.*)/medias/transcode/(?P<pk>.*)/download/$', media_transcoded.download, name="teleforma-media-transcoded-download"),
+ url(r'^desk/periods/(?P<period_id>.*)/medias/transcode/(?P<pk>.*)/stream/$', media_transcoded.stream, name="teleforma-media-transcoded-stream"),
url(r'^desk/periods/(?P<period_id>.*)/medias/(?P<pk>.*)/detail/$', MediaView.as_view(), name="teleforma-media-detail"),
url(r'^desk/periods/(?P<period_id>.*)/medias/(?P<pk>.*)/embed/$', MediaViewEmbed.as_view(), name="teleforma-media-embed"),
url(r'^desk/periods/(?P<period_id>.*)/medias/(?P<pk>.*)/download/$', media.download, name="teleforma-media-download"),
from appointment import *
from payment import *
from profile import *
+from home import *
from teleforma.forms import *
from teleforma.models.appointment import AppointmentPeriod
from teleforma.webclass.models import Webclass, WebclassSlot, WebclassRecord
+import pages
import jqchat.models
from xlwt import Workbook
course = Course.objects.get(code=id)
media_list = []
for media in course.media.all():
- if media.is_published and media.item.file and media.conference and 'video' in media.mime_type:
- urls = [ {'url': settings.MEDIA_URL + unicode(media.item.file), 'mime_type': media.mime_type} ]
- for transcoded in media.item.transcoded.all():
- urls.append({'url':settings.MEDIA_URL + unicode(transcoded.file), 'mime_type': media.mime_type})
+ 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
media.set_mime_type()
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="course")
courses = get_courses(request.user)
media = Media.objects.get(id=pk)
if get_access(media, courses):
- media_path = media.item.file.path
+ 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.")
--- /dev/null
+# -*- 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')
+
--- /dev/null
+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
+
-# -*- 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):