Merge branch 'master' of https://gitlab.com/lilcity/backend into hotfix/lil-576

remotes/origin/hotfix/LIL-661
gzbender 8 years ago
commit 32e426631a
  1. 8
      apps/auth/forms.py
  2. 6
      apps/auth/views.py
  3. 7
      apps/course/models.py
  4. 2
      apps/course/templates/course/content/imagetext.html
  5. 8
      apps/course/templates/course/course.html
  6. 6
      apps/course/templates/course/course_only_lessons.html
  7. 5
      apps/course/templates/course/lesson.html
  8. 31
      apps/course/views.py
  9. 3
      apps/payment/models.py
  10. 7
      apps/payment/views.py
  11. 78
      apps/school/templates/blocks/_schedule_purchased_item.html
  12. 2
      apps/school/templates/blocks/open_lesson.html
  13. 69
      apps/school/templates/blocks/schedule.html
  14. 40
      apps/school/templates/blocks/schedule_item.html
  15. 4
      apps/school/templates/blocks/schedule_purchased.html
  16. 2
      apps/school/templates/school/livelessons_list.html
  17. 62
      apps/school/templates/school/schedules_print.html
  18. 23
      apps/school/templates/summer/schedule_purchased.html
  19. 43
      apps/school/views.py
  20. 87
      apps/user/templates/user/author_profile.html
  21. 2
      apps/user/templates/user/notification-settings.html
  22. 2
      apps/user/templates/user/payment-history.html
  23. 2
      apps/user/templates/user/profile-settings.html
  24. 24
      apps/user/templates/user/profile.html
  25. 46
      apps/user/views.py
  26. 21
      project/context_processors.py
  27. 1
      project/settings.py
  28. 2
      project/templates/blocks/about.html
  29. 4
      project/templates/blocks/header.html
  30. 4
      project/templates/blocks/popup_course_lock.html
  31. 74
      project/templates/blocks/promo.html
  32. 4
      project/templates/blocks/user_menu.html
  33. 7
      project/urls.py
  34. 2
      web/src/components/CourseRedactor.vue
  35. 11
      web/src/sass/_common.sass

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.contrib.auth.forms import AuthenticationForm
class LearnerRegistrationForm(forms.Form): class LearnerRegistrationForm(forms.Form):
@ -8,6 +9,7 @@ class LearnerRegistrationForm(forms.Form):
password = forms.CharField() password = forms.CharField()
class LoginForm(forms.Form): class AuthenticationForm(AuthenticationForm):
email = forms.CharField()
password = forms.CharField() def clean_username(self):
return self.cleaned_data.get('username', '').lower()

@ -7,7 +7,6 @@ from facepy import GraphAPI
from facepy.exceptions import FacepyError from facepy.exceptions import FacepyError
from django.contrib.auth import get_user_model, logout, login, views from django.contrib.auth import get_user_model, logout, login, views
from django.contrib.auth.forms import AuthenticationForm
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.http import JsonResponse from django.http import JsonResponse
from django.urls import reverse_lazy from django.urls import reverse_lazy
@ -20,7 +19,7 @@ from django.shortcuts import redirect
from apps.notification.utils import send_email from apps.notification.utils import send_email
from apps.config.models import Config from apps.config.models import Config
from .forms import LearnerRegistrationForm from .forms import LearnerRegistrationForm, AuthenticationForm
from .tokens import verification_email_token from .tokens import verification_email_token
User = get_user_model() User = get_user_model()
@ -33,7 +32,7 @@ class LearnerRegistrationView(FormView):
def form_valid(self, form): def form_valid(self, form):
first_name = form.cleaned_data['first_name'] first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name'] last_name = form.cleaned_data['last_name']
email = form.cleaned_data['email'] email = form.cleaned_data['email'].lower()
password = form.cleaned_data['password'] password = form.cleaned_data['password']
user, created = User.objects.get_or_create( user, created = User.objects.get_or_create(
@ -170,6 +169,7 @@ class FacebookLoginOrRegistration(View):
"errors": {"email": 'is field required'} "errors": {"email": 'is field required'}
}) })
else: else:
email = email.lower()
try: try:
user = User.objects.get(email=email) user = User.objects.get(email=email)
except User.DoesNotExist: except User.DoesNotExist:

@ -7,6 +7,7 @@ from django.utils.text import slugify
from django.utils.timezone import now from django.utils.timezone import now
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.conf import settings
from polymorphic_tree.models import PolymorphicMPTTModel, PolymorphicTreeForeignKey from polymorphic_tree.models import PolymorphicMPTTModel, PolymorphicTreeForeignKey
from project.mixins import BaseModel, DeactivatedMixin from project.mixins import BaseModel, DeactivatedMixin
@ -129,11 +130,11 @@ class Course(BaseModel, DeactivatedMixin):
@property @property
def deferred_start_at_humanize(self): def deferred_start_at_humanize(self):
return arrow.get(self.deferred_start_at).humanize(locale='ru') return arrow.get(self.deferred_start_at, settings.TIME_ZONE).humanize(locale='ru')
@property @property
def created_at_humanize(self): def created_at_humanize(self):
return arrow.get(self.created_at).humanize(locale='ru') return arrow.get(self.created_at, settings.TIME_ZONE).humanize(locale='ru')
@property @property
def is_deferred_start(self): def is_deferred_start(self):
@ -234,7 +235,7 @@ class Comment(PolymorphicMPTTModel, DeactivatedMixin):
@property @property
def created_at_humanize(self): def created_at_humanize(self):
return arrow.get(self.created_at).humanize(locale='ru') return arrow.get(self.created_at, settings.TIME_ZONE).humanize(locale='ru')
def __str__(self): def __str__(self):
return self.content return self.content

@ -9,7 +9,7 @@
<img class="lessons__pic" src="{{ content.img.image.url }}"> <img class="lessons__pic" src="{{ content.img.image.url }}">
</div> </div>
</div> </div>
<div class="lessons__content">{{ content.txt | safe }}</div> <div class="lessons__content">{{ content.txt | safe | linebreaks }}</div>
</div> </div>
</div> </div>

@ -70,7 +70,7 @@
</a> </a>
</div> </div>
<div class="course__title title">{{ course.title }}</div> <div class="course__title title">{{ course.title }}</div>
<div class="course__content">{{ course.short_description }}</div> <div class="course__content">{{ course.short_description | linebreaks }}</div>
<a href="{% url 'user' course.author.id %}"> <a href="{% url 'user' course.author.id %}">
<div class="course__user user"> <div class="course__user user">
{% if course.author.photo %} {% if course.author.photo %}
@ -158,13 +158,13 @@
{% else %} {% else %}
<a <a
class="course__action btn btn_lg{% if only_lessons %} btn_stroke{% else %} btn_gray{% endif %}" class="course__action btn btn_lg{% if only_lessons %} btn_stroke{% else %} btn_gray{% endif %}"
{% if paid %} {% if paid or not course.price %}
href="{% url 'course-only-lessons' course.id %}" href="{% url 'course-only-lessons' course.id %}"
{% else %} {% else %}
data-popup=".js-popup-course-lock" data-popup=".js-popup-course-lock"
{% endif %} {% endif %}
>УРОКИ >УРОКИ
{% if not paid %} {% if not paid and course.price %}
<svg class="icon icon-lock"> <svg class="icon icon-lock">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-lock"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-lock"></use>
</svg> </svg>
@ -270,7 +270,7 @@
</a> </a>
</div> </div>
<div class="course__title title">{{ course.title }}</div> <div class="course__title title">{{ course.title }}</div>
<div class="course__content">{{ course.short_description }}</div> <div class="course__content">{{ course.short_description | linebreaks }}</div>
<a href="{% url 'user' course.author.id %}"> <a href="{% url 'user' course.author.id %}">
<div class="course__user user user_white"> <div class="course__user user user_white">
{% if course.author.photo %} {% if course.author.photo %}

@ -25,7 +25,7 @@
</div> </div>
<div class="go__title">Вернуться</div> <div class="go__title">Вернуться</div>
</a> </a>
{% if not paid and course.price %} {% if not paid and course.price and not has_full_access %}
<a <a
class="go__btn btn{% if pending %} btn_gray{% endif %} btn_md" class="go__btn btn{% if pending %} btn_gray{% endif %} btn_md"
{% if user.is_authenticated %} {% if user.is_authenticated %}
@ -154,10 +154,10 @@
</a> </a>
{% else %} {% else %}
<a <a
href="{% if paid %}{% url 'course-only-lessons' course.id %}{% else %}#{% endif %}" href="{% if paid or not course.price %}{% url 'course-only-lessons' course.id %}{% else %}#{% endif %}"
class="course__action btn btn_lg{% if only_lessons %} btn_stroke{% else %} btn_gray{% endif %}" class="course__action btn btn_lg{% if only_lessons %} btn_stroke{% else %} btn_gray{% endif %}"
>УРОКИ >УРОКИ
{% if not paid %} {% if not paid and course.price %}
<svg class="icon icon-lock"> <svg class="icon icon-lock">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-lock"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-lock"></use>
</svg> </svg>

@ -98,6 +98,7 @@
<div class="questions"> <div class="questions">
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<form class="questions__form" method="post" action="{% url 'lessoncomment' lesson_id=lesson.id %}"> <form class="questions__form" method="post" action="{% url 'lessoncomment' lesson_id=lesson.id %}">
<input type="hidden" name="reply_id">
<div class="questions__ava ava"> <div class="questions__ava ava">
<img <img
class="ava__pic" class="ava__pic"
@ -109,6 +110,10 @@
> >
</div> </div>
<div class="questions__wrap"> <div class="questions__wrap">
<div class="questions__reply-info">В ответ на
<a href="" class="questions__reply-anchor">этот комментарий</a>.
<a href="#" class="questions__reply-cancel grey-link">Отменить</a>
</div>
<div class="questions__field"> <div class="questions__field">
<textarea class="questions__textarea" placeholder="Спросите автора курса интересующие вас вопросы"></textarea> <textarea class="questions__textarea" placeholder="Спросите автора курса интересующие вас вопросы"></textarea>
</div> </div>

@ -189,9 +189,13 @@ class CourseView(DetailView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs) response = super().get(request, *args, **kwargs)
context = self.get_context_data() context = self.get_context_data()
if (not request.user.is_authenticated and self.object.status != Course.PUBLISHED) or\
(request.user.is_authenticated and request.user.role < User.AUTHOR_ROLE and self.object.author != request.user and self.only_lessons and not context['paid']): # если это не админ или автор
raise Http404 if not context.get('has_full_access'):
# если это не опубл курс или это страница уроков, курс платный, а юзер не оплатил курс - 404
if (self.object.status != Course.PUBLISHED) or \
(self.only_lessons and self.object.price and not context.get('paid')):
raise Http404
return response return response
# ((self.object.status != Course.PUBLISHED and request.user.role != User.ADMIN_ROLE) or # ((self.object.status != Course.PUBLISHED and request.user.role != User.ADMIN_ROLE) or
@ -216,6 +220,9 @@ class CourseView(DetailView):
context['only_lessons'] = self.only_lessons context['only_lessons'] = self.only_lessons
if self.only_lessons: if self.only_lessons:
context['lessons'] = self.object.lessons.order_by('position') context['lessons'] = self.object.lessons.order_by('position')
context['is_owner'] = self.object.author == self.request.user
context['is_admin'] = self.request.user.role == User.ADMIN_ROLE
context['has_full_access'] = context['is_owner'] or context['is_admin']
return context return context
def get_queryset(self): def get_queryset(self):
@ -292,10 +299,20 @@ class LessonView(DetailView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs) response = super().get(request, *args, **kwargs)
if (self.object.course.status != Course.PUBLISHED and not paid = request.user.is_authenticated and self.object.course.payments.filter(
(request.user.role == User.ADMIN_ROLE or user=self.request.user,
self.object.course.author == request.user)): status__in=[
raise Http404 Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
).exists()
# если это не автор или админ
if not (request.user.is_authenticated and
(request.user.role == User.ADMIN_ROLE or self.object.course.author == request.user)):
# если курс не опубликован или он платный и не оплачен - 404
if self.object.course.status != Course.PUBLISHED or (self.object.course.price and not paid):
raise Http404
return response return response
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):

@ -9,6 +9,7 @@ from django.contrib.auth import get_user_model
from django.contrib.postgres.fields import ArrayField, JSONField from django.contrib.postgres.fields import ArrayField, JSONField
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.utils.timezone import now from django.utils.timezone import now
from django.conf import settings
from project.utils import weekday_in_date_range from project.utils import weekday_in_date_range
@ -198,4 +199,4 @@ class SchoolPayment(Payment):
@property @property
def date_end_humanize(self): def date_end_humanize(self):
return arrow.get(self.date_end).humanize(locale='ru') return arrow.get(self.date_end, settings.TIME_ZONE).humanize(locale='ru')

@ -17,6 +17,7 @@ from django.views.decorators.csrf import csrf_exempt
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.timezone import now from django.utils.timezone import now
from django.conf import settings
from paymentwall import Pingback, Product, Widget from paymentwall import Pingback, Product, Widget
@ -219,14 +220,14 @@ class PaymentwallCallbackView(View):
date_start = self.add_months(sourcedate=now().replace(hour=0, minute=0, day=1), months=1) date_start = self.add_months(sourcedate=now().replace(hour=0, minute=0, day=1), months=1)
date_end = school_payment.date_end date_end = school_payment.date_end
else: else:
date_start = arrow.get(school_payment.date_end).shift(days=1).datetime date_start = arrow.get(school_payment.date_end, settings.TIME_ZONE).shift(days=1).datetime
date_end = arrow.get(date_start).shift(months=1).datetime date_end = arrow.get(date_start, settings.TIME_ZONE).shift(months=1).datetime
else: else:
#month = 0 if now().day >= 1 and now().day <= 10 else 1 #month = 0 if now().day >= 1 and now().day <= 10 else 1
# Логика июльского лагеря: до конца июля приобретаем только на текущий месяц # Логика июльского лагеря: до конца июля приобретаем только на текущий месяц
month = 0 month = 0
date_start = self.add_months(sourcedate=now().replace(hour=0, minute=0, day=1), months=month) date_start = self.add_months(sourcedate=now().replace(hour=0, minute=0, day=1), months=month)
date_end = arrow.get(date_start).shift(months=1, minutes=-1).datetime date_end = arrow.get(date_start, settings.TIME_ZONE).shift(months=1, minutes=-1).datetime
payment.date_start = date_start payment.date_start = date_start
payment.date_end = date_end payment.date_end = date_end
if product_type_name == 'course': if product_type_name == 'course':

@ -1,78 +0,0 @@
{% load static %} {% load thumbnail %}
<div class="timing__item{% if school_schedule.weekday > 5 %} timing__item_bg{% endif %} js-timing-item js-timing-toggle{% if not school_schedule.weekday in school_schedules_purchased %} disable{% endif %}">
<div class="timing__cell">
<div class="timing__info">
<div class="timing__day{% if school_schedule.is_online %} active{% endif %}">
{{ school_schedule }}
</div>
{% if live_lesson %}
<div class="timing__date">{{ live_lesson.date }}</div>
{% endif %}
</div>
<div class="timing__buy">
<div class="timing__time">{{ school_schedule.start_at }} (МСК)</div>
{% if school_schedule.weekday in school_schedules_purchased %}
{% if live_lesson and live_lesson.title %}
{% include './open_lesson.html' %}
{% endif %}
{% else %}
{% include './day_pay_btn.html' %}
{% endif %}
</div>
{% comment %}
<!-- это нужно чтобы в попапе продления школы всегда знать какие дни выбраны(куплены) -->
{% endcomment %}
{% if school_schedule.weekday in school_schedules_purchased %}
<span style="display: none;" data-purchased="{{ school_schedule.weekday }}"></span>
{% endif %}
</div>
<div class="timing__cell">
<div class="timing__preview">
{% thumbnail live_lesson.cover.image "70x70" crop="center" as im %}
<img class="timing__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />
{% empty %}
<img class="timing__pic" src="{% static 'img/no_cover.png' %}" width="70px" height="70px" />
{% endthumbnail %}
</div>
</div>
<div class="timing__cell">
<div class="timing__title">{{ school_schedule.title }}{% if live_lesson and live_lesson.title %},
<span class="bold">{{ live_lesson.title }}</span>
{% endif %}
</div>
<div class="timing__content">
{% if live_lesson and live_lesson.short_description %}
{{ live_lesson.short_description }}
{% else %}
{{ school_schedule.description }}
{% endif %}
</div>
<div class="timing__more">
<div class="timing__head">Материалы</div>
<div class="timing__row">
<div class="timing__text">
{{ school_schedule.materials }}
</div>
</div>
{% if school_schedule.schoolschedule_images.exists %}
<div class="timing__head">Результаты прошлых уроков</div>
<div class="timing__works gallery">
{% for image in school_schedule.schoolschedule_images.all %}
{% thumbnail image.img.image "48x48" crop="center" as im %}
<a class="timing__work" href="{{ image.img.image.url }}">
<img class="timing__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}"/>
</a>
{% endthumbnail %}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="timing__cell">
<button class="timing__toggle">
<svg class="icon icon-arrow-down">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-down"></use>
</svg>
</button>
</div>
</div>

@ -1,4 +1,4 @@
<a <a
class="timing__btn btn btn_light" class="timing__btn btn btn_light"
href="{% url 'school:lesson-detail' live_lesson.id %}" href="{% url 'school:lesson-detail' live_lesson.id %}"
>смотреть урок</a> >подробнее</a>

@ -6,74 +6,7 @@
<div class="timing js-timing"> <div class="timing js-timing">
<div class="timing__week"> <div class="timing__week">
{% for school_schedule in school_schedules %} {% for school_schedule in school_schedules %}
{% with current_live_lesson=school_schedule.current_live_lesson %} {% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson purchased=True %}
<div class="timing__item{% if school_schedule.weekday > 5 %} timing__item_bg{% endif %} js-timing-item js-timing-toggle">
<div class="timing__cell">
<div class="timing__info">
<div class="timing__day{% if school_schedule.is_online %} active{% endif %}">
{{ school_schedule }}
</div>
{% if current_live_lesson %}
<!--<div class="timing__date">{{ current_live_lesson.date }}</div>-->
{% endif %}
</div>
<div class="timing__buy">
<div class="timing__time">{{ school_schedule.start_at }} (МСК)</div>
<!--{% include './pay_btn.html' %}-->
</div>
</div>
<div class="timing__cell">
<div class="timing__preview">
{% thumbnail current_live_lesson.cover.image "70x70" crop="center" as im %}
<img class="timing__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}"/>
{% empty %}
<img class="timing__pic" src="{% static 'img/no_cover.png' %}" width="70px" height="70px"/>
{% endthumbnail %}
</div>
</div>
<div class="timing__cell">
<div class="timing__title">{{ school_schedule.title }}
{% if current_live_lesson and current_live_lesson.title %}
, <span class="bold">{{ current_live_lesson.title }}</span>
{% endif %}
</div>
<div class="timing__content">
{% if live_lesson %}
{{ live_lesson.short_description }}
{% else %}
{{ school_schedule.description }}
{% endif %}
</div>
<div class="timing__more">
<div class="timing__head">Материалы</div>
<div class="timing__row">
<div class="timing__text">
{{ school_schedule.materials }}
</div>
</div>
{% if school_schedule.schoolschedule_images.exists %}
<div class="timing__head">Результаты прошлых уроков</div>
<div class="timing__works gallery">
{% for image in school_schedule.schoolschedule_images.all %}
{% thumbnail image.img.image "48x48" crop="center" as im %}
<a class="timing__work" href="{{ image.img.image.url }}">
<img class="timing__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}"/>
</a>
{% endthumbnail %}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="timing__cell">
<button class="timing__toggle">
<svg class="icon icon-arrow-down">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-down"></use>
</svg>
</button>
</div>
</div>
{% endwith %}
{% endfor %} {% endfor %}
</div> </div>
<div class="timing__foot"> <div class="timing__foot">

@ -1,21 +1,23 @@
{% load static %} {% load thumbnail %} {% load static %} {% load thumbnail %}
<div class="timing__item{% if school_schedule.weekday > 5 %} timing__item_bg{% endif %} js-timing-item js-timing-toggle{% if not school_schedule.weekday in school_schedules_purchased %} disable{% endif %}"> <div class="timing__item{% if school_schedule.weekday > 5 %} timing__item_bg{% endif %} js-timing-item js-timing-toggle {% if print %}open{% endif %} {% if purchased and not school_schedule.weekday in school_schedules_purchased %} disable{% endif %}">
<div class="timing__cell timing__cell--info"> <div class="timing__cell timing__cell--info">
<div class="timing__info"> <div class="timing__info">
<div class="timing__day{% if school_schedule.is_online %} active{% endif %}"> <div class="timing__day{% if school_schedule.is_online %} active{% endif %}">
{{ school_schedule }} {{ school_schedule }}
</div> </div>
{% if live_lesson %} {% if purchased and live_lesson %}
<div class="timing__date">{{ live_lesson.date }}</div> <div class="timing__date">{{ live_lesson.date }}</div>
{% endif %} {% endif %}
<div class="timing__time">{{ school_schedule.start_at }} (МСК)</div>
<div class="timing__buy"> <div class="timing__buy">
<div class="timing__time">{{ school_schedule.start_at }} (МСК)</div> {% if purchased %}
{% if school_schedule.weekday in school_schedules_purchased %} {% if school_schedule.weekday in school_schedules_purchased %}
{% if live_lesson and live_lesson.title %} {% if live_lesson and live_lesson.title %}
{% include './open_lesson.html' %} {% include './open_lesson.html' %}
{% endif %}
{% else %}
{% include './day_pay_btn.html' %}
{% endif %} {% endif %}
{% else %}
{% include './day_pay_btn.html' %}
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -26,7 +28,7 @@
<span style="display: none;" data-purchased="{{ school_schedule.weekday }}"></span> <span style="display: none;" data-purchased="{{ school_schedule.weekday }}"></span>
{% endif %} {% endif %}
</div> </div>
<div style="display: flex;"> <div style="display: flex; width: 100%;">
<div class="timing__cell timing__cell--preview"> <div class="timing__cell timing__cell--preview">
<div class="timing__preview"> <div class="timing__preview">
{% thumbnail live_lesson.cover.image "70x70" crop="center" as im %} {% thumbnail live_lesson.cover.image "70x70" crop="center" as im %}
@ -36,7 +38,7 @@
{% endthumbnail %} {% endthumbnail %}
</div> </div>
</div> </div>
<div class="timing__cell timing__cell--content"> <div class="timing__cell timing__cell--content" {% if print %}style="flex: 1 0 0;"{% endif %}>
<div class="timing__title">{{ school_schedule.title }}{% if live_lesson and live_lesson.title %}, <div class="timing__title">{{ school_schedule.title }}{% if live_lesson and live_lesson.title %},
<span class="bold">{{ live_lesson.title }}</span> <span class="bold">{{ live_lesson.title }}</span>
{% endif %} {% endif %}
@ -51,11 +53,19 @@
<div class="timing__more"> <div class="timing__more">
<div class="timing__head">Материалы</div> <div class="timing__head">Материалы</div>
<div class="timing__row"> <div class="timing__row">
<div class="timing__text"> {% if print %}
{{ school_schedule.materials }} <div class="timing__col" style="flex: 0 0 100%;">
</div> <div class="timing__text">
{{ school_schedule.materials }}
</div>
</div>
{% else %}
<div class="timing__text">
{{ school_schedule.materials }}
</div>
{% endif %}
</div> </div>
{% if school_schedule.schoolschedule_images.exists %} {% if not print and school_schedule.schoolschedule_images.exists %}
<div class="timing__head">Результаты прошлых уроков</div> <div class="timing__head">Результаты прошлых уроков</div>
<div class="timing__works gallery"> <div class="timing__works gallery">
{% for image in school_schedule.schoolschedule_images.all %} {% for image in school_schedule.schoolschedule_images.all %}
@ -69,6 +79,7 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
{% if not print %}
<div class="timing__cell timing__cell--toggle"> <div class="timing__cell timing__cell--toggle">
<button class="timing__toggle"> <button class="timing__toggle">
<svg class="icon icon-arrow-down"> <svg class="icon icon-arrow-down">
@ -76,5 +87,6 @@
</svg> </svg>
</button> </button>
</div> </div>
{% endif %}
</div> </div>
</div> </div>

@ -41,10 +41,10 @@
{% for school_schedule in school_schedules %} {% for school_schedule in school_schedules %}
{% if is_previous %} {% if is_previous %}
{% if school_schedule.previous_live_lesson in live_lessons %} {% if school_schedule.previous_live_lesson in live_lessons %}
{% include './_schedule_purchased_item.html' with school_schedule=school_schedule live_lesson=school_schedule.previous_live_lesson %} {% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.previous_live_lesson purchased=True %}
{% endif %} {% endif %}
{% else %} {% else %}
{% include './_schedule_purchased_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson %} {% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson purchased=True %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}

@ -24,7 +24,7 @@
</div> </div>
<div class="lessons__subtitle subtitle">{{ livelesson.date }} // {{ livelesson.title }}</div> <div class="lessons__subtitle subtitle">{{ livelesson.date }} // {{ livelesson.title }}</div>
<div class="lessons__row"> <div class="lessons__row">
<div class="lessons__content">{{ livelesson.short_description }}</div> <div class="lessons__content">{{ livelesson.short_description | linebreaks }}</div>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}

@ -11,70 +11,16 @@
<link rel="stylesheet" media="all" href={% static "app.css" %}> <link rel="stylesheet" media="all" href={% static "app.css" %}>
</head> </head>
<body onload="window.print()"> <body onload="setTimeout(window.print, 1000)">
<div class="outer js-outer"> <div class="outer js-outer">
<div class="section" id="schedule"> <div class="section" id="schedule">
<div class="section__center center center_md"> <div class="section__center center center_md">
<div class="title title_center">Расписание</div> <div class="title title_center">Расписание</div>
<div class="timing js-timing"> <div class="timing js-timing">
<div class="timing__week"> <div class="timing__week">
{% for school_schedule in school_schedules %} {% with current_live_lesson=school_schedule.current_live_lesson %} {% for school_schedule in school_schedules %}
<div class="timing__item {% if school_schedule.weekday > 5 %} timing__item_bg{% endif %} js-timing-item open"> {% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson print=True %}
<div class="timing__cell"> {% endfor %}
<div class="timing__info">
<div class="timing__day{% if school_schedule.is_online %} active{% endif %}">
{{ school_schedule }}
</div>
{% if current_live_lesson %}
<!--<div class="timing__date">{{ current_live_lesson.date }}</div>-->
{% endif %}
</div>
<div class="timing__buy">
<div class="timing__time">{{ school_schedule.start_at }} (МСК)</div>
</div>
</div>
<div class="timing__cell">
<div class="timing__preview">
{% thumbnail current_live_lesson.cover.image "70x70" crop="center" as im %}
<img class="timing__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" /> {% empty %}
<img class="timing__pic" src="{% static 'img/no_cover.png' %}" width="70px" height="70px" /> {% endthumbnail %}
</div>
</div>
<div class="timing__cell">
<div class="timing__title">{{ school_schedule.title }}{% if current_live_lesson %},
<span class="bold">{{ current_live_lesson.title }}</span>
{% endif %}
</div>
<div class="timing__content">
{% if live_lesson %}
{{ live_lesson.short_description }}
{% else %}
{{ school_schedule.description }}
{% endif %}
</div>
<div class="timing__more">
<div class="timing__head">Материалы</div>
<div class="timing__row">
<div class="timing__col" style="flex: 0 0 100%;">
<div class="timing__text">
{{ school_schedule.materials }}
</div>
</div>
</div>
<!--{% if school_schedule.schoolschedule_images.exists %}-->
<!--<div class="timing__head">Результаты прошлых уроков</div>-->
<!--<div class="timing__works gallery">-->
<!--{% for image in school_schedule.schoolschedule_images.all %} {% thumbnail image.img.image "48x48" crop="center" as im %}-->
<!--<a class="timing__work" href="{{ image.img.image.url }}">-->
<!--<img class="timing__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />-->
<!--</a>-->
<!--{% endthumbnail %} {% endfor %}-->
<!--</div>-->
<!--{% endif %}-->
</div>
</div>
</div>
{% endwith %} {% endfor %}
</div> </div>
</div> </div>
</div> </div>

@ -25,12 +25,15 @@
{% else %} {% else %}
<div class="casing__title title">Новые уроки</div> <div class="casing__title title">Новые уроки</div>
{% endif %} {% endif %}
{% comment %}
<label class="casing__switcher switcher"> <label class="casing__switcher switcher">
<span class="switcher__wrap"> <span class="switcher__wrap">
<a href="{% url 'school:summer-school' %}?is_previous=true" class="switcher__item{% if is_previous %} active{% endif %}">запись уроков</a> <a href="{% url 'school:summer-school' %}?is_previous=true" class="switcher__item{% if is_previous %} active{% endif %}">запись уроков</a>
<a href="{% url 'school:summer-school' %}" class="switcher__item{% if not is_previous %} active{% endif %}">новые уроки</a> <a href="{% url 'school:summer-school' %}" class="switcher__item{% if not is_previous %} active{% endif %}">новые уроки</a>
</span> </span>
</label> </label>
{% endcomment %}
</div> </div>
{% endif %} {% endif %}
<div class="casing__timing timing js-timing"> <div class="casing__timing timing js-timing">
@ -38,15 +41,17 @@
{% if is_previous and not live_lessons_exists %} {% if is_previous and not live_lessons_exists %}
Записей уроков пока нет Записей уроков пока нет
{% else %} {% else %}
{% for school_schedule in school_schedules %} {% if is_previous %}
{% if is_previous %} {% for live_lesson in live_lessons %}
{% if school_schedule.previous_live_lesson in live_lessons %} {% if live_lesson.school_schedule and live_lesson.title %}
{% include './_schedule_purchased_item.html' with school_schedule=school_schedule live_lesson=school_schedule.previous_live_lesson %} {% include 'blocks/schedule_item.html' with school_schedule=live_lesson.school_schedule live_lesson=live_lesson purchased=True %}
{% endif %} {% endif %}
{% else %} {% endfor %}
{% include './_schedule_purchased_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson %} {% else %}
{% endif %} {% for school_schedule in school_schedules %}
{% endfor %} {% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson purchased=True %}
{% endfor %}
{% endif %}
{% endif %} {% endif %}
</div> </div>
<div class="timing__week"> <div class="timing__week">

@ -4,9 +4,9 @@ from paymentwall import Pingback
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.decorators import login_required, user_passes_test
from django.db.utils import IntegrityError from django.db.utils import IntegrityError
from django.db.models import Min, F, Func, Q from django.db.models import Min, F, Func, Q, Value
from django.http import Http404 from django.http import Http404
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404, redirect
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.timezone import now from django.utils.timezone import now
from django.views.generic import ListView, UpdateView, TemplateView, DetailView from django.views.generic import ListView, UpdateView, TemplateView, DetailView
@ -170,10 +170,19 @@ class SchoolView(TemplateView):
class SummerSchoolView(TemplateView): class SummerSchoolView(TemplateView):
template_name = 'school/summer_school.html' template_name = 'school/summer_school.html'
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
if not context.get('is_purchased'):
return redirect('/')
return self.render_to_response(context)
def get_context_data(self): def get_context_data(self):
context = super().get_context_data() context = super().get_context_data()
is_previous = 'is_previous' in self.request.GET is_previous = 'is_previous' in self.request.GET
date_now = now().date() date_now = now().date()
yesterday = date_now - timedelta(days=1)
# month_start = date_now.replace(day=1)
month_start = datetime(2018, 7, 1).date()
now_time = now() now_time = now()
try: try:
school_schedule = SchoolSchedule.objects.get(weekday=now_time.isoweekday()) school_schedule = SchoolSchedule.objects.get(weekday=now_time.isoweekday())
@ -186,7 +195,25 @@ class SummerSchoolView(TemplateView):
(end_at + timedelta(hours=1)).time() >= now_time.time() and (end_at + timedelta(hours=1)).time() >= now_time.time() and
school_schedule.current_live_lesson() school_schedule.current_live_lesson()
) )
school_schedules = SchoolSchedule.objects.all()
school_schedules_dict = {ss.weekday: ss for ss in school_schedules}
school_schedules_dict[0] = school_schedules_dict.get(7)
all_schedules_purchased = []
if self.request.user.is_authenticated: if self.request.user.is_authenticated:
all_schedules_purchased = SchoolPayment.objects.filter(
user=self.request.user,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
date_start__range=[month_start, date_now],
).annotate(
joined_weekdays=Func(F('weekdays'), function='unnest',)
).distinct().values_list('joined_weekdays', flat=True)
all_schedules_purchased = list(map(lambda x: 1 if x == 7 else x+1, all_schedules_purchased))
school_payment = SchoolPayment.objects.filter( school_payment = SchoolPayment.objects.filter(
user=self.request.user, user=self.request.user,
status__in=[ status__in=[
@ -221,12 +248,14 @@ class SummerSchoolView(TemplateView):
school_payment_exists_future = False school_payment_exists_future = False
school_purchased_future = False school_purchased_future = False
school_schedules_purchased = [] school_schedules_purchased = []
if school_payment_exists and is_previous: if all_schedules_purchased and is_previous:
live_lessons = LiveLesson.objects.filter( live_lessons = LiveLesson.objects.filter(
date__gte=school_payment.last().date_start, date__range=[month_start, yesterday],
date__range=[(now_time - timedelta(days=8)).date(), (now_time - timedelta(days=1)).date()],
deactivated_at__isnull=True, deactivated_at__isnull=True,
) date__week_day__in=all_schedules_purchased,
).order_by('-date')
for ll in live_lessons:
ll.school_schedule = school_schedules_dict.get(ll.date.isoweekday())
live_lessons_exists = live_lessons.exists() live_lessons_exists = live_lessons.exists()
else: else:
live_lessons = None live_lessons = None
@ -240,7 +269,7 @@ class SummerSchoolView(TemplateView):
'is_purchased': school_payment_exists, 'is_purchased': school_payment_exists,
'is_purchased_future': school_payment_exists_future, 'is_purchased_future': school_payment_exists_future,
'min_school_price': SchoolSchedule.objects.aggregate(Min('month_price'))['month_price__min'], 'min_school_price': SchoolSchedule.objects.aggregate(Min('month_price'))['month_price__min'],
'school_schedules': SchoolSchedule.objects.all(), 'school_schedules': school_schedules,
'school_schedules_purchased': school_schedules_purchased, 'school_schedules_purchased': school_schedules_purchased,
'school_purchased_future': school_purchased_future, 'school_purchased_future': school_purchased_future,
'subscription_ends': school_payment.filter(add_days=False).first().date_end if school_payment_exists else None, 'subscription_ends': school_payment.filter(add_days=False).first().date_end if school_payment_exists else None,

@ -0,0 +1,87 @@
{% extends "templates/lilcity/index.html" %} {% load static %} {% load thumbnail %} {% block content %}
<div class="section">
<div class="section__center center">
<div class="profile">
<div class="profile__ava ava">
{% thumbnail user.photo "120x120" crop="center" as im %}
<img class="ava__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />
{% empty %}
<img class="ava__pic" src="{% static 'img/user_default.jpg' %}" width="120px" height="120px" />
{% endthumbnail %}
</div>
<div class="profile__wrap">
<div class="profile__name">{{ user.get_full_name }}</div>
<div class="profile__share share share_sm">
<div class="share__list">
{% if user.facebook %}
<a class="share__item" href="{{ user.facebook }}">
<svg class="icon icon-share-facebook">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-facebook"></use>
</svg>
</a>
{% endif %} {% if user.instagram %}
<a class="share__item" href="{{ user.instagram }}">
<svg class="icon icon-share-instagram">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-instagram"></use>
</svg>
</a>
{% endif %} {% if user.twitter %}
<a class="share__item" href="{{ user.twitter }}">
<svg class="icon icon-share-twitter">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-twitter"></use>
</svg>
</a>
{% endif %} {% if user.google %}
<a class="share__item" href="{{ user.google }}">
<svg class="icon icon-share-google">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-google"></use>
</svg>
</a>
{% endif %} {% if user.pinterest %}
<a class="share__item" href="{{ user.pinterest }}">
<svg class="icon icon-share-pinterest">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-pinterest"></use>
</svg>
</a>
{% endif %}
</div>
</div>
</div>
<div class="profile__content">
{% if user.about %}
{{ user.about }}
{% endif %}
</div>
</div>
</div>
</div>
<div class="section section_pink-light section_tabs">
<div class="section__center center">
<div class="tabs js-tabs">
<div class="tabs__nav">
<button class="tabs__btn js-tabs-btn {% if not owner %}active{% endif %}">ОПУБЛИКОВАННЫЕ
<span class="mobile-hide">КУРСЫ</span>
</button>
</div>
<div class="tabs__container">
<div class="tabs__item js-tabs-item" style="display: block;">
<div class="courses courses_scroll">
<div class="courses__list">
{% if published.exists %}
{% include "course/course_items.html" with course_items=published %}
{% else %}
<div class="center center_xs">
<div class="done">
<div class="done__title title">Нет опубликованных курсов!</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}

@ -2,7 +2,7 @@
<div class="section section_gray section_menu"> <div class="section section_gray section_menu">
<div class="section__center center center_xs"> <div class="section__center center center_xs">
<div class="menu"> <div class="menu">
<a class="menu__link" href="{% url 'user-edit-profile' user.id %}">Профиль</a> <a class="menu__link" href="{% url 'user-edit-profile' %}">Профиль</a>
<a class="menu__link active" href="{% url 'user-edit-notifications' user.id %}">Уведомления</a> <a class="menu__link active" href="{% url 'user-edit-notifications' user.id %}">Уведомления</a>
<a class="menu__link" href="{% url 'user-edit-payments' user.id %}">Платежи</a> <a class="menu__link" href="{% url 'user-edit-payments' user.id %}">Платежи</a>
</div> </div>

@ -2,7 +2,7 @@
<div class="section section_gray section_menu"> <div class="section section_gray section_menu">
<div class="section__center center center_xs"> <div class="section__center center center_xs">
<div class="menu"> <div class="menu">
<a class="menu__link" href="{% url 'user-edit-profile' user.id %}">Профиль</a> <a class="menu__link" href="{% url 'user-edit-profile' %}">Профиль</a>
<a class="menu__link" href="{% url 'user-edit-notifications' user.id %}">Уведомления</a> <a class="menu__link" href="{% url 'user-edit-notifications' user.id %}">Уведомления</a>
<a class="menu__link active" href="{% url 'user-edit-payments' user.id %}">Платежи</a> <a class="menu__link active" href="{% url 'user-edit-payments' user.id %}">Платежи</a>
</div> </div>

@ -2,7 +2,7 @@
<div class="section section_gray section_menu"> <div class="section section_gray section_menu">
<div class="section__center center center_xs"> <div class="section__center center center_xs">
<div class="menu"> <div class="menu">
<a class="menu__link active" href="{% url 'user-edit-profile' user.id %}">Профиль</a> <a class="menu__link active" href="{% url 'user-edit-profile' %}">Профиль</a>
<a class="menu__link" href="{% url 'user-edit-notifications' user.id %}">Уведомления</a> <a class="menu__link" href="{% url 'user-edit-notifications' user.id %}">Уведомления</a>
<a class="menu__link" href="{% url 'user-edit-payments' user.id %}">Платежи</a> <a class="menu__link" href="{% url 'user-edit-payments' user.id %}">Платежи</a>
</div> </div>

@ -2,9 +2,7 @@
<div class="section"> <div class="section">
<div class="section__center center"> <div class="section__center center">
<div class="profile"> <div class="profile">
{% if not guest %} <a class="profile__btn profile__btn_edit btn" href="{% url 'user-edit-profile' %}">Редактировать</a>
<a class="profile__btn profile__btn_edit btn" href="{% url 'user-edit-profile' user.id %}">Редактировать</a>
{% endif %}
<div class="profile__ava ava"> <div class="profile__ava ava">
{% thumbnail user.photo "120x120" crop="center" as im %} {% thumbnail user.photo "120x120" crop="center" as im %}
<img class="ava__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" /> <img class="ava__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />
@ -56,7 +54,7 @@
{% endif %} {% endif %}
</div> </div>
<div class="profile__foot"> <div class="profile__foot">
<a class="profile__btn btn" href="{% url 'user-edit-profile' user.id %}">Изменить</a> <a class="profile__btn btn" href="{% url 'user-edit-profile' %}">Изменить</a>
</div> </div>
</div> </div>
</div> </div>
@ -66,18 +64,18 @@
<div class="section__center center"> <div class="section__center center">
<div class="tabs js-tabs"> <div class="tabs js-tabs">
<div class="tabs__nav"> <div class="tabs__nav">
{% if owner %} {# <button class="tabs__btn js-tabs-btn active">ЛАГЕРЬ</button> #}
<button class="tabs__btn js-tabs-btn active">ЛАГЕРЬ</button>
<button class="tabs__btn js-tabs-btn">ПРИОБРЕТЕННЫЕ <button class="tabs__btn js-tabs-btn">ПРИОБРЕТЕННЫЕ
<span class="mobile-hide">КУРСЫ</span> <span class="mobile-hide">КУРСЫ</span>
</button> </button>
{% endif %} {% if is_author %}
<button class="tabs__btn js-tabs-btn {% if not owner %}active{% endif %}">ОПУБЛИКОВАННЫЕ <button class="tabs__btn js-tabs-btn">ОПУБЛИКОВАННЫЕ
<span class="mobile-hide">КУРСЫ</span> <span class="mobile-hide">КУРСЫ</span>
</button> </button>
{% endif %}
</div> </div>
<div class="tabs__container"> <div class="tabs__container">
{% if owner %} {% comment %}
<div class="tabs__item js-tabs-item" style="display: block;"> <div class="tabs__item js-tabs-item" style="display: block;">
{% if is_purchased_future %} {% if is_purchased_future %}
<div class="center center_xs"> <div class="center center_xs">
@ -108,7 +106,8 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
<div class="tabs__item js-tabs-item"> {% endcomment %}
<div class="tabs__item js-tabs-item" style="display: block;">
<div class="courses courses_scroll"> <div class="courses courses_scroll">
<div class="courses__list"> <div class="courses__list">
{% if paid.exists %} {% if paid.exists %}
@ -126,8 +125,8 @@
</div> </div>
</div> </div>
</div> </div>
{% endif %} {% if is_author %}
<div class="tabs__item js-tabs-item" {% if not owner %}style="display: block;"{% endif %}> <div class="tabs__item js-tabs-item">
<div class="courses courses_scroll"> <div class="courses courses_scroll">
<div class="courses__list"> <div class="courses__list">
{% if published.exists %} {% if published.exists %}
@ -145,6 +144,7 @@
</div> </div>
</div> </div>
</div> </div>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

@ -1,5 +1,3 @@
import arrow
from io import BytesIO from io import BytesIO
from PIL import Image from PIL import Image
from uuid import uuid4 from uuid import uuid4
@ -41,25 +39,23 @@ def resend_email_verify(request):
url = request.scheme + '://' + request.get_host() + str(reverse_lazy('lilcity:verification-email', args=[token, request.user.id])) url = request.scheme + '://' + request.get_host() + str(reverse_lazy('lilcity:verification-email', args=[token, request.user.id]))
send_email('Вы успешно прошли регистрацию', request.user.email, "notification/email/verification_email.html", url=url) send_email('Вы успешно прошли регистрацию', request.user.email, "notification/email/verification_email.html", url=url)
messages.info(request, 'Письмо подтверждения отправлено.') messages.info(request, 'Письмо подтверждения отправлено.')
return redirect('user-edit-profile', request.user.id) return redirect('user-edit-profile')
class UserView(DetailView): @method_decorator(login_required, name='dispatch')
class ProfileView(TemplateView):
model = User model = User
template_name = 'user/profile.html' template_name = 'user/profile.html'
def get(self, request, *args, **kwargs):
self.object = self.request.user
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
def get_context_data(self, object): def get_context_data(self, object):
context = super().get_context_data() context = super().get_context_data()
if not self.request.user.is_anonymous: context['user'] = self.request.user
context['simple_user'] = self.request.user.role == User.USER_ROLE context['is_author'] = self.request.user.role == User.AUTHOR_ROLE
context['guest'] = self.request.user.id != self.object.id and self.request.user.role <= User.USER_ROLE
else:
context['simple_user'] = True
context['guest'] = True
context['owner'] = self.request.user.id == self.object.id
if context['guest'] and self.object.role <= User.USER_ROLE:
raise Http404()
context['published'] = Course.objects.filter( context['published'] = Course.objects.filter(
author=self.object, author=self.object,
@ -110,6 +106,18 @@ class UserView(DetailView):
return context return context
class UserView(DetailView):
model = User
template_name = 'user/author_profile.html'
def get_context_data(self, object):
context = super().get_context_data()
context['published'] = Course.objects.filter(
author=self.object,
)
return context
class SubscribeView(View): class SubscribeView(View):
def post(self, request, pk=None, **kwargs): def post(self, request, pk=None, **kwargs):
@ -190,16 +198,16 @@ class PaymentHistoryView(FormView):
@method_decorator(login_required, name='dispatch') @method_decorator(login_required, name='dispatch')
class UserEditView(UpdateView): class ProfileEditView(UpdateView):
model = User model = User
template_name = 'user/profile-settings.html' template_name = 'user/profile-settings.html'
form_class = UserEditForm form_class = UserEditForm
@method_decorator(login_required) def get_object(self, queryset=None):
return self.request.user
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
if request.user != self.object:
raise Http404()
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
@ -245,7 +253,7 @@ class UserEditView(UpdateView):
return super().post(request, *args, **kwargs) return super().post(request, *args, **kwargs)
def get_success_url(self): def get_success_url(self):
return reverse('user-edit-profile', args=[self.object.id]) return reverse('user-edit-profile')
class AuthorRequestView(FormView): class AuthorRequestView(FormView):

@ -1,5 +1,9 @@
from django.utils.timezone import now
from paymentwall.pingback import Pingback
from apps.config.models import Config from apps.config.models import Config
from apps.content.models import Baner from apps.content.models import Baner
from apps.payment.models import SchoolPayment
def config(request): def config(request):
@ -8,3 +12,20 @@ def config(request):
def baner(request): def baner(request):
return {'baner': Baner.objects.filter(use=True).first()} return {'baner': Baner.objects.filter(use=True).first()}
def is_summer_school_purchased(request):
if request.user.is_authenticated:
n = now().date()
school_payment = SchoolPayment.objects.filter(
user=request.user,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
date_start__lte=n,
date_end__gte=n
)
return {'is_summer_school_purchased': school_payment.exists()}
return {'is_summer_school_purchased': False}

@ -93,6 +93,7 @@ TEMPLATES = [
'context_processors': [ 'context_processors': [
'project.context_processors.config', 'project.context_processors.config',
'project.context_processors.baner', 'project.context_processors.baner',
'project.context_processors.is_summer_school_purchased',
'django.template.context_processors.debug', 'django.template.context_processors.debug',
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',

@ -44,6 +44,7 @@
</div> </div>
</div> </div>
<div class="letsgo"> <div class="letsgo">
{% comment %}
{% if not is_purchased and not is_purchased_future %} {% if not is_purchased and not is_purchased_future %}
<a <a
{% if not user.is_authenticated %} {% if not user.is_authenticated %}
@ -57,6 +58,7 @@
купить доступ от {{ min_school_price }} руб./месяц купить доступ от {{ min_school_price }} руб./месяц
</a> </a>
{% endif %} {% endif %}
{% endcomment %}
</div> </div>
</div> </div>
</div> </div>

@ -25,13 +25,15 @@
</form> </form>
</div> </div>
<nav class="header__nav"> <nav class="header__nav">
{% if is_summer_school_purchased %}
<div class="header__group"> <div class="header__group">
<a class="header__section {% active_link 'school:summer-school' %}" href="{% url 'school:summer-school' %}"> <a class="header__section {% active_link 'school:summer-school' %}" href="{% url 'school:summer-school' %}?is_previous=true">
ЛАГЕРЬ {% if online or livelesson.is_online %} ЛАГЕРЬ {% if online or livelesson.is_online %}
<div class="header__dot"></div> <div class="header__dot"></div>
{% endif %} {% endif %}
</a> </a>
</div> </div>
{% endif %}
<div class="header__group"> <div class="header__group">
<a class="header__section {% active_link 'school:school' %}" href="{% url 'school:school' %}"> <a class="header__section {% active_link 'school:school' %}" href="{% url 'school:school' %}">
ОНЛАЙН-ШКОЛА {% if online or livelesson.is_online %} ОНЛАЙН-ШКОЛА {% if online or livelesson.is_online %}

@ -5,8 +5,8 @@
<div class="popup__body"> <div class="popup__body">
<div class="lock"> <div class="lock">
<div class="lock__label">ЧТОБЫ ПРОДОЛЖИТЬ ПРОСМОТР</div> <div class="lock__label">ЧТОБЫ ПРОДОЛЖИТЬ ПРОСМОТР</div>
<div class="lock__title title">Как просто научиться рисовать простых персонажей.</div> <div class="lock__title title">{{ course.title }}</div>
<div class="lock__content">Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.</div> <div class="lock__content">{{ course.short_description }}</div>
<a href="{% url 'course-checkout' course.id %}" class="lock__btn btn">КУПИТЬ КУРС</a> <a href="{% url 'course-checkout' course.id %}" class="lock__btn btn">КУПИТЬ КУРС</a>
</div> </div>
</div> </div>

@ -11,44 +11,46 @@
<div class="main__title"> <div class="main__title">
<span class="main__bold">Lil School</span> — первая образовательная онлайн-платформа креативного мышления для детей <span class="main__bold">Lil School</span> — первая образовательная онлайн-платформа креативного мышления для детей
</div> </div>
{% if user.is_authenticated and online %} {% if False and user.is_authenticated and online %}
<div class="main__content"> <div class="main__content">
Сейчас идёт прямой эфир урока «{{ school_schedule.title }}, {{ school_schedule.current_live_lesson.title }}» Сейчас идёт прямой эфир урока «{{ school_schedule.title }}, {{ school_schedule.current_live_lesson.title }}»
</div> </div>
<div class="main__actions"> <div class="main__actions">
<a <a
{% if not is_purchased %} {% if not is_purchased %}
data-popup=".js-popup-buy" data-popup=".js-popup-buy"
href='#' href='#'
{% else %} {% else %}
href="{{ school_schedule.current_live_lesson.get_absolute_url }}" href="{{ school_schedule.current_live_lesson.get_absolute_url }}"
{% endif %} {% endif %}
class="main__btn btn" class="main__btn btn"
>{% if not is_purchased %}Получить доступ{% else %}Смотреть урок{% endif %}</a> >{% if not is_purchased %}Получить доступ{% else %}Смотреть урок{% endif %}</a>
</div> </div>
{% elif user.is_authenticated and online_coming_soon and school_schedule and school_schedule.start_at_humanize %} {% elif False and user.is_authenticated and online_coming_soon and school_schedule and school_schedule.start_at_humanize %}
<div class=""> <div class="">
Урок «{{ school_schedule.title }}, {{ school_schedule.current_live_lesson.title }}» начнётся Урок «{{ school_schedule.title }}, {{ school_schedule.current_live_lesson.title }}» начнётся
</div> </div>
<div class="main__time"> <div class="main__time">
{{ school_schedule.start_at_humanize }} {{ school_schedule.start_at_humanize }}
</div> </div>
<div class="main__actions"> <div class="main__actions">
<a <a
{% if not is_purchased %} {% if not is_purchased %}
data-popup=".js-popup-buy" data-popup=".js-popup-buy"
href='#' href='#'
{% else %} {% else %}
href="{{ school_schedule.current_live_lesson.get_absolute_url }}" href="{{ school_schedule.current_live_lesson.get_absolute_url }}"
{% endif %} {% endif %}
class="main__btn btn" class="main__btn btn"
>{% if not is_purchased %}Получить доступ{% else %}Смотреть урок{% endif %}</a> >{% if not is_purchased %}Получить доступ{% else %}Смотреть урок{% endif %}</a>
</div> </div>
{% else %} {% else %}
<div class="main__subtitle"> <div class="main__subtitle">
Присоединяйтесь в Рисовальный лагерь {# Присоединяйтесь в Рисовальный лагерь #}
Приглашаем вас на месяц открытых дверей в Lil School
</div> </div>
<div class="main__actions"> <div class="main__actions">
{% comment %}
{% if not is_purchased and not is_purchased_future %} {% if not is_purchased and not is_purchased_future %}
<a <a
{% if not is_purchased_future %} {% if not is_purchased_future %}
@ -64,7 +66,9 @@
Получить доступ Получить доступ
</a> </a>
{% endif %} {% endif %}
<a class="main__btn btn btn_white" href="{% url 'school:summer-school' %}">О лагере</a> {% endcomment %}
{# <a class="main__btn btn btn_white" href="{% url 'school:summer-school' %}">О лагере</a> #}
<a class="main__btn btn btn_white" href="{% url 'course' pk=50 %}">Подробнее</a>
</div> </div>
{% endif %} {% endif %}
</div> </div>

@ -1,7 +1,7 @@
{% load static %} {% load thumbnail %} {% load static %} {% load thumbnail %}
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<div class="header__login"> <div class="header__login">
<a class="header__ava ava" href="{% if request.user_agent.is_touch_capable %}#{% else %}{% url 'user' request.user.id %}{% endif %}"> <a class="header__ava ava" href="{% if request.user_agent.is_touch_capable %}#{% else %}{% url 'user-profile' %}{% endif %}">
{% thumbnail request.user.photo "48x48" crop="center" as im %} {% thumbnail request.user.photo "48x48" crop="center" as im %}
<img class="ava__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" /> <img class="ava__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />
{% empty %} {% empty %}
@ -26,7 +26,7 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
<a class="header__link" href="{% url 'user' request.user.id %}"> <a class="header__link" href="{% url 'user-profile' %}">
<div class="header__title">ПРОФИЛЬ</div> <div class="header__title">ПРОФИЛЬ</div>
</a> </a>
<a class="header__link" href="{% url 'lilcity:logout' %}"> <a class="header__link" href="{% url 'lilcity:logout' %}">

@ -27,9 +27,9 @@ from apps.course.views import (
) )
from apps.user.views import ( from apps.user.views import (
AuthorRequestView, UserView, AuthorRequestView, UserView,
UserEditView, NotificationEditView, ProfileEditView, NotificationEditView,
PaymentHistoryView, resend_email_verify, PaymentHistoryView, resend_email_verify,
SubscribeView, SubscribeView, ProfileView,
) )
from apps.payment.views import ( from apps.payment.views import (
CourseBuySuccessView, CourseBuyView, CourseBuySuccessView, CourseBuyView,
@ -67,8 +67,9 @@ urlpatterns = [
path('payments/error', TemplateView.as_view(template_name='payment/payment_error.html'), name='payment-error'), path('payments/error', TemplateView.as_view(template_name='payment/payment_error.html'), name='payment-error'),
path('school/checkout', SchoolBuyView.as_view(), name='school-checkout'), path('school/checkout', SchoolBuyView.as_view(), name='school-checkout'),
path('search/', SearchView.as_view(), name='search'), path('search/', SearchView.as_view(), name='search'),
path('user/profile/', ProfileView.as_view(), name='user-profile'),
path('user/profile/edit', ProfileEditView.as_view(), name='user-edit-profile'),
path('user/<int:pk>/', UserView.as_view(), name='user'), path('user/<int:pk>/', UserView.as_view(), name='user'),
path('user/<int:pk>/edit', UserEditView.as_view(), name='user-edit-profile'),
path('user/<int:pk>/notifications', NotificationEditView.as_view(), name='user-edit-notifications'), path('user/<int:pk>/notifications', NotificationEditView.as_view(), name='user-edit-notifications'),
path('user/<int:pk>/payments', PaymentHistoryView.as_view(), name='user-edit-payments'), path('user/<int:pk>/payments', PaymentHistoryView.as_view(), name='user-edit-payments'),
path('user/resend-email-verify', resend_email_verify, name='resend-email-verify'), path('user/resend-email-verify', resend_email_verify, name='resend-email-verify'),

@ -236,7 +236,7 @@
</div> </div>
<div class="lessons__subtitle subtitle">{{ lesson.title }}</div> <div class="lessons__subtitle subtitle">{{ lesson.title }}</div>
<div class="lessons__row"> <div class="lessons__row">
<div class="lessons__content">{{ lesson.short_description }}</div> <div class="lessons__content">{{ lesson.short_description | linebreaks }}</div>
</div> </div>
</div> </div>
</vue-draggable> </vue-draggable>

@ -3799,6 +3799,7 @@ a.grey-link
+m +m
display: flex display: flex
flex-direction: row flex-direction: row
width: 100%
&__day &__day
position: relative position: relative
margin: 10px 0 5px margin: 10px 0 5px
@ -3824,20 +3825,22 @@ a.grey-link
margin: -3px 0 0 auto margin: -3px 0 0 auto
&__buy &__buy
+m +m
display: flex flex: 1 0 0
margin-left: 20px text-align: right
&__time &__time
margin: 15px 0 margin: 15px 0
opacity: .5 opacity: .5
+m +m
width: 90px margin: -1px 15px
margin: 0 font-size: 12px;
&__btn &__btn
margin-right: -60px margin-right: -60px
padding-left: 20px padding-left: 20px
padding-right: 20px padding-right: 20px
white-space: nowrap white-space: nowrap
letter-spacing: 1px letter-spacing: 1px
+m
margin-right: 0
&__pic &__pic
display: block display: block
width: 100% width: 100%

Loading…
Cancel
Save