Skip to content

Commit

Permalink
Merge pull request #268 from EsupPortail/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
ptitloup authored Jun 12, 2020
2 parents cd4fd60 + ca479d1 commit de9ec91
Show file tree
Hide file tree
Showing 47 changed files with 7,057 additions and 2,505 deletions.
14 changes: 13 additions & 1 deletion pod/authentication/apps.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
from django.apps import AppConfig
from django.db.models.signals import post_migrate
from django.core.exceptions import ObjectDoesNotExist


def set_default_site(sender, **kwargs):
def create_groupsite_if_not_exists(g):
from pod.authentication.models import GroupSite
try:
GroupSite.objects.get(group=g)
except ObjectDoesNotExist:
GroupSite.objects.create(group=g)


def set_default_site(sender, **kwargs):
from pod.authentication.models import Owner
from django.contrib.sites.models import Site
from django.contrib.auth.models import Group
from pod.authentication.models import GroupSite
for g in Group.objects.all():
create_groupsite_if_not_exists(g)
for gs in GroupSite.objects.all():
if len(gs.sites.all()) == 0:
gs.sites.add(Site.objects.get_current())
Expand Down
7 changes: 5 additions & 2 deletions pod/authentication/templates/authentication/login.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{% extends "base.html" %}
{% load i18n static %}

{% load i18n static custom_tags %}
{% block page_extra_head %}

{% endblock %}

{% block page_title %}{% trans 'Authentication' %}{% endblock %}

{% block page_content %}
{% get_setting "HIDE_LOCAL_LOGIN" default=False as local_login %}

<h2>{% trans 'Authentication' %}</h2>

<div class="text-center">
Expand All @@ -17,7 +18,9 @@ <h2>{% trans 'Authentication' %}</h2>
{% if USE_SHIB %}
<p><a class="btn btn-primary" href="{{SHIB_URL }}?target={{ referrer|urlencode }}" title="{{ SHIB_NAME }}">{{ SHIB_NAME}}</a></p>
{% endif %}
{% if not local_login %}
<p><a class="btn btn-primary" href="{% url 'local-login'%}?{% if request.GET.is_iframe %}is_iframe=true&{%endif%}next={{ referrer|urlencode }}" title="">{% trans "local sign on" %}</a></p>
{% endif %}
</div>

{% endblock %}
20 changes: 14 additions & 6 deletions pod/authentication/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
CAS_GATEWAY = getattr(
settings, 'CAS_GATEWAY', False)
SHIB_URL = getattr(
settings, 'SHIB_URL', "")
settings, 'SHIB_URL', "/idp/shibboleth.sso/Login")
SHIB_LOGOUT_URL = getattr(
settings, 'SHIB_LOGOUT_URL', "")

Expand All @@ -30,7 +30,8 @@ def authentication_login_gateway(request):
return redirect(next)

return render(request, 'authentication/login.html', {
'USE_CAS': USE_CAS, 'referrer': next
'USE_CAS': USE_CAS, 'USE_SHIB': USE_SHIB, "SHIB_URL": SHIB_URL,
'referrer': next
})
else:
def authentication_login_gateway(request):
Expand All @@ -50,25 +51,32 @@ def authentication_login(request):
return redirect(url)
elif USE_CAS or USE_SHIB:
return render(request, 'authentication/login.html', {
'USE_CAS': USE_CAS, 'referrer': referrer
'USE_CAS': USE_CAS, 'USE_SHIB': USE_SHIB, "SHIB_URL": SHIB_URL,
'referrer': referrer
})
else:
url = reverse('local-login')
url += '?%snext=%s' % (iframe_param, referrer)
return redirect(url)


def local_logout(request):
url = reverse('local-logout')
url += '?next=/'
return redirect(url)


def authentication_logout(request):
if request.user.is_anonymous():
return local_logout(request)
if request.user.owner.auth_type == "CAS":
return redirect(reverse('cas-logout'))
elif request.user.owner.auth_type == "Shibboleth":
auth.logout(request)
logout = SHIB_LOGOUT_URL + "?return=" + request.build_absolute_uri("/")
return redirect(logout)
else:
url = reverse('local-logout')
url += '?next=/'
return redirect(url)
return local_logout(request)


@csrf_protect
Expand Down
3 changes: 2 additions & 1 deletion pod/chapter/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.utils.safestring import mark_safe
from pod.chapter.models import Chapter
from pod.chapter.utils import vtt_to_chapter
from django.utils.translation import ugettext as _

if getattr(settings, 'USE_PODFILE', False):
FILEPICKER = True
Expand Down Expand Up @@ -57,7 +58,7 @@ def __init__(self, *args, **kwargs):
created_by=self.user)
else:
self.fields['file'].queryset = CustomFileModel.objects.all()
self.fields['file'].label = 'File to import'
self.fields['file'].label = _('File to import')

def clean_file(self):
msg = vtt_to_chapter(self.cleaned_data['file'], self.video)
Expand Down
2 changes: 1 addition & 1 deletion pod/chapter/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,4 @@ def sites(self):
return self.video.sites

def __str__(self):
return u'Chapter: {0} - video: {0}'.format(self.title, self.video)
return u'Chapter: {0} - video: {1}'.format(self.title, self.video)
12 changes: 12 additions & 0 deletions pod/live/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from django.conf import settings
from pod.live.models import Building
from pod.live.models import Broadcaster
from pod.main.forms import add_placeholder_and_asterisk
from django.utils.translation import ugettext_lazy as _

FILEPICKER = False
if getattr(settings, 'USE_PODFILE', False):
Expand Down Expand Up @@ -42,3 +44,13 @@ def clean(self):
class Meta(object):
model = Broadcaster
fields = '__all__'


class LivePasswordForm(forms.Form):
password = forms.CharField(
label=_('Password'),
widget=forms.PasswordInput())

def __init__(self, *args, **kwargs):
super(LivePasswordForm, self).__init__(*args, **kwargs)
self.fields = add_placeholder_and_asterisk(self.fields)
19 changes: 19 additions & 0 deletions pod/live/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from select2 import fields as select2_fields
from django.dispatch import receiver
from django.db.models.signals import post_save
from django.urls import reverse

if getattr(settings, 'USE_PODFILE', False):
from pod.podfile.models import CustomImageModel
Expand Down Expand Up @@ -76,13 +77,31 @@ class Broadcaster(models.Model):
blank=True,
null=True,
verbose_name=_('Video on hold'))
iframe_url = models.URLField(_('Embedded Site URL'), help_text=_(
'Url of the embedded site to display'), null=True, blank=True)
iframe_height = models.IntegerField(
_('Embedded Site Height'), null=True, blank=True, help_text=_(
'Height of the embedded site (in pixels)'))
status = models.BooleanField(default=0, help_text=_(
'Check if the broadcaster is currently sending stream.'))
is_restricted = models.BooleanField(
verbose_name=_(u'Restricted access'),
help_text=_(
'Live is accessible only to authenticated users.'),
default=False)
public = models.BooleanField(
verbose_name=_(u'Show in live tab'),
help_text=_(
'Live is accessible from the Live tab'),
default=True)
password = models.CharField(
_('password'),
help_text=_(
'Viewing this live will not be possible without this password.'),
max_length=50, blank=True, null=True)

def get_absolute_url(self):
return reverse('live:video_live', args=[str(self.slug)])

def __str__(self):
return "%s - %s" % (self.name, self.url)
Expand Down
35 changes: 35 additions & 0 deletions pod/live/templates/live/live-form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{% load i18n %}

<p>{% trans 'This live is protected by password, please fill in and click send.' %}</p>
<form method="post" action="{{ request.get_full_path }}" id="live_password_form" class='needs-validation' novalidate>
{% csrf_token %}
<div class="list-group">
<fieldset>
<legend>{% trans 'Password required' %}</legend>
{% if form.errors %}
<p class="text-danger">{% trans "One or more errors have been found in the form." %}</p>
{% endif %}
{% for field_hidden in form.hidden_fields %}
{{field_hidden}}
{% endfor %}
{% for field in form.visible_fields %}
{% spaceless %}
<div class="list-group-item">
<div class="form-group {% if field.field.required %}form-group-required {%endif%}" >
{{ field.errors }}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
{% if field.help_text %}
<small id="{{field.id_for_label}}Help" class="form-text text-muted">{{ field.help_text|safe }}</small>
{% endif %}
{% if field.field.required %}<div class="invalid-feedback">{% trans "Please provide a valid value for this field" %}.</div>{%endif%}
</div>
</div>
{% endspaceless %}
{% endfor %}
<div class="text-center mt-1">
<button type="submit" class="btn btn-primary">{% trans "Send" %}</button>
</div>
</fieldset>
</div>
</form>
58 changes: 49 additions & 9 deletions pod/live/templates/live/live.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,18 @@
{% block page_title %}{% trans "Lives" %}{% endblock %}

{% block page_content %}


{% if form %}
{% include 'live/live-form.html' %}
{% else %}


<h3><i data-feather="airplay"></i>&nbsp;{{broadcaster.name}}</h3>




{% if broadcaster.video_on_hold.is_video %}
<div id="divvideoonhold" style="display: block;">
<video id="podvideoonholdplayer" class="video-js vjs-default-skin{% if request.GET.is_iframe %} vjs-16-9{% endif %} vjs-big-play-centered" controls height="360" muted autoplay>
Expand All @@ -45,6 +55,18 @@ <h3><i data-feather="airplay"></i>&nbsp;{{broadcaster.name}}</h3>

<p>{{ broadcaster.description|safe }}</p>

{% if broadcaster.iframe_url != "" and broadcaster.iframe_url != None %}
<iframe id="inlineFrameExample" style="padding: 0; margin: 0; border:0; width: 100%;"
title="Inline Frame Example"
height="{{broadcaster.iframe_height}}"
src="{{broadcaster.iframe_url}}">
</iframe>
{% endif %}


{%endif%}


{% endblock page_content %}

{% block page_aside %}
Expand All @@ -59,9 +81,9 @@ <h5 class="card-title pl-2">
</p>
{% endif %}
{% for otherbroadcaster in broadcaster.building.broadcaster_set.all%}
{% if otherbroadcaster != broadcaster %}
{% if otherbroadcaster != broadcaster and otherbroadcaster.public %}
<p class="card-text">
{%if otherbroadcaster.status %}<a href="{% url "live:video_live" id=otherbroadcaster.id %}" class="live_on"><i data-feather="airplay"></i>&nbsp;{{otherbroadcaster.name}}</a>
{%if otherbroadcaster.status %}<a href="{% url "live:video_live" slug=otherbroadcaster.slug %}" class="live_on">{%if otherbroadcaster.password%}<i data-feather="lock"></i>{%else%}<i data-feather="airplay"></i>{%endif%}</i>&nbsp;{{otherbroadcaster.name}}</a>
{%else%}<span class="live_off"><i data-feather="airplay"></i>&nbsp;{{otherbroadcaster.name}} ({% trans "no broadcast in progress" %})</span>{%endif%}</p>
{% endif %}
{% empty %}
Expand All @@ -88,6 +110,8 @@ <h5 class="card-title pl-2">
// Number of loop until we are sure the live is stopped
// See video state (cf. https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState)
var nbLoop = 0;
// Live seems stopped
var stopped = false;

//videojs.options.flash.swf = "video-js.swf"
var options = {
Expand All @@ -108,13 +132,29 @@ <h5 class="card-title pl-2">
// Reset counter if video state is ok
if (started && player.readyState() > 2) { nbLoop = 0; }
if (started && player.readyState() <= 2) {
nbLoop = nbLoop + 1;
// We're waiting a bit to make sure it's not a network / data flow issue...
if (debug) { console.info("The streaming live stopped ? Video state : " + player.readyState() + ". It's been " + nbLoop + " times that there is no more video stream. After 4, we stop."); }
if (nbLoop > 3) {
// Display of a message of end of live and reload of the page in 9 seconds
let modal = player.createModal('{% trans "Thank you for watching this streaming live with us. The page will reload automatically within a few seconds to display the video on hold." %}');
setTimeout(function(){ location.reload(); }, 9000);
// Check if .m3u8 exists, to be sure that live is stopped
$.ajax({ url: '{{broadcaster.url}}',
type : 'GET',
crossDomain: true,
dataType : 'html',
success: function(html, status){
stopped = false;
},
error : function(result, status, error){
stopped = true;
},
complete : function(result, status){
}
});
if (stopped) {
nbLoop = nbLoop + 1;
// We're waiting a bit to make sure it's not a network / data flow issue...
if (debug) { console.info("The streaming live stopped ? Video state : " + player.readyState() + ". It's been " + nbLoop + " times that there is no more video stream. After 4 times, we stop."); }
if (nbLoop > 3) {
// Display of a message of end of live and reload of the page in 9 seconds
let modal = player.createModal('{% trans "Thank you for watching this streaming live with us. The page will reload automatically within a few seconds to display the video on hold." %}');
setTimeout(function(){ location.reload(); }, 9000);
}
}
}
return options;
Expand Down
6 changes: 3 additions & 3 deletions pod/live/templates/live/lives.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ <h3><i data-feather="radio"></i>&nbsp;{% trans "Lives" %}</h3>
<img class="card-img-top" src="{{building.get_headband_url}}" alt="{{building.name}}">
<div class="card-body">
<h5 class="card-title">{{building.name}}</h5>
{% for broadcaster in building.broadcaster_set.all%}
{% for broadcaster in building.broadcaster_set.all %}
<p class="card-text">
{%if broadcaster.status %}<a href="{% url "live:video_live" id=broadcaster.id %}" class="live_on"><i data-feather="airplay"></i>&nbsp;{{broadcaster.name}}</a>
{%else%}<span class="live_off"><i data-feather="airplay"></i>&nbsp;{{broadcaster.name}} ({% trans "no broadcast in progress" %})</span>{%endif%}</p>
{%if broadcaster.status %}<a href="{% url "live:video_live" slug=broadcaster.slug %}" class="live_on">{%if broadcaster.password%}<i data-feather="lock"></i>{%else%}<i data-feather="airplay"></i>{%endif%}&nbsp;{{broadcaster.name}} </a>
{%else%}<span class="live_off"><i data-feather="airplay"></i>&nbsp;{{broadcaster.name}} ({% trans "no broadcast in progress" %})</span>{%endif%}</p>
{% empty %}
<p class="card-text">{% trans "Sorry, no lives found" %}.</p>
{% endfor %}
Expand Down
Empty file added pod/live/tests/__init__.py
Empty file.
14 changes: 12 additions & 2 deletions pod/live/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ def setUp(self):
url="http://test.live",
status=True,
is_restricted=True,
building=building)
building=building,
iframe_url="http://iframe.live",
iframe_height=120,
public=False)
# Test with a video on hold
video_on_hold = Video.objects.create(
title="VideoOnHold", owner=user, video="test.mp4",
Expand All @@ -99,7 +102,10 @@ def setUp(self):
status=True,
is_restricted=False,
video_on_hold=video_on_hold,
building=building)
building=building,
iframe_url="http://iframe2.live",
iframe_height=140,
password="mot2passe")
print(" ---> SetUp of BroadcasterTestCase : OK !")

"""
Expand All @@ -111,13 +117,17 @@ def test_attributs(self):
self.assertEqual(broadcaster.name, "broadcaster1")
self.assertTrue("blabla" in broadcaster.poster.name)
self.assertEqual(broadcaster.url, "http://test.live")
self.assertEqual(broadcaster.iframe_url, "http://iframe.live")
self.assertEqual(broadcaster.iframe_height, 120)
self.assertEqual(broadcaster.status, True)
self.assertEqual(broadcaster.public, False)
self.assertEqual(broadcaster.is_restricted, True)
self.assertEqual(broadcaster.building.id, 1)
self.assertEqual(broadcaster.__str__(), "%s - %s" %
(broadcaster.name, broadcaster.url))
broadcaster2 = Broadcaster.objects.get(id=2)
self.assertEqual(broadcaster2.video_on_hold.id, 1)
self.assertEqual(broadcaster2.password, "mot2passe")
print(
" ---> test_attributs of BroadcasterTestCase : OK !")

Expand Down
Loading

0 comments on commit de9ec91

Please sign in to comment.