Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions pythonpro/cohorts/admin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
from django.contrib import admin
from django.utils.safestring import mark_safe

from pythonpro.cohorts.models import Cohort
from pythonpro.cohorts.models import Cohort, LiveClass


class ClassInline(admin.TabularInline):
extra = 1
model = LiveClass


@admin.register(Cohort)
class ModuleAdmin(admin.ModelAdmin):
list_display = 'title start end'.split()
inlines = [ClassInline]
prepopulated_fields = {'slug': ('title',)}
list_display = 'title start end page_link'.split()
ordering = ('-start',)

def page_link(self, cohort):
return mark_safe(f'<a href="{cohort.get_absolute_url()}">See on Page</a>')

page_link.short_description = 'page'
12 changes: 11 additions & 1 deletion pythonpro/cohorts/facade.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
from pythonpro.cohorts.models import Cohort as _Cohort
from django.db.models import Prefetch

from pythonpro.cohorts.models import Cohort as _Cohort, LiveClass


def get_all_cohorts_desc():
return tuple(_Cohort.objects.order_by('-start'))


def find_cohort(slug):
return _Cohort.objects.filter(slug=slug).prefetch_related(Prefetch(
'liveclass_set',
queryset=LiveClass.objects.order_by('start'),
to_attr='classes'
)).get()
23 changes: 23 additions & 0 deletions pythonpro/cohorts/migrations/0002_liveclass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 2.0.6 on 2018-06-04 17:53

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('cohorts', '0001_initial'),
]

operations = [
migrations.CreateModel(
name='LiveClass',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('start', models.DateTimeField()),
('vimeo_id', models.CharField(blank=True, max_length=11)),
('cohort', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cohorts.Cohort')),
],
),
]
6 changes: 6 additions & 0 deletions pythonpro/cohorts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ def get_absolute_url(self):
class CohortStudent(models.Model):
cohort = models.ForeignKey(Cohort, on_delete=models.DO_NOTHING)
user = models.ForeignKey(get_user_model(), on_delete=models.DO_NOTHING)


class LiveClass(models.Model):
start = models.DateTimeField()
vimeo_id = models.CharField(max_length=11, db_index=False, blank=True)
cohort = models.ForeignKey(Cohort, models.CASCADE)
23 changes: 22 additions & 1 deletion pythonpro/cohorts/templates/cohorts/cohort_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,28 @@ <h2 class="mt-5">Intruções</h2>
<dt>Passo 2</dt>
<dd>Se apresente no <a href="{{ cohort.forum_post }}" target="_blank">post do fórum</a></dd>
<dt>Passo 3</dt>
<dd>Entre no nosso <a href="https://t.me/joinchat/DZ2HMkC_wRSHCm5YwIM1UQ" target="_blank">grupo do Telegram</a> para tirar dúvidas e interagir!</dd>
<dd>Entre no nosso <a href="https://t.me/joinchat/DZ2HMkC_wRSHCm5YwIM1UQ" target="_blank">grupo do
Telegram</a> para tirar dúvidas e interagir!
</dd>
</div>
</div>
<div class="row">
<div class="col">
<h2 class="mt-3">Aulas ao Vivo</h2>
{% for class in cohort.classes %}
<dt>{{ class.start }}</dt>
<dd>
{% if class.vimeo_id %}
<div class="embed-container mb-3">
<iframe src="https://player.vimeo.com/video/{{ class.vimeo_id }}" width="640"
height="360" frameborder="0"
webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
{% else %}
Upload de Vídeo Pendente
{% endif %}
</dd>
{% endfor %}
</div>
</div>
</div>
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import operator
from datetime import datetime, timedelta
from os import path

import pytest
Expand All @@ -7,7 +9,8 @@
from model_mommy import mommy

from pythonpro import settings
from pythonpro.cohorts.models import Cohort
from pythonpro.cohorts import facade
from pythonpro.cohorts.models import Cohort, LiveClass
from pythonpro.django_assertions import dj_assert_contains, dj_assert_not_contains

_img_path = path.join(settings.BASE_DIR, 'pythonpro', 'core', 'static', 'img', 'instructors', 'renzo-nuccitelli.png')
Expand Down Expand Up @@ -82,3 +85,33 @@ def test_cohort_start(cohort: Cohort, resp):

def test_cohort_end(cohort: Cohort, resp):
dj_assert_contains(resp, date(cohort.end))


@pytest.fixture
def live_classes(cohort):
now = datetime.now()
return [
mommy.make(LiveClass, cohort=cohort, vimeo_id=str(i), start=now + timedelta(days=i)) for i in range(100, 105)
]


@pytest.fixture
def resp_with_classes(live_classes, cohort, client):
assert len(live_classes) > 0
return client.get(reverse('cohorts:detail', kwargs={'slug': cohort.slug}), secure=True)


def test_live_classes_are_sorted(live_classes: list, cohort):
live_classes.sort(key=operator.attrgetter('start'))
db_cohort = facade.find_cohort(slug=cohort.slug)
assert live_classes == db_cohort.classes


def test_live_classes_datetime(resp_with_classes, live_classes):
for live_class in live_classes:
dj_assert_contains(resp_with_classes, date(live_class.start))


def test_live_classes_vimeo(resp_with_classes, live_classes):
for live_class in live_classes:
dj_assert_contains(resp_with_classes, live_class.vimeo_id)
5 changes: 2 additions & 3 deletions pythonpro/cohorts/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from django.contrib.auth.decorators import login_required
from django.shortcuts import render

# Create your views here.
from pythonpro.cohorts.models import Cohort
from pythonpro.cohorts import facade


@login_required
def detail(request, slug):
return render(request, 'cohorts/cohort_detail.html', {'cohort': Cohort.objects.get(slug=slug)})
return render(request, 'cohorts/cohort_detail.html', {'cohort': facade.find_cohort(slug=slug)})
32 changes: 20 additions & 12 deletions pythonpro/modules/admin.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
from django.contrib import admin
from django.utils.safestring import mark_safe
from ordered_model.admin import OrderedModelAdmin

from pythonpro.modules.models import Section, Module, Chapter, Topic


class ModuleAdmin(OrderedModelAdmin):
list_display = 'title slug order move_up_down_links'.split()
class BaseAdmin(OrderedModelAdmin):
prepopulated_fields = {'slug': ('title',)}

def page_link(self, content):
return mark_safe(f'<a href="{content.get_absolute_url()}">See on Page</a>')

class SectionAdmin(OrderedModelAdmin):
list_display = 'title slug module order move_up_down_links'.split()
page_link.short_description = 'page'


class ChapterAdmin(OrderedModelAdmin):
list_display = 'title slug section order move_up_down_links'.split()
@admin.register(Module)
class ModuleAdmin(BaseAdmin):
list_display = 'title slug order move_up_down_links page_link'.split()


class TopicAdmin(OrderedModelAdmin):
list_display = 'title slug chapter order move_up_down_links'.split()
@admin.register(Section)
class SectionAdmin(BaseAdmin):
list_display = 'title slug module order move_up_down_links page_link'.split()


admin.site.register(Module, ModuleAdmin)
admin.site.register(Section, SectionAdmin)
admin.site.register(Chapter, ChapterAdmin)
admin.site.register(Topic, TopicAdmin)
@admin.register(Chapter)
class ChapterAdmin(BaseAdmin):
list_display = 'title slug section order move_up_down_links page_link'.split()


@admin.register(Topic)
class TopicAdmin(BaseAdmin):
list_display = 'title slug chapter order move_up_down_links page_link'.split()