Merge remote-tracking branch 'origin/dev' into dev

remotes/origin/hasaccess
Vitaly Baev 8 years ago
commit 65f710736c
  1. 50
      apps/auth/views.py
  2. 48
      apps/course/migrations/0020_auto_20180202_1716.py
  3. 10
      apps/course/models.py
  4. 24
      apps/course/templates/course/_items.html
  5. 2
      apps/course/templates/course/course.html
  6. 6
      apps/course/templates/course/inclusion/category_menu_items.html
  7. 2
      apps/course/templates/course/result.html
  8. 29
      apps/course/views.py
  9. 12
      docker-compose.yml
  10. 21
      project/celery.py
  11. 3
      project/celery_settings.py
  12. 2
      project/settings.py
  13. 18
      project/templates/lilcity/index.html
  14. 120
      project/templates/lilcity/main.html
  15. 21
      project/templates/lilcity/refund_policy.html
  16. 100
      project/templates/lilcity/terms.html
  17. 5
      project/urls.py
  18. 4
      requirements.txt
  19. 7443
      web/build/css/app.css
  20. 2
      web/build/css/app.css.map
  21. 11
      web/src/sass/_common.sass

@ -5,6 +5,7 @@ from facepy.exceptions import FacepyError
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.http import JsonResponse
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
@ -135,27 +136,42 @@ class FacebookLoginOrRegistration(View):
graph = GraphAPI(access_token)
try:
data = graph.get('/me?fields=email, first_name, last_name')
photo_data = graph.get('/me/picture?height=120')
except FacepyError:
return JsonResponse({"success": False})
fb_id = data.get('id')
lilcity_user_settings = User.objects.filter(fb_id=fb_id)
if lilcity_user_settings.count():
login(requests, user=lilcity_user_settings[0])
return JsonResponse({"success": True})
email = requests.POST.get('email') or data.get('email')
if not email:
return JsonResponse({"success": False,
"errors": {"email": 'is field required'}
})
try:
user = User.objects.get(fb_id=fb_id)
except User.DoesNotExist:
email = requests.POST.get('email') or data.get('email')
if not email:
return JsonResponse({"success": False,
"errors": {"email": 'is field required'}
})
else:
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
first_name = data.get('first_name', '')
last_name = data.get('last_name', '')
user = User.objects.create_user(username=email, email=email, first_name=first_name, last_name=last_name, password=uuid4().hex)
user.is_email_proved = True
user.fb_id = fb_id
if photo_data:
photo = ContentFile(photo_data)
fname = str(fb_id) + '.jpg'
user.photo.save(fname, photo, save=True)
user.save()
login(requests, user=user)
return JsonResponse({"success": True})
else:
first_name = data.get('first_name', '')
last_name = data.get('last_name', '')
user = User.objects.create_user(username=email, email=email, first_name=first_name, last_name=last_name, password=uuid4().hex)
user.is_email_proved = True
user.fb_id = fb_id
user.save()
if not user.photo and photo_data:
photo = ContentFile(photo_data)
fname = str(fb_id) + '.jpg'
user.photo.save(fname, photo, save=True)
login(requests, user=user)
return JsonResponse({"success": True})

@ -0,0 +1,48 @@
# Generated by Django 2.0.2 on 2018-02-02 17:16
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import polymorphic_tree.models
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('course', '0019_auto_20180130_1630'),
]
operations = [
migrations.AlterModelOptions(
name='coursecomment',
options={'base_manager_name': 'objects', 'ordering': ('tree_id', 'lft'), 'verbose_name': 'Комментарий курса', 'verbose_name_plural': 'Комментарии курсов'},
),
migrations.AlterModelOptions(
name='lessoncomment',
options={'base_manager_name': 'objects', 'ordering': ('tree_id', 'lft'), 'verbose_name': 'Комментарий урока', 'verbose_name_plural': 'Комментарии уроков'},
),
migrations.RemoveField(
model_name='coursecomment',
name='parent',
),
migrations.RemoveField(
model_name='lessoncomment',
name='parent',
),
migrations.AddField(
model_name='comment',
name='parent',
field=polymorphic_tree.models.PolymorphicTreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='course.Comment'),
),
migrations.AddField(
model_name='comment',
name='polymorphic_ctype',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_course.comment_set+', to='contenttypes.ContentType'),
),
migrations.AlterField(
model_name='comment',
name='author',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

@ -3,7 +3,7 @@ from django.db import models
from django.utils import timezone
from django.contrib.auth import get_user_model
from mptt.models import MPTTModel, TreeForeignKey
from polymorphic_tree.models import PolymorphicMPTTModel, PolymorphicTreeForeignKey
from .manager import CategoryQuerySet
@ -123,9 +123,10 @@ class Material(models.Model):
ordering = ('title',)
class Comment(MPTTModel):
author = models.ForeignKey(User, on_delete=models.PROTECT)
class Comment(PolymorphicMPTTModel):
content = models.TextField('Текст комментария', default='')
author = models.ForeignKey(User, on_delete=models.CASCADE)
parent = PolymorphicTreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, on_delete=models.PROTECT)
created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
@ -142,11 +143,9 @@ class Comment(MPTTModel):
class MPTTMeta:
order_insertion_by = ['-created_at']
abstract = True
class CourseComment(Comment):
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, on_delete=models.PROTECT)
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='comments')
class Meta(Comment.Meta):
@ -155,7 +154,6 @@ class CourseComment(Comment):
class LessonComment(Comment):
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, on_delete=models.PROTECT)
lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE, related_name='comments')
class Meta(Comment.Meta):

@ -6,27 +6,27 @@
data-course data-course-id={{ course.id }}
{% if course.is_deferred_start %}data-future-course data-future-course-time={{ course.deferred_start_at.timestamp }}{% endif %}
>
<a class="courses__preview" href="{% url 'course' course.id %}">
<img class="courses__pic" src="{{ course.cover.url }}"/>
<div class="courses__view">Подробнее</div>
{% if course.is_featured %}
<div class="courses__label courses__label_fav"></div>
{% endif %} {% if course.is_deferred_start %}
<div class="courses__soon">
<div class="courses__left">Курс начнется:</div>
<div class="courses__time">{{ course.deferred_start_at_humanize }}</div>
<a class="courses__preview" href="{% url 'course' course.id %}?next={{ request.get_full_path }}">
<img class="courses__pic" src="{{ course.cover.url }}"/>
<div class="courses__view">Подробнее</div>
{% if course.is_featured %}
<div class="courses__label courses__label_fav"></div>
{% endif %} {% if course.is_deferred_start %}
<div class="courses__soon">
<div class="courses__left">Курс начнется:</div>
<div class="courses__time">{{ course.deferred_start_at_humanize }}</div>
</div>
<div class="courses__label courses__label_clock"></div>
{% endif %}
</a>
<div class="courses__details">
</a>
<div class="courses__details">
<a class="courses__theme theme {{ theme_color }}"
href="{% url 'courses' %}?category={{ course.category.title }}">{{ course.category | upper }}</a>
{% if not course.is_free %}
<div class="courses__price">{{ course.price|floatformat:"-2" }}₽</div>
{% endif %}
</div>
<a class="courses__title" href="{% url 'course' course.id %}">{{ course.title }}</a>
<a class="courses__title" href="{% url 'course' course.id %}?next={{ request.get_full_path }}">{{ course.title }}</a>
<div class="courses__content">{{ course.short_description }}
</div>
<div class="courses__user user">

@ -7,7 +7,7 @@
<div class="section section_border">
<div class="section__center center center_sm">
<div class="go">
<a class="go__item" href="{% url 'courses' %}">
<a class="go__item" href="{% if next %}{{next}}{% else %}{% url 'courses' %}{% endif %}">
<div class="go__arrow">
<svg class="icon icon-arrow-left">
<use xlink:href="{% static '/img/sprite.svg' %}#icon-arrow-left"></use>

@ -1,5 +1,5 @@
{% for category in category_items %}
<a class="header__link" href="{% url 'courses' %}?category={{ category.title }}">
<div class="header__title">{{ category.title }}</div>
{% for cat in category_items %}
<a class="header__link{% if category.0 == cat.title %} active{% endif %}" data-category-name="{{ cat.title }}" href="{% url 'courses' %}?category={{ cat.title }}">
<div class="header__title">{{ cat.title }}</div>
</a>
{% endfor %}

@ -22,9 +22,11 @@
<div class="courses__list">
{% include "./course_items.html" %}
</div>
{% if next_page %}
<div class="courses__load load">
<button class="load__btn btn" data-next-page-url="/search?q={{ q }}&page={{ next_page }}">Подгрузить еще</button>
</div>
{% endif %}
{% else %}
<div class="empty">К сожалению, по вашему запросу ничего не&nbsp;найдено.</div>
{% endif %}

@ -90,7 +90,7 @@ def coursecomment(request, course_id):
@login_required
@csrf_exempt
@require_http_methods(['POST'])
def lessoncomment(request, Lesson):
def lessoncomment(request, lesson_id):
try:
lesson = Lesson.objects.get(id=lesson_id)
except Lesson.DoesNotExist:
@ -111,7 +111,7 @@ def lessoncomment(request, Lesson):
lessoncomment = LessonComment.objects.create(
author=request.user,
content=comment,
course=course,
lesson=lesson,
)
else:
try:
@ -119,13 +119,13 @@ def lessoncomment(request, Lesson):
except LessonComment.DoesNotExist:
return JsonResponse({
'success': False,
'errors': ['CourseComment with id f{reply_to} not found']
'errors': ['LessonComment with id f{reply_to} not found']
}, status=400)
else:
lessoncomment = LessonComment.objects.create(
author=request.user,
content=comment,
course=course,
lesson=lesson,
parent=_lessoncomment,
)
ctx = {'node': lessoncomment, 'user': request.user}
@ -141,6 +141,11 @@ class CourseView(DetailView):
context_object_name = 'course'
template_name = 'course/course.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['next'] = self.request.GET.get('next', None)
return context
class CoursesView(ListView):
model = Course
@ -153,7 +158,7 @@ class CoursesView(ListView):
if request.is_ajax():
context = self.get_context_data()
template_name = self.get_template_names()
html = loader.render_to_string(template_name, context)
html = loader.render_to_string(template_name, context, request=request)
is_paginated = context.get('is_paginated')
if is_paginated:
page_obj = context.get('page_obj')
@ -207,11 +212,17 @@ class SearchView(CoursesView):
queryset = queryset.none()
return queryset
def get_context_data(self):
context = super().get_context_data()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['q'] = self.request.GET.get('q', None) or ''
context['page'] = self.request.GET.get('page', None) or 1
context['next_page'] = str(int(context['page']) + 1)
return context
if 'is_paginated' in context and context['is_paginated']:
page_obj = context.get('page_obj')
context['page'] = page_obj.number
context['next_page'] = str(page_obj.next_page_number()) if page_obj.has_next() else None
else:
context['page'] = 1
context['next_page'] = None
return context
def get_template_names(self):

@ -12,18 +12,26 @@ services:
ports:
- "5432:5432"
redis:
image: redis:3-alpine
ports:
- "6379:6379"
web:
build: .
restart: always
volumes:
- .:/lilcity
command: bash -c "python manage.py migrate && python manage.py loaddata /lilcity/apps/*/fixtures/*.json && python manage.py runserver 0.0.0.0:8000"
command: bash -c "python manage.py migrate && python manage.py loaddata /lilcity/apps/*/fixtures/*.json && python manage.py runserver 0.0.0.0:8000 && celery worker -A project -Q web"
environment:
- DJANGO_SETTINGS_MODULE=project.settings
- DATABASE_SERVICE_HOST=db
- REDIS_SERVICE_HOST=redis
ports:
- "8000:8000"
depends_on:
- db
- redis
links:
- db
- db
- redis

@ -0,0 +1,21 @@
import os
from celery import Celery
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
app = Celery('project')
# Using a string here means the worker don't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('project.celery_settings')
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
return f'Request: {self.request}'

@ -0,0 +1,3 @@
broker_url = 'redis://redis:6379/0'
result_backend = 'redis://redis:6379/1'
task_serializer = 'json'

@ -40,6 +40,8 @@ INSTALLED_APPS = [
'anymail',
'active_link',
'django_filters',
'polymorphic_tree',
'polymorphic',
'mptt',
] + [
'apps.auth.apps',

@ -33,6 +33,7 @@
<meta property="fb:admins" content="Facebook numeric ID">
<meta name="csrf-token" content="{{ csrf_token }}">
<link rel="stylesheet" media="all" href={% static "css/app.css" %}>
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}"/>
<script>
var viewportmeta = document.querySelector('meta[name="viewport"]');
if (viewportmeta) {
@ -119,7 +120,7 @@
</div>
<div class="header__group"><a class="header__section header__section_sub js-header-section {% active_link 'courses' %}" href="{% url 'courses' %}">ВИДЕО-КУРСЫ</a>
<div class="header__list js-header-list">
{% category_menu_items %}
{% category_menu_items category %}
</div>
</div>
<div class="header__group"><a class="header__section" target="_blank" href="http://blog.lil.school">БЛОГ</a></div>
@ -157,6 +158,9 @@
{% endif %}
</div>
</div>
{% if user.is_authenticated and not user.fb_id or user.is_authenticated and not user.is_email_proved %}
<div class="message message_error">Необходимо подтвердить электронную почту</div>
{% endif %}
</header>
<div class="container">
{% block content %}{% endblock content %}
@ -220,9 +224,13 @@
<div class="footer__col footer__col_lg">
<div class="footer__group">
<div class="footer__copyright">2017 © Lil City, UAB.</div>
<div class="footer__links"><a class="footer__link" href="#">Договор-оферта</a>
<div class="footer__links">
<a class="footer__link" href="{% url 'terms' %}">Договор-оферта</a>
<div class="footer__divider">|</div>
<a class="footer__link" href="#">Политика обработки персональных данных</a></div>
<a class="footer__link" href="{% url 'privacy' %}">Политика обработки персональных данных</a>
<div class="footer__divider">|</div>
<a class="footer__link" href="{% url 'refund_policy' %}">Политика возврата</a>
</div>
</div>
</div>
</div>
@ -295,7 +303,7 @@
class="auth__field field learner-registration-form__field">
<div class="field__label">ИМЯ</div>
<div class="field__wrap"><input id="learner-registration-form__first-name" class="field__input"
type="text" name="first_name" placeholder="Sasha"></div>
type="text" name="first_name" placeholder=""></div>
<div id="learner-registration-field-error__first-name"
class="field__error learner-registration-form__field-error"></div>
</div>
@ -303,7 +311,7 @@
class="auth__field field learner-registration-form__field">
<div class="field__label">ФАМИЛИЯ</div>
<div class="field__wrap"><input id="learner-registration-form__last-name" class="field__input"
type="text" name="last_name" placeholder="Kru"></div>
type="text" name="last_name" placeholder=""></div>
<div id="learner-registration-field-error__last-name"
class="field__error learner-registration-form__field-error"></div>
</div>

@ -322,9 +322,7 @@
</div>
</div>
</div>
<div class="text text_mb0">Если хотите к нам в команду, то ждем ваше резюме
<a href='#'>на&nbsp;почту</a>
</div>
<div class="text text_mb0">Если хотите к нам в команду, то отправьте нам заявку</div>
</div>
</div>
<div class="section section_gray">
@ -457,128 +455,24 @@
<a href='#'>Распечатать расписание</a> чтобы не забыть</div>
</div>
</div>
{% if course_items %}
<div class="section">
<div class="section__center center">
<div class="title title_center">Онлайн-курсы</div>
<div class="text">Помимо онлайн-школы Lil City у нас есть отдельные
<a href='#'>курсы в записи</a>. Учитесь и развивайте креативное мышление когда вам удобно.</div>
<a href='{% url 'courses' %}'>курсы в записи</a>. Учитесь и развивайте креативное мышление когда вам удобно.
</div>
<div class="courses">
<div class="courses__list">
<div class="courses__item">
<a class="courses__preview" href="#">
<img class="courses__pic" src="{% static 'img/pic-1.jpg' %}" />
<div class="courses__view">Подробнее</div>
<div class="courses__label courses__label_fav"></div>
</a>
<div class="courses__details">
<a class="courses__theme theme" href="#">АНИМАЦИЯ</a>
<div class="courses__price">30$</div>
</div>
<a class="courses__title" href="#">Базовый курс для детей по основам иллюстрации</a>
<div class="courses__content">Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.</div>
<div class="courses__user user">
<div class="user__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}" />
</div>
<div class="user__info">
<div class="user__name">Александра Неимоверноумная</div>
<div class="user__meta">
<div class="user__date">SEPT 12, 2017</div>
<a class="user__likes likes" href="#">
<div class="likes__counter">253</div>
<div class="likes__icon">
<svg class="icon icon-like">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like"></use>
</svg>
<svg class="icon icon-like-fill">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like-fill"></use>
</svg>
</div>
</a>
</div>
</div>
</div>
</div>
<div class="courses__item">
<a class="courses__preview" href="#">
<img class="courses__pic" src="{% static 'img/pic-1.jpg' %}" />
<div class="courses__view">Подробнее</div>
<div class="courses__soon">
<div class="courses__left">Курс начнется:</div>
<div class="courses__time">через 16 часов 13 минут</div>
</div>
<div class="courses__label courses__label_clock"></div>
</a>
<div class="courses__details">
<a class="courses__theme theme theme_green" href="#">АНИМАЦИЯ</a>
<div class="courses__price">30$</div>
</div>
<a class="courses__title" href="#">Базовый курс для детей по основам иллюстрации</a>
<div class="courses__content">Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.</div>
<div class="courses__user user">
<div class="user__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}" />
</div>
<div class="user__info">
<div class="user__name">Александра Неимоверноумная</div>
<div class="user__meta">
<div class="user__date">SEPT 12, 2017</div>
<a class="user__likes likes" href="#">
<div class="likes__counter">253</div>
<div class="likes__icon">
<svg class="icon icon-like">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like"></use>
</svg>
<svg class="icon icon-like-fill">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like-fill"></use>
</svg>
</div>
</a>
</div>
</div>
</div>
</div>
<div class="courses__item">
<a class="courses__preview" href="#">
<img class="courses__pic" src="{% static 'img/pic-1.jpg' %}" />
<div class="courses__view">Подробнее</div>
</a>
<div class="courses__details">
<a class="courses__theme theme theme_violet" href="#">АНИМАЦИЯ</a>
<div class="courses__price">30$</div>
</div>
<a class="courses__title" href="#">Базовый курс для детей по основам иллюстрации</a>
<div class="courses__content">Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.</div>
<div class="courses__user user">
<div class="user__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}" />
</div>
<div class="user__info">
<div class="user__name">Александра Неимоверноумная</div>
<div class="user__meta">
<div class="user__date">SEPT 12, 2017</div>
<a class="user__likes likes" href="#">
<div class="likes__counter">253</div>
<div class="likes__icon">
<svg class="icon icon-like">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like"></use>
</svg>
<svg class="icon icon-like-fill">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like-fill"></use>
</svg>
</div>
</a>
</div>
</div>
</div>
</div>
{% include "course/course_items.html" %}
</div>
<div class="courses__more more">
<a class="more__btn btn btn_light" href="#">УЗНАТЬ ПОДРОБНЕЕ</a>
<a class="more__btn btn btn_light" href="{% url 'courses' %}">УЗНАТЬ ПОДРОБНЕЕ</a>
</div>
</div>
</div>
</div>
{% endif %}
<div class="game">
<div class="game__center center">
<div class="game__wrap">

@ -0,0 +1,21 @@
{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %}
<div class="section">
<div class="section__center center">
<div class="head">
<div class="head__title title title_center">Refund Policy</div>
</div>
</div>
</div>
<div class="section">
<div class="section__center center">
<p style="margin-bottom: 24px;">Lil City wants you to be happy with your new purchase. If you are having issues with a product and you need our support, please send us a message at hello@lil.city explaining your problem.</p>
<p style="margin-bottom: 24px;">Digital content, which is not supplied on a tangible medium, such as in-app items, is not eligible for a refund unless the content is defective. When you buy such digital content, you waive an automatic right of withdrawal.</p>
<p style="margin-bottom: 24px;">Refunds for purchases may be available only in the following cases:</p>
<p>- Unauthorized purchases: if a purchase was made on your account or with your payment method that you did not permit. Note: It is important that you keep your account information and password private. If you give your details to someone else or appear to be abusing our policies, you are responsible for any purchases made and will not be eligible for a refund.</p>
<p style="margin-bottom: 24px;">- Defective purchases: if a purchase you made was not delivered or is defective.</p>
<p style="margin-bottom: 24px;">In the above-named cases, you may request a refund within 14 calendar days from the date of a transaction. To start your refund procedure please send your refund request to hello@lil.city. Depending on your specific situation, we may be able to help. If your refund is approved, you will lose access to the content. We may deny any return if it fails to meet our return criteria stated above.</p>
<p style="margin-bottom: 24px;">Refunds from Lil City are returned to the payment method used to make the original purchase. Refunds take different account of time depending on how you paid. If you have questions on refund timelines, contact us at hello@lil.city.</p>
</div>
</div>
{% endblock content %}

@ -0,0 +1,100 @@
{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %}
<div style="position: relative; width: 1024px; height: 2400px; top: 0px; left: 140.5px;">
<div style="position: absolute; left: 66px; top: 20px; width: 437px; height: 2473px;">
<p style="font-size: 20px; line-height: 26px;">End-User License Agreement ("Agreement") for Lil City products</p>
<p style="margin-bottom: 50px; font-size: 12px; line-height: 15px;">Last updated: September 14, 2017</p>
<p style="font-size: 12px; line-height: 15px;">Please read this End-User License Agreement ("Agreement") carefully before clicking the "I Agree" button, downloading or using Lil City ("Products").</p>
<p style="font-size: 12px; line-height: 15px;">By clicking the "I Agree" button, downloading or using the Application, you are agreeing to be bound by the terms and conditions of this Agreement.</p>
<p style="font-size: 12px; line-height: 15px;">This Agreement is a legal agreement between you (either an individual or a single entity) and Lil City, UAB and it governs your use of the Application made available to you by Lil City, UAB.</p>
<p style="font-size: 12px; line-height: 15px;">If you do not agree to the terms of this Agreement, do not click on the "I Agree" button and do not download or use the Application.</p>
<p style="font-size: 12px; line-height: 15px;">The Application is licensed, not sold, to you by Lil City, UAB for use strictly in accordance with the terms of this Agreement.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">License (Apps)</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB grants you a revocable, non-exclusive, non-transferable, limited license to download, install and use the Application/Products strictly in accordance with the terms of this Agreement.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Restrictions</p>
<p style="font-size: 15px; line-height: 19px; padding-top: 12px; padding-bottom: 11px; font-weight: bold; font-style: italic;">Do not use the Products the contents (art, illustrations, photos, texts, stickers, etc) for commercial purposes without permission of Lil City,UAB.</p>
<p style="font-size: 12px; line-height: 15px;">You agree not to, and you will not permit others to:</p>
<p style="font-size: 12px; line-height: 15px;">remove, alter or obscure any proprietary notice (including any notice of copyright or trademark) of Lil City, UAB or its affiliates, partners, suppliers or the licensors of the Application.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Intellectual Property</p>
<p style="font-size: 12px; line-height: 15px;">The Application, including without limitation all copyrights, patents, trademarks, trade secrets and other intellectual property rights are, and shall remain, the sole and exclusive property of Lil City, UAB.</p>
<p style="font-size: 12px; line-height: 15px;">Modifications to Application</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB reserves the right to modify, suspend or discontinue, temporarily or permanently, the Application or any service to which it connects, with or without notice and without liability to you.</p>
<p style="font-size: 12px; line-height: 15px;">Updates to Application</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB may from time to time provide enhancements or improvements to the features/functionality of the Application, which may include patches, bug fixes, updates, upgrades and other modifications ("Updates").</p>
<p style="font-size: 12px; line-height: 15px;">Updates may modify or delete certain features and/or functionalities of the Application. You agree that Lil City, UAB has no obligation to (i) provide any Updates, or (ii) continue to provide or enable any particular features and/or functionalities of the Application to you.</p>
<p style="font-size: 12px; line-height: 15px;">You further agree that all Updates will be (i) deemed to constitute an integral part of the Application, and (ii) subject to the terms and conditions of this Agreement.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Third-Party Services</p>
<p style="font-size: 12px; line-height: 15px;">The Application may display, include or make available third-party content (including data, information, applications and other products services) or provide links to third-party websites or services ("Third-Party Services").</p>
<p style="font-size: 12px; line-height: 15px;">You acknowledge and agree that Lil City, UAB shall not be responsible for any Third-Party Services, including their accuracy, completeness, timeliness, validity, copyright compliance, legality, decency, quality or any other aspect thereof. Lil City, UAB does not assume and shall not have any liability or responsibility to you or any other person or entity for any Third-Party Services.</p>
<p style="font-size: 12px; line-height: 15px;">Third-Party Services and links thereto are provided solely as a convenience to you and you access and use them entirely at your own risk and subject to such third parties' terms and conditions.</p>
<p style="font-size: 12px; line-height: 15px;">Privacy Policy</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB has the right to use any materials/images created by the user using the Company's products (Lil World, Lil City School and others) to promote the services/products of the Company without informing the author of the artwork.</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB collects, stores, maintains, and shares information about you in accordance with its Privacy Policy, which is available at http://privacy.lil.city. By accepting this Agreement, you acknowledge that you hereby agree and consent to the terms and conditions of our Privacy Policy.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Term and Termination</p>
<p style="font-size: 12px; line-height: 15px;">This Agreement shall remain in effect until terminated by you or Lil City, UAB.</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB may, in its sole discretion, at any time and for any or no reason, suspend or terminate this Agreement with or without prior notice.</p>
<p style="font-size: 12px; line-height: 15px;">This Agreement will terminate immediately, without prior notice from Lil City, UAB, in the event that you fail to comply with any provision of this Agreement. You may also terminate this Agreement by deleting the Application and all copies thereof from your mobile device or from your computer.</p>
<p style="font-size: 12px; line-height: 15px;">Upon termination of this Agreement, you shall cease all use of the Application and delete all copies of the Application from your mobile device or from your computer.</p>
<p style="font-size: 12px; line-height: 15px;">Termination of this Agreement will not limit any of Lil City, UAB's rights or remedies at law or in equity in case of breach by you (during the term of this Agreement) of any of your obligations under the present Agreement.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Amendments to this Agreement</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB reserves the right, at its sole discretion, to modify or replace this Agreement at any time. If a revision is material we will provide at least 30 days' notice prior to any new terms taking effect. What constitutes a material change will be determined at our sole discretion.</p>
<p style="font-size: 12px; line-height: 15px;">By continuing to access or use our Application after any revisions become effective, you agree to be bound by the revised terms. If you do not agree to the new terms, you are no longer authorized to use the Application.</p>
<p style="font-size: 12px; line-height: 15px;">Governing Law</p>
<p style="font-size: 12px; line-height: 15px;">The laws of Lithuania, excluding its conflicts of law rules, shall govern this Agreement and your use of the Application. Your use of the Application may also be subject to other local, state, national, or international laws.</p>
<p style="font-size: 12px; line-height: 15px;">Contact Information</p>
<p style="font-size: 12px; line-height: 15px;">If you have any questions about this Agreement, please contact us: <a href="mailto:hello@lil.city">hello@lil.city</a></p>
<p style="font-size: 12px; line-height: 15px;">Entire Agreement</p>
<p style="font-size: 12px; line-height: 15px;">The Agreement constitutes the entire agreement between you and Lil City, UAB regarding your use of the Application and supersedes all prior and contemporaneous written or oral agreements between you and Lil City, UAB.</p>
<p style="font-size: 12px; line-height: 15px;">You may be subject to additional terms and conditions that apply when you use or purchase other Lil City, UAB's services, which Lil City, UAB will provide to you at the time of such use or purchase.</p>
<p style="font-size: 15px; line-height: 19px; padding-top: 450px;">LIL CITY, UAB</p>
<p style="font-size: 15px; line-height: 19px;">Įm.k.304127005,</p>
<p style="font-size: 15px; line-height: 19px;">A.Goštauto g.40, Vilnius</p>
<p style="font-size: 15px; line-height: 19px;">LT-03163</p>
<p style="font-size: 15px; line-height: 19px;"><a href="mailto:hello@lil.city">hello@lil.city</a></p>
</div>
<div style="position: absolute;left: 540px; top: 20px; width: 434px; height: 2571px;">
<p style="font-size: 20px; line-height: 26px;">Лицензионное пользовательское соглашение ( "Соглашение") для продуктов Lil City.</p>
<p style="margin-bottom: 50px; font-size: 12px; line-height: 15px;">Последнее обновление: 14 сентября 2017</p>
<p style="font-size: 12px; line-height: 15px;">Пожалуйста, прочтите данное лицензионное соглашение ( "Соглашение"), прежде чем нажать на кнопку "Я согласен", перед использованием продуктами Lil City ( "Продукты").</p>
<p style="font-size: 12px; line-height: 15px;">При нажатии на кнопку "Я согласен", загрузки или с помощью приложения, вы соглашаетесь с положениями и условиями настоящего Соглашения.</p>
<p style="font-size: 12px; line-height: 15px;">Настоящее Соглашение является юридическим соглашением между вами (физическим или юридическим лицом) и Lil City, UAB и регламентирует использование Вами заявки доступны вам Lil City, UAB.</p>
<p style="font-size: 12px; line-height: 15px;">Если вы не согласны с условиями настоящего Соглашения, не нажимайте на кнопку "Я согласен" и не загружайте или используйте приложение.</p>
<p style="font-size: 12px; line-height: 15px;">Применение лицензируется, а не продается, вам Lil City, UAB для использования строго в соответствии с условиями настоящего Договора.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Лицензия (Приложения)</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB предоставляет вам непостоянную, неисключительную, не подлежащую передаче, ограниченную лицензию на загрузку, установку и использование Приложения и его содержимого строго в соответствии с условиями настоящего Договора.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Ограничения.</p>
<p style="font-size: 15px; line-height: 19px; padding-top: 12px; padding-bottom: 11px; font-weight: bold; font-style: italic;">Запрещается использовать Продукты и любые его части (арт, иллюстрации, фото, стикеры, тексты) в коммерческих целях без письменного согласия Lil City, UAB.</p>
<p style="font-size: 12px; line-height: 15px;">Вы соглашаетесь не будете сами и вы не будете позволять другим: удалять, изменять или скрывать любые запатентованную уведомления (включая любые уведомления об авторских правах или товарного знака) Lil City, UAB или её филиалов, партнеров, поставщиков или лицензиаров приложения.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Интеллектуальная собственность</p>
<p style="font-size: 12px; line-height: 15px;">Применение, в том числе, без ограничений, все авторские права, патенты, торговые марки, торговые секреты и другие права интеллектуальной собственности являются, и остаются, единственной и исключительной собственностью Lil City, UAB.</p>
<p style="font-size: 12px; line-height: 15px;">Изменения в Продуктах</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB оставляет за собой право изменять, приостанавливать или прекращать, временно или постоянно, Продукты или любую услугу, к которой он подключается, с или без предварительного уведомления и без ответственности перед вами.</p>
<p style="font-size: 12px; line-height: 15px;">Обновления к применению</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB может время от времени вносить улучшения или усовершенствования в возможности / функциональность Продуктов, которые может включать в себя патчи, исправления ошибок, обновления, обновления и другие модификации ( "Обновление").</p>
<p style="font-size: 12px; line-height: 15px;">Обновления могут изменять или удалять определенные функции и / или функциональные возможности применения. Вы согласны с тем, что Lil City, UAB не имеет никаких обязательств (I), предоставлять какие-либо обновления, или (II) продолжать предоставлять или включить какие-либо особые характеристики и / или функциональные возможности применения к вам.</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB имеет право использовать любые материалы/изображения созданные пользователем при помощи или благодаря продуктам Компании (Lil World, Lil City School и других) для рекламы услуг/продуктов Компании без предупреждения пользователя/автора произведения.</p>
<p style="font-size: 12px; line-height: 15px;">Вы также соглашаетесь с тем, что все обновления будут (я) считается, являются неотъемлемой частью Заявки, и (II) в соответствии с условиями настоящего Соглашения.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Услуги сторонних организаций</p>
<p style="font-size: 12px; line-height: 15px;">Приложение может отображать, включать в себя или предоставлять контент сторонних производителей (в том числе данные, информацию, приложения и другие продукты услуг) или предоставлять ссылки на сторонние веб-сайты или услуги ( "Услуги сторонних организаций").</p>
<p style="font-size: 12px; line-height: 15px;">Вы признаете и соглашаетесь с тем, что Lil City, UAB не несет ответственности за любые Услуги сторонних организаций, включая их точность, полноту, своевременность, достоверность, соблюдение авторских прав, законность, порядочность, качество или любой другой из него в сторону. Lil City, UAB не принимает на себя и не несет никакой ответственности или ответственности перед вами или любым другим физическим или юридическим лицом для каких-либо служб сторонних производителей.</p>
<p style="font-size: 12px; line-height: 15px;">Услуги сторонних организаций и ссылки на них предоставляются исключительно для удобства пользователей и вы получаете доступ и использовать их исключительно на свой страх и риск и в соответствии с условиями таких третьих лиц.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Политика конфиденциальности</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB собирает, хранит, поддерживает и разделяет информацию о Вас в соответствии с политикой конфиденциальности, которая доступна на <a href="http://privacy.lil.city">http://privacy.lil.city</a>. Принимая данное Соглашение, Вы подтверждаете, что вы тем самым соглашаетесь и согласие с условиями нашей политики конфиденциальности.</p>
<p style="font-size: 12px; line-height: 15px;">Срок действия и прекращение действия</p>
<p style="font-size: 12px; line-height: 15px;">Настоящее Соглашение остается в силе до момента прекращения действия Вами или Lil City, UAB.</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB может, по своему усмотрению, в любое время и по любой причине или без нее, приостановить или прекратить действие настоящего Соглашения с или без предварительного уведомления.</p>
<p style="font-size: 12px; line-height: 15px;">Настоящее Соглашение будет немедленно прекращено, без предварительного уведомления от Lil City, UAB, в том случае, если вы не в состоянии выполнить какое-либо положение настоящего Соглашения. Вы также можете прекратить действие настоящего Соглашения, удалив приложение и все его копии с вашего мобильного устройства или с компьютера.</p>
<p style="font-size: 12px; line-height: 15px;">После прекращения действия настоящего Соглашения, Вы должны прекратить любое использование Приложения и удалить все копии программы с мобильного устройства или с компьютера.</p>
<p style="font-size: 12px; line-height: 15px;">Прекращение действия настоящего Соглашения не будет ограничивать права Lil City, UAB, или средства правовой защиты по закону или по справедливости в случае нарушения Вами (в течение срока действия настоящего Договора) любых из ваших обязательств по настоящему Договору.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Поправки к настоящему Соглашению</p>
<p style="font-size: 12px; line-height: 15px;">Lil City, UAB оставляет за собой право, по своему усмотрению изменить или заменить данное Соглашение в любое время. В случае пересмотр положений мы будем предоставлять уведомление по меньшей мере за 30 дней до добавления каких-либо новых терминов, вступающих в силу. Что представляет собой существенное изменение будет определяться по собственному усмотрению.</p>
<p style="font-size: 12px; line-height: 15px;">Продолжая доступ или использование нашего Приложения после того, как любые изменения вступят в силу, вы соглашаетесь быть связанными измененными условиями. Если вы не согласны с новыми условиями, вам больше не разрешается использовать приложение.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Регулирующий закон</p>
<p style="font-size: 12px; line-height: 15px;">Законы Литвы(Евросоюза), России и любых других стран за исключением его разногласий правовых норм, регулируют это Соглашение и использование Вами заявки. Использование приложения может также подвергаться другим местным, государственным, национальным или международным законодательством.</p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Контактная информация</p>
<p style="font-size: 12px; line-height: 15px;">Если у вас есть какие-либо вопросы по поводу данного Соглашения, пожалуйста, свяжитесь с нами: <a href="mailto:hello@lil.city">hello@lil.city</a></p>
<p style="font-size: 13px; line-height: 17px; padding-top: 24px; font-weight: bold;">Полное согласие</p>
<p style="font-size: 12px; line-height: 15px;">Соглашение представляет собой полное соглашение между вами и Lil City, UAB относительно Вашего использования Приложения, и заменяет собой все предшествующие и одновременные письменные или устные соглашения между вами и Lil City, UAB.</p>
<p style="font-size: 12px; line-height: 15px;">Вы можете быть сопряжены с дополнительными условиями, которые применяются при использовании или приобретении других продуктов Lil City, UAB, которая Lil City, UAB предоставит вам в момент такого использования или покупки.</p>
</div>
</div>
{% endblock content %}

@ -23,6 +23,7 @@ from apps.course.views import (
CourseView, LessonView, SearchView,
lessoncomment,
)
from apps.course.models import Course
from apps.user.views import UserView
urlpatterns = [
@ -37,7 +38,9 @@ urlpatterns = [
path('search/', SearchView.as_view(), name='search'),
path('user/<int:pk>/', UserView.as_view(), name='user'),
path('privacy', TemplateView.as_view(template_name="templates/lilcity/privacy_policy.html"), name='privacy'),
path('', TemplateView.as_view(template_name="templates/lilcity/main.html"), name='index'),
path('terms', TemplateView.as_view(template_name="templates/lilcity/terms.html"), name='terms'),
path('refund-policy', TemplateView.as_view(template_name="templates/lilcity/refund_policy.html"), name='refund_policy'),
path('', TemplateView.as_view(template_name="templates/lilcity/main.html", extra_context={'course_items': Course.objects.all()[:3]}), name='index'),
]

@ -1,5 +1,5 @@
# Python-3.6
Django==2.0.1
Django==2.0.2
django-anymail[mailgun]==1.2
paymentwall-python==1.0.7
twilio==6.10.0
@ -10,3 +10,5 @@ django-active-link==0.1.2
arrow==0.12.1
django-filter==2.0.0.dev1
django-mptt==0.9.0
django-polymorphic-tree==1.5
celery[redis]==4.1.0

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -3209,6 +3209,17 @@ a.grey-link
padding: 10px
display: none
.message
margin: 15px
font-size: 14px
text-align: center
color: #fff
padding: 10px
z-index: 999
&_error
background: $pink
.mobile-hide
+m
display: none

Loading…
Cancel
Save