from .models.core import (Conference, Course, CourseType, Department, Document,
DocumentSimple, DocumentType, LiveStream, Media,
MediaTranscoded, Organization, Period, Professor,
- Room, StreamingServer)
+ Room, StreamingServer, ConferencePublication)
from .models.crfpa import (IEJ, Corrector, Discount, Home, NewsItem,
OptionalFee, Parameters, Payback, Payment, Profile,
Student, Training)
model = Media
exclude = ['readers', ]
+class ConferenceInline(admin.StackedInline):
+ model = ConferencePublication
+
@admin.action(description='Publish selected conferences')
def publish_conferences(modeladmin, request, queryset):
for conference in queryset:
class ConferenceAdmin(admin.ModelAdmin):
- inlines = [MediaInline,]
+ inlines = [MediaInline, ConferenceInline]
exclude = ['readers']
list_per_page = 30
list_filter = ('course', 'period', 'date_begin', 'session', 'course_type')
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from django.urls import reverse
-from teleforma.models.core import Conference, Period
+from teleforma.models.core import Conference, ConferencePublication, Period
from teleforma.models.crfpa import Student
from teleforma.models.notification import notify
from teleforma.views.core import get_courses
now_plus = now + datetime.timedelta(minutes=minute_high_range)
publications = list(Conference.objects.filter(
+ period=period,
+ status=2,
+ notified=False,
+ date_publish__lte=now_plus,
+ date_publish__gte=now_minus,
+ )) + list(ConferencePublication.objects.filter(
period=period,
status=2,
notified=False,
for publication in publications:
- conference = publication
+ if type(publication) == ConferencePublication:
+ conference = publication.conference
+ else:
+ conference = publication
medias = conference.media.all()
--- /dev/null
+# Generated by Django 3.2.25 on 2024-09-25 09:29
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('teleforma', '0011_auto_20240311_2202'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='student',
+ name='confirmation_sent',
+ field=models.BooleanField(default=False, verbose_name='confirmation sent'),
+ ),
+ migrations.AlterField(
+ model_name='student',
+ name='is_subscribed',
+ field=models.BooleanField(default=False, verbose_name='subscribed'),
+ ),
+ migrations.CreateModel(
+ name='ConferencePublication',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('date_publish', models.DateTimeField(blank=True, null=True, verbose_name='publishing date')),
+ ('status', models.IntegerField(choices=[(0, 'Hidden'), (1, 'Private'), (2, 'Draft'), (3, 'Public')], default=2, verbose_name='status')),
+ ('notified', models.BooleanField(default=False, verbose_name='notified')),
+ ('conference', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='publications', to='teleforma.conference', verbose_name='conference')),
+ ('period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teleforma.period', verbose_name='period')),
+ ],
+ ),
+ ]
db_table = app_label + '_' + 'room'
verbose_name = _('room')
+class ConferencePublication(models.Model):
+ conference = models.ForeignKey('Conference', related_name='publications', verbose_name=_('conference'),
+ on_delete=models.CASCADE)
+ period = models.ForeignKey('Period', verbose_name=_('period'),
+ on_delete=models.CASCADE)
+ date_publish = models.DateTimeField(_('publishing date'), null=True, blank=True)
+ status = models.IntegerField(
+ _('status'), choices=STATUS_CHOICES, default=2)
+ notified = models.BooleanField(_('notified'), default=False)
class Conference(models.Model):
@property
def description(self):
return str(self)
+
+ @property
+ def session_as_int(self):
+ try:
+ return int(self.session)
+ except ValueError:
+ return 0
@property
def slug(self):
str(self.date_begin)]
return ' - '.join(list)
- @property
- def slug(self):
- slug = '-'.join([self.course.department.slug,
- self.course.slug,
- self.course_type.name.lower()])
- return slug
-
def save(self, *args, **kwargs):
if not self.public_id:
self.public_id = get_random_hash()
self.web_class_group = WebClassGroup.objet.get(
name=data['web_class_group'])
+ def video(self):
+ """
+ get media video
+ """
+ try:
+ videos = self.media.filter(type='mp4')
+ if videos:
+ return videos[0]
+ except Media.DoesNotExist:
+ try:
+ return self.media.filter(type='webm')[0]
+ except Media.DoesNotExist:
+ pass
+ return None
+
+ def publication_info(self, period):
+ """
+ Get publication info according to period.
+ """
+ publication = self.publications.filter(period=period).first()
+ if not publication and self.period == period:
+ publication = self
+ elif not publication:
+ return None
+
+ return {
+ 'status': publication.status,
+ 'published': publication.status == 3,
+ 'publication_date': publication.date_publish,
+ 'notified': publication.notified
+ }
class Meta(MetaCore):
db_table = app_label + '_' + 'conference'
verbose_name = _('conference')
{% load teleforma_tags %}
{% load i18n %}
-{% with course.conference.all|from_course_type:type|streaming_only as conferences %}
-{% if conferences|from_periods:period %}
+{% course_ingoing_conferences as conferences %}
+
+{% if conferences %}
<div class="course_content content_video">
<div class="course_subtitle">
<h3><img src="/static/teleforma/images/item_title.png" width="10px" alt="" /> {% trans "Live conferences"%}</h3>
</div>
<table class="listing" width="100%">
<tbody>
- {% for conference in conferences|from_periods:period %}
+ {% for conference in conferences %}
{% for stream in conference.livestream.all %}
{% if stream.stream_type == 'webm' %}
<tr>
{% if stream.streaming %}
<td {% if forloop.first %}class="border-top"{% endif %} width="230px">
<a href="{% url 'teleforma-conference-detail' period.id stream.conference.id %}" title="{% trans "View" %}">
- <img id="snapshot-{{ stream.course.code }}-{{ stream.course_type }}" src="{{ stream.snapshot_url }}" width="100%" alt="{% trans 'Click here' %}" />
+ <img src="/static/teleforma/images/play_168.png" width="100%" style="background: black;" alt="{% trans 'Click here' %}" />
</a>
</td>
<td {% if forloop.first %}class="border-top"{% endif %} width="60%" style="padding-left: 1em;">
<dt>{% trans "Title" %}</dt><dd>{{ stream.conference.course.title }}</dd>
<dt>{% trans "Session" %}</dt><dd>{{ stream.conference.session }}</dd>
{% if stream.conference.professor.user.username %}
- <dt>{% trans "Professor" %}</dt><dd><a href="{% url 'teleforma-profile-detail' stream.conference.professor.user.username %}" target="_blank">{{ stream.conference.professor }}</a></dd>
+ <dt>{% trans "Professor" %}</dt><dd>{{ stream.conference.professor }}</dd>
{% endif %}
<dt>{% trans "Begin" %}</dt><dd>{{ stream.conference.date_begin }}</dd>
</dl>
</tr>
{% endif %}
{% endfor %}
- {% endfor %}
+ {% endfor %}
</tbody>
</table>
</div>
{% endif %}
-{% endwith %}
{% load thumbnail %}
{% load i18n %}
-{% if course.media.all|from_course_type:type %}
+{% course_past_conferences as all_conferences %}
+
+{% if all_conferences %}
<div class="course_content content_video">
<div class="course_subtitle">
- <h3><img src="/static/teleforma/images/item_title.png" width="10px" alt="" /> {% trans title %}</h3>
+ <h3><img src="/static/teleforma/images/item_title.png" width="10px" alt="" /> {% trans "Conférences en différé" %}</h3>
</div>
<table class="listing" width="100%">
<tbody>
- {% for media in course.media.all|from_course_type:type|from_periods:period %}
- {% if media.is_published or user.is_staff and not list_view %}
- {% if media.type == 'webm' or media.type == 'mp4' %}
+ {% for conference in all_conferences %}
+ {% if conference.video %}
<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.poster_file %}
- {% thumbnail media.poster_file "168x96" as im %}
+ <a href="{% url 'teleforma-media-detail' period.id conference.video.id %}" title="{% trans "Play" %}">
+ {% if conference.video.poster_file %}
+ {% thumbnail conference.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_URL }}teleforma/images/play_168.png" width="100%" alt="{% trans 'Click here' %}" />
+ <img src="/static/teleforma/images/play_168.png" width="100%" alt="{% trans 'Click here' %}" />
</div>
{% endthumbnail %}
{% else %}
- {% trans 'Click here' %}
+ <div>{% trans 'Click here' %}</div>
{% endif %}
+ {% comment %}<div>{% trans 'Click here' %}</div>{% endcomment %}
</a>
</td>
+ {% conference_publication conference as publication %}
<td {% if forloop.first %}class="border-top"{% endif %} width="60%" style="padding-left: 1em;">
<div>
<dl class="listing" style="font-size: 1.2em;">
- <dt>{% trans "Title" %}</dt><dd>{{ media.conference.course.title }}</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>
+ <dt>{% trans "Title" %}</dt><dd>{{ conference.course.title }}</dd>
+ <dt>{% trans "Session" %}</dt><dd>{{ conference.session }}</dd>
+ {% if conference.professor %}
+ <dt>{% trans "Professor" %}</dt><dd>{{ conference.professor }}</dd>
+ {% endif %}
+ {% if conference.streaming %}
+ <dt>{% trans "Begin date" %}</dt><dd>{{ conference.date_begin }}</dd>
+ {% else %}
+ <dt>{% trans "Publishing date" %}</dt><dd>{{ publication.publication_date }}</dd>
{% endif %}
- <dt>{% trans "Begin" %}</dt><dd>{{ media.conference.date_begin }}</dd>
- {% if media.conference.comment %}
- <dt>{% trans "Comment" %}</dt><dd>{{ media.conference.comment }}</dd>
+ {% if conference.duration %}
+ <dt>{% trans "Duration" %}</dt><dd>{{ conference.duration }}</dd>
+ {% endif %}
+ {% if conference.comment %}
+ <dt>{% trans "Comment" %}</dt><dd>{{ conference.comment }}</dd>
{% endif %}
</dl>
</div>
</td>
+
<td {% if forloop.first %}class="border-top"{% endif %} width="10%" align="center">
- {% if media.is_published and user.is_staff %}
- <img src="/static/teleforma/images/ok.png" style="vertical-align:middle" alt="" title="{% trans ' published' %}" />
- {% elif not media.is_published and user.is_staff %}
- <img src="/static/teleforma/images/delete.png" style="vertical-align:middle" alt="" title="{% trans ' rejected' %}" />
+ {% if user.is_staff or user.professor.count %}
+ {% if publication.published %}
+ <img src="/static/teleforma/images/ok.png" style="vertical-align:middle" alt="" title="{% trans ' published' %}" />
+ {% else %}
+ <img src="/static/teleforma/images/delete.png" style="vertical-align:middle" alt="" title="{% trans ' rejected' %}" />
+ {% endif %}
{% endif %}
- {% 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 %}">
+ {% if conference.video.file %}
+ {% if not "video" in conference.video.mime_type or request.user_agent.os.family == 'iOS' %}
+ <a href="{% url 'teleforma-media-download' period.id conference.video.id %}">
<img src="/static/teleforma/images/download_media.png" style="vertical-align:middle" alt="" title="{% trans "Download" %}" />
</a>
{% endif %}
</td>
</tr>
{% endif %}
- {% endif %}
{% endfor %}
</tbody>
</table>
from docutils.core import publish_parts
from teleforma.models.chat import ChatMessage
+from teleforma.views.core import get_course_conferences
from ..exam.models import Quota, Script
from ..models.core import Document, Professor
'user_id': context.request.user.id
}
}
+
+@register.simple_tag(takes_context=True)
+def course_ingoing_conferences(context):
+ course = context['course']
+ confs = course.conference.filter(streaming=True,
+ period=context['period'],
+ course_type=context['type'])
+ return list(confs)
+
+@register.simple_tag(takes_context=True)
+def course_past_conferences(context):
+ user = context['user']
+ if user.is_staff or user.professor.count():
+ status_min = 2
+ else:
+ status_min = 3
+ course = context['course']
+ period = context['period']
+ course_type = context['type']
+ return get_course_conferences(period, course, course_type, status_min=status_min)
+
+@register.simple_tag(takes_context=True)
+def conference_publication(context, conference):
+ period = context['period']
+ return conference.publication_info(period)
return get_ae_courses(user, date_order, num_order, period)
+def get_trainings(user):
+ trainings = []
+
+ if not user.is_authenticated:
+ return trainings
+
+ professor = user.professor.all()
+ student = user.student.all()
+ quotas = user.quotas.all()
+
+ if professor or quotas or user.is_staff:
+ trainings = Training.objects.filter(available=True)
+
+ elif student:
+ student = user.student.get()
+ trainings = student.trainings.all()
+ return trainings
+
+
+
+def get_course_conferences(period, course, course_type, status_min=3):
+ conferences = []
+ already_added = set()
+
+ periods = [period,]
+
+ # get conference publications
+ publications = ConferencePublication.objects.filter(
+ period__in=periods,
+ conference__course=course,
+ conference__course_type=course_type,
+ status__gte=status_min).distinct()
+ for publication in publications:
+ conferences.append(publication.conference)
+ already_added.add(publication.conference.id)
+
+ cc = Conference.objects.filter(period__in=periods,
+ course=course,
+ course_type=course_type,
+ status__gte=status_min).distinct()
+
+ for conference in cc:
+ # do not include conferences with publication rules
+ if conference.id not in already_added:
+ conferences.append(conference)
+ conferences = sorted(conferences, key=lambda c:-c.session_as_int)
+ return conferences
+
+
+
def stream_from_file(__file):
chunk_size = 0x10000
f = open(__file, 'r')