Merge branch 'develop' into 'master'

Develop

See merge request !7
remotes/origin/pm_task_31703
Zolotarev Alexander 9 years ago
commit eeca6aa9a4
  1. 24
      .gitlab-ci.yml
  2. 0
      __migrate/__init__.py
  3. 9
      __migrate/dump_fixtures.py
  4. 15
      __migrate/fix_arch.py
  5. 1
      __migrate/fixtures/access.json
  6. 1
      __migrate/fixtures/courses.json
  7. 1
      __migrate/fixtures/finance.json
  8. 1
      __migrate/fixtures/management.json
  9. 1
      __migrate/fixtures/storage.json
  10. 105
      __migrate/journal_merge.py
  11. 63
      __migrate/load_fixtures.py
  12. 277
      __migrate/merge_courses.py
  13. 110
      __migrate/merge_finance.py
  14. 111
      __migrate/merge_fixtures.py
  15. 228
      __migrate/merge_journals.py
  16. 88
      __migrate/merge_management.py
  17. 100
      __migrate/merge_storage.py
  18. 116
      __migrate/merge_users.py
  19. 1
      __migrate/pk_maps.json
  20. 121
      __migrate/post_fixtures.py
  21. 11
      __migrate/test_course_map.py
  22. BIN
      __test/access_api.rar
  23. 83
      __test/access_api/form.js
  24. 5
      __test/access_api/jquery.min.js
  25. 19
      __test/access_api/text.html
  26. 13
      __test/other_pay.html
  27. 15
      __test/time_test.html
  28. 5796
      _practice/1.txt
  29. 10
      _practice/reg_test.py
  30. 62
      _utils/check_course_journal.py
  31. 74
      _utils/clean_twice_course_journals.py
  32. 3
      _utils/get_reports.py
  33. 28
      _utils/open_bills.py
  34. 199
      _utils/open_course_lesson.py
  35. 2
      _utils/open_lesson.py
  36. 2
      _utils/reports/get_all_students_emails.py
  37. 3
      _utils/reports/get_learn_balance.py
  38. 2
      _utils/reports/get_success_for_theme.py
  39. 2
      _utils/reports/get_success_hw_themes.py
  40. 2
      _utils/reports/get_theme_try_len.py
  41. 2
      _utils/reports/post_sale.py
  42. 6
      access/api.py
  43. 16
      access/models.py
  44. 22
      conf/uwsgi_prod.ini
  45. 9
      courses/models.py
  46. 2
      finance/amo.py
  47. 3
      finance/models.py
  48. 2
      journals/admin.py
  49. 10
      lms/settings.py
  50. 14
      management/api.py
  51. 2
      management/forum_views.py
  52. 71
      management/letters.py
  53. 3
      management/mails.py
  54. 2
      management/tools.py
  55. 1
      management/urls.py
  56. 2
      practice/api.py
  57. 2
      practice/views.py
  58. 1
      requirements.txt
  59. 53
      static/css/app.css
  60. 10
      static/js/bill.js
  61. 14
      static/js/homework.js
  62. 127
      stud.txt
  63. 15
      templates/mails/sent_order.html
  64. 6
      templates/workshop_homework.html

@ -6,10 +6,10 @@
variables:
CHANNEL: "skillbox"
SERVER_URL: "lms.test.spicycms.com"
DOMAIN: "$CI_BUILD_REF_NAME.$SERVER_URL"
SLACK_MSG: "Check new website <http://$DOMAIN>"
#SLACK_PAYLOAD: 'payload={\"channel\":\"#'${CHANNEL}'\",\"username\":\"'${SERVER_URL}'\",\"text\":\"'${SLACK_MSG}'\",\"icon_emoji\":\":ghost:\"}'
SLACK_URL: "https://hooks.slack.com/services/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"
DOMAIN: "$CI_BUILD_REF_SLUG.$SERVER_URL"
SLACK_MSG: "Check new website <https://$DOMAIN>"
SLACK_URL: "https://hooks.slack.com/services/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"
SLACK_URL_BRAMA: "https://hooks.slack.com/services/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"
types:
- build
- test
@ -17,21 +17,23 @@ build_app:
type: build
script:
- docker login -u "gitlab-ci-token" -p "$CI_BUILD_TOKEN" $CI_REGISTRY
- docker build --no-cache --rm --pull -t "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_NAME" --build-arg SSH_PRIVATE_KEY="$SSH_PRIVATE_KEY" --build-arg SPICYCODE_LOGIN="$SPICYCODE_LOGIN" --build-arg SPICYCODE_PASS="$SPICYCODE_PASS" .
#- docker run --rm --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_NAME" python manage.py test
- docker push "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_NAME"
- docker build --no-cache --rm --pull -t "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG" --build-arg SSH_PRIVATE_KEY="$SSH_PRIVATE_KEY" --build-arg SPICYCODE_LOGIN="$SPICYCODE_LOGIN" --build-arg SPICYCODE_PASS="$SPICYCODE_PASS" .
#- docker run --rm --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG" python manage.py test
- docker push "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG"
test_app:
type: test
script:
#- docker login -u "gitlab-ci-token" -p "$CI_BUILD_TOKEN" $CI_REGISTRY
#- docker pull "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_NAME"
#- docker pull "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG"
- if [[ $(docker ps -a) == *$DOMAIN* ]] ; then docker stop $DOMAIN ; fi
- if [[ $(docker ps -a) == *$DOMAIN* ]] ; then docker rm $DOMAIN; fi
- "SLACK_PAYLOAD='payload={\"channel\":\"#'${CHANNEL}'\",\"username\":\"'${SERVER_URL}'\",\"text\":\"'${SLACK_MSG}'\",\"icon_emoji\":\":ghost:\"}'"
- docker run -d --expose=80 -e VIRTUAL_HOST=$DOMAIN --name=$DOMAIN -e DB_NAME=$DB_NAME -e PG_PORT_5432_TCP_ADDR=$DB_HOST -e PG_PORT_5432_TCP_PORT=$DB_PORT -e PG_ENV_POSTGRES_USER=$DB_TEST_USER -e PG_ENV_POSTGRES_PASSWORD=$DB_TEST_PASS "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_NAME"
- docker run -d --expose=80 -e VIRTUAL_HOST=$DOMAIN --name=$DOMAIN -e DB_NAME=$DB_NAME -e PG_PORT_5432_TCP_ADDR=$DB_HOST -e PG_PORT_5432_TCP_PORT=$DB_PORT -e PG_ENV_POSTGRES_USER=$DB_TEST_USER -e PG_ENV_POSTGRES_PASSWORD=$DB_TEST_PASS "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG"
- curl -I $DOMAIN 2>/dev/null | head -n 1 | cut -d$' ' -f2
- echo ${SLACK_PAYLOAD}
- curl -X POST -d ${SLACK_PAYLOAD} $SLACK_URL
- SLACK_MSG="REVIEW app is started on https://$DOMAIN/"
- SLACK_PAYLOAD="payload={\"text\":\"$SLACK_MSG\",\"username\":\"gitlab-ci\"}"
- curl -X POST -d "$SLACK_PAYLOAD" $SLACK_URL
- curl -X POST -d "$SLACK_PAYLOAD" $SLACK_URL_BRAMA
dependencies:
- build_app

@ -1,9 +0,0 @@
# coding=utf-8
import os
apps = ['access', 'courses', 'finance', 'management', 'storage']
for app in apps:
os.system('python manage.py dumpdata {0} -o fixtures/{0}.json'.format(app))
print u'Загружаю медиа'
os.system('tar czf media.tar.gz media/')

@ -1,15 +0,0 @@
# coding=utf-8
import json
print 'Вытаскиваю материалы'
_fixture = json.load(open('fixtures/courses.json'))
loader = ('courses.course')
w = open('fixtures/courses.json', 'w')
for i in _fixture:
if i['model'] in loader.keys():
i['model'] = loader[i['model']]
json.dump(_fixture, w)
w.close()
print 'Закончил вытаскивание'

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,105 +0,0 @@
# coding=utf-8
def set_hm_success(obj):
# Получить статус домашку в success
if obj['fields']['status'] == 'F':
return True
else:
return False
def create_try(obj):
# Создать попытку со всеми комментариями и результатом
global HT
HT += 1
if obj["fields"]["teacher"]:
_journal_result.append({"model": "journals.homeworktry",
"pk": HT, "fields": {"parent": obj['pk'], "student": obj['fields']['student'],
"teacher": obj['fields']['teacher'],
"material": obj['fields']['homework'],
"date": obj['fields']['date'], "f_date": obj['fields']['f_date'],
"comments": obj['fields']['comments'],
"success": set_hm_success(obj),
"expired": False}})
print 'Создание карты курса'
# id: {'themes': {}, 'exam': 'id экзамена'}
# 'themes': {'id темы': {'lessons': [список id уроков], 'homework': id дз}
_courses_map = {}
for i in _fixture:
if i['model'] == 'courses.course':
if i['pk'] not in _courses_map.keys():
# Добавить курс на карту
_courses_map[i['pk']] = {'themes': {}, 'exam': {}}
elif i['model'] == 'courses.coursetheme':
# Добавить тему в курс
if i['pk'] not in _courses_map[i['fields']['course']]['themes'].keys():
_courses_map[i['fields']['course']]['themes'][i['pk']] = {'lessons': set({}), 'homework': ''}
elif i['model'] == 'courses.exam':
# Присвоить курсу ID экзамена
_courses_map[i['fields']['course']]['exam'] = i['pk']
elif i['model'] == 'courses.homework':
# Добавить домашнее задание в тему
_courses_map[i['fields']['course']]['themes'][i['fields']['theme']]['homework'] = i['pk']
elif i['model'] == 'courses.lesson':
_courses_map[i['fields']['course']]['themes'][i['fields']['theme']]['lessons'].add(i['pk'])
# Вторая обработка
print 'Постобработка'
for key, value in _theme_counts.items():
value['fix'] = int(value['fix']) + 1
value['last'] = value['fix']
# +1 - готовый ID для новой темы
print 'Обход по карте'
_merge_map = {
'journals.teacherj': {'exclude': ['lessons', 'homeworks', 'exam', 'f_date'],
'new': {'progress': 0},
'rename': {},
'rebuild': {}},
'journals.lessonj': {'exclude': ['status'],
'new': {'success': True, 'parent': None},
'rename': {'lesson': 'material'},
'rebuild': {}},
'journals.homeworkj': {'exclude': ['status', 'comments'],
'new': {'success': set_hm_success, 'parent': None},
'rename': {'homework': 'material'},
'rebuild': {'comments': create_try}},
'journals.examj': {'exclude': ['status', 'comments'],
'new': {'success': False, 'parent': None},
'rename': {'exam': 'material'},
'rebuild': {}},
}
# Преобразовать модели объектов
_journal_result = []
for i in _journal:
if i['model'] in _merge_map.keys():
__tmp = {}
for key, value in _merge_map[i['model']]['rebuild'].items():
value(i)
for key, value in i['fields'].items():
# Исключить не используемые поля
if key not in _merge_map[i['model']]['exclude']:
if key in _merge_map[i['model']]['rename'].keys():
# Переименовать переменные
__tmp[_merge_map[i['model']]['rename'][key]] = value
else:
__tmp[key] = value
for key, value in _merge_map[i['model']]['new'].items():
if type(value) in [str, int, bool] or value is None:
__tmp[key] = value
else:
# Получение не определенного заранее ответа
__tmp[key] = value(i)
# Как получить ID журнала темы
__tmp = {"pk": i['pk'], "model": i['model'], "fields": __tmp}
_journal_result.append(__tmp)
else:
_journal_result.append(i)
json.dump(_journal_result, open('fixtures/journals.json', 'w'))

@ -1,63 +0,0 @@
м# coding=utf-8
import os
import django
from post_fixtures import main
from _utils.clear_db import main as clear_main
print '==== Загружаю DJANGO'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from storage.models import Storage, CroppedImage
print '==== Загрузил DJANGO'
# == Загрузка данных
print '==== Обрабатываю модели'
# Загрузка материалов
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
print BASE_DIR
APPS = ('storage', 'access', 'management', 'courses', 'finance', )
#courses_models = ('courses.course', 'courses.coursetheme', 'courses.lesson', 'courses.homework', 'courses.exam')
#journal_models = ('courses.teacherj', 'courses.lessonj', 'courses.homeworkj', 'courses.examj')
#finance_models = ("courses.bill", 'courses.price', 'courses.servicerequest')
clear_main()
os.system('python merge_fixtures.py')
# Загрузить фикстуры не изменившихся моделей
print '==== Заливаю модели'
for app in APPS:
print app.upper()
os.system('python manage.py loaddata fixtures/{0}.json'.format(app))
print '==== Заливаю MEDIA'
os.system('tar xfz media.tar.gz')
print '==== Проверка заливки'
# Проверить существование файлов из storage
errors = []
for store in Storage.objects.all():
# Проверить original, f_format.icon
obj = (store.original.path if store.original else '',
store.f_format.icon.path if store.f_format and store.f_format.icon else '')
for i in obj:
if i and not os.path.exists(i):
errors.append(i)
#print 'Ошибки файлов: {0}'.format(len(errors))
for store in CroppedImage.objects.all():
# croppedimage.big, croppedimage.middle, croppedimage.small
obj = (store.big.path if store.big else '',
store.middle.path if store.middle else '',
store.small.path if store.small else '')
for i in obj:
if i and not os.path.exists(i):
errors.append(i)
#print 'Ошибки файлов: {0}'.format(len(errors))
print 'Ошибки файлов: {0}'.format(len(errors))
#print errors
main()

@ -1,277 +0,0 @@
# coding=utf-8
import os
import django
import sys
import simplejson as json
sys.path.append("/var/www/projects/lms/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from __migrate.post_fixtures import show_progress
from courses.models import Course, CourseTheme, Lesson, Homework, Exam, Skills, SkillJ, Achievements, CourseBuilder
from management.models import Comment
from storage.models import Storage
_fixture = json.load(open('fixtures/courses.json'))
user_pk = 1
courses = []
lessons = []
themes = []
homeworks = []
exams = []
skills = []
skillsj = []
achs = []
def new_index(model, key, obj):
if str(key) in pk_map[model]:
return obj.objects.get(id=pk_map[model][str(key)])
return None
# Пример записи маршрута
pk_map = json.load(open('pk_maps.json'))
if 'courses.course' not in pk_map.keys():
pk_map['courses.course'] = {}
if 'courses.coursetheme' not in pk_map.keys():
pk_map['courses.coursetheme'] = {}
if 'courses.lesson' not in pk_map.keys():
pk_map['courses.lesson'] = {}
if 'courses.homework' not in pk_map.keys():
pk_map['courses.homework'] = {}
if 'courses.exam' not in pk_map.keys():
pk_map['courses.exam'] = {}
if 'courses.skills' not in pk_map.keys():
pk_map['courses.skills'] = {}
if 'courses.skillj' not in pk_map.keys():
pk_map['courses.skillj'] = {}
if 'courses.achievements' not in pk_map.keys():
pk_map['courses.achievements'] = {}
for i in _fixture:
if i['model'] == 'courses.course':
if i not in courses:
courses.append(i)
elif i['model'] == 'courses.coursetheme':
if i not in themes:
themes.append(i)
elif i['model'] == 'courses.lesson':
if i not in lessons:
lessons.append(i)
elif i['model'] == 'courses.homework':
if i not in homeworks:
homeworks.append(i)
elif i['model'] == 'courses.exam':
if i not in exams:
exams.append(i)
elif i['model'] == 'courses.skills':
if i not in skillsj:
skills.append(i)
elif i['model'] == 'courses.skillj':
if i not in skillsj:
skillsj.append(i)
elif i['model'] == 'courses.achievements':
if i not in achs:
achs.append(i)
print '\nCourse'
_now = 0
big_len = len(courses)
show_progress(big_len, _now)
for i in courses:
c = Course.objects.create(
level=i['fields']['level'],
public=True,
title=i['fields']['title'],
description=i['fields']['description'],
image=i['fields']['image'],
big_image=i['fields']['big_image'],
page=i['fields']['page'],
preview=i['fields']['preview'],
sort=i['fields']['sort'],
use_fail=i['fields']['use_fail'],
basic_len=i['fields']['basic_len'],
addition_len=i['fields']['addition_len'],
min_price=i['fields']['min_price'],
buy_icon=i['fields']['buy_icon']
)
pk_map['courses.course'][str(i['pk'])] = str(c.id)
_now += 1
show_progress(big_len, _now)
print u'\nCourseTheme'
_now = 0
big_len = len(themes)
show_progress(big_len, _now)
for i in themes:
c = CourseTheme.objects.create(
price_type='E' if i['fields']['type'] == 'A' else i['fields']['type'],
_type='E' if i['fields']['type'] == 'A' else i['fields']['type'],
icon=i['fields']['icon'],
course=new_index('courses.course', i['fields']['course'], Course),
sort=i['fields']['sort'],
title=i['fields']['title'],
description=i['fields']['description'],
)
# print i['fields']['course']
# print new_index('courses.course', i['fields']['course'], Course)
pk_map['courses.coursetheme'][str(i['pk'])] = str(c.id)
_now += 1
show_progress(big_len, _now)
print u'\nLessons'
_now = 0
big_len = len(lessons)
show_progress(big_len, _now)
for i in lessons:
c = Lesson.objects.create(
free=i['fields']['free'],
token=i['fields']['token'],
title=i['fields']['title'],
sort=i['fields']['sort'],
course=new_index('courses.course', i['fields']['course'], Course),
theme=new_index('courses.coursetheme', i['fields']['theme'], CourseTheme),
description=i['fields']['description'],
video=i['fields']['video']
)
for key in i['fields']['materials']:
c.materials.add(new_index('storage.storage', key, Storage))
for key in i['fields']['comments']:
# print key
# print new_index('management.comment', key, Comment)
c.comments.add(new_index('management.comment', key, Comment))
pk_map['courses.lesson'][str(i['pk'])] = str(c.id)
_now += 1
show_progress(big_len, _now)
print u'\nHomework'
_now = 0
big_len = len(homeworks)
show_progress(big_len, _now)
for i in homeworks:
c = Homework.objects.create(
token=i['fields']['token'],
course=new_index('courses.course', i['fields']['course'], Course),
theme=new_index('courses.coursetheme', i['fields']['theme'], CourseTheme),
description=i['fields']['description'],
sort=1
)
for key in i['fields']['materials']:
c.materials.add(new_index('storage.storage', key, Storage))
_now += 1
show_progress(big_len, _now)
pk_map['courses.homework'][str(i['pk'])] = str(c.id)
print u'\nExams'
_now = 0
big_len = len(exams)
show_progress(big_len, _now)
for i in exams:
tm = CourseTheme.objects.create(
course=new_index('courses.course', i['fields']['course'], Course),
_type='Ex'
)
pk_map['courses.coursetheme'][str(tm.id)] = str(tm.id)
c = Exam.objects.create(
token=i['fields']['token'],
sort=1,
course=new_index('courses.course', i['fields']['course'], Course),
theme=tm,
icon=new_index('storage.storage', i['fields']['diploma'], Storage),
title=i['fields']['title'],
description=i['fields']['description'],
diploma=new_index('storage.storage', i['fields']['diploma'], Storage)
)
for key in i['fields']['materials']:
c.materials.add(new_index('storage.storage', key, Storage))
_now += 1
show_progress(big_len, _now)
pk_map['courses.exam'][str(i['pk'])] = str(c.id)
print u'\nПереформировать порядок'
for course in Course.objects.all():
_count = 1
#print course
for _type in ['B', 'M', 'Ex', 'E', 'P']:
for theme in CourseTheme.objects.filter(course=course, _type=_type):
theme.sort = _count
_count += 1
theme.save()
#print _count
print u'\nКарты курсов'
for course in Course.objects.all():
CourseBuilder(course).main()
print u'\nSkills'
_now = 0
big_len = len(skills)
show_progress(big_len, _now)
for i in skills:
c, c2 = Skills.objects.get_or_create(
title=i['fields']['title'],
color=i['fields']['color']
)
_now += 1
show_progress(big_len, _now)
pk_map['courses.skills'][str(i['pk'])] = str(c.id)
print u'\nSkillsJ'
_now = 0
big_len = len(skillsj)
show_progress(big_len, _now)
for i in skillsj:
c, c2 = SkillJ.objects.get_or_create(
skill=new_index('courses.skills', i['fields']['skill'], Skills),
lesson=new_index('courses.lesson', i['fields']['lesson'], Lesson),
size=i['fields']['size']
)
_now += 1
show_progress(big_len, _now)
pk_map['courses.skillj'][str(i['pk'])] = str(c.id)
print u'\nAchivements'
_now = 0
big_len = len(achs)
show_progress(big_len, _now)
for i in achs:
c, c2 = Achievements.objects.get_or_create(
tech_name=i['fields']['tech_name'],
icon=i['fields']['icon'],
title=i['fields']['title'],
image=i['fields']['image'],
background=i['fields']['background'],
border=i['fields']['border'],
)
_now += 1
show_progress(big_len, _now)
pk_map['courses.achievements'][str(i['pk'])] = str(c.id)
for course in Course.objects.all():
course.build_map()
json.dump(pk_map, open('pk_maps.json', 'w'))

@ -1,110 +0,0 @@
# coding=utf-8
import os
import django
import sys
import simplejson as json
sys.path.append("/var/www/projects/lms/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from __migrate.post_fixtures import show_progress
from courses.models import Course
from finance.models import Price, Bill, ServiceRequest
from access.models import User
_fixture = json.load(open('fixtures/courses.json'))
user_pk = 1
prices = []
bills = []
requests = []
def new_index(model, key, obj):
if str(key) in pk_map[model]:
return obj.objects.get(id=pk_map[model][str(key)])
return None
# Пример записи маршрута
pk_map = json.load(open('pk_maps.json'))
if 'finance.price' not in pk_map.keys():
pk_map['finance.price'] = {}
if 'finance.bill' not in pk_map.keys():
pk_map['finance.bill'] = {}
if 'finance.servicerequest' not in pk_map.keys():
pk_map['finance.servicerequest'] = {}
for i in _fixture:
if i['model'] == 'courses.price':
prices.append(i)
elif i['model'] == 'courses.bill':
bills.append(i)
elif i['model'] == 'courses.servicerequest':
requests.append(i)
print u'\nPrice'
_now = 0
big_len = len(prices)
show_progress(big_len, _now)
for i in prices:
f, c = Price.objects.get_or_create(
m_type=i['fields']['m_type'],
public=i['fields']['public'],
title=i['fields']['title'],
cost=i['fields']['cost'],
course=new_index('courses.course', i['fields']['course'], Course),
description=i['fields']['description']
)
_now += 1
show_progress(big_len, _now)
pk_map['finance.price'][str(i['pk'])] = str(f.id)
print u'\nBill'
_now = 0
big_len = len(bills)
show_progress(big_len, _now)
for i in bills:
s = Bill.objects.create(
status=i['fields']['status'],
user=new_index('access.user', i['fields']['user'], User),
manager=new_index('access.user', i['fields']['manager'], User),
service=new_index('finance.price', i['fields']['service'], Price),
key=i['fields']['key'],
out_id=i['fields']['out_id'],
date=i['fields']['date'],
status_changed=i['fields']['status_changed'],
comment=i['fields']['comment'],
finish_date=i['fields']['finish_date'],
salt=i['fields']['salt'],
)
_now += 1
show_progress(big_len, _now)
pk_map['finance.bill'][str(i['pk'])] = str(s.id)
print u'\nServiceRequest'
_now = 0
big_len = len(requests)
show_progress(big_len, _now)
for i in requests:
c = ServiceRequest.objects.create(
status=i['fields']['status'],
student=new_index('access.user', i['fields']['student'], User),
course=new_index('courses.course', i['fields']['course'], Course),
manager=new_index('access.user', i['fields']['manager'], User),
cancel_description=i['fields']['cancel_description'],
charge=i['fields']['charge'],
date=i['fields']['date'],
f_date=i['fields']['f_date'],
send=i['fields']['send'],
)
_now += 1
show_progress(big_len, _now)
pk_map['finance.servicerequest'][str(i['pk'])] = str(c.id)
json.dump(pk_map, open('pk_maps.json', 'w'))

@ -1,111 +0,0 @@
# coding=utf-8
import json
HT = 0
print 'Приступил к МЕРДЖУ'
loader = {
'courses.teacherj': 'journals.teacherj',
'courses.lessonj': 'journals.lessonj',
'courses.homeworkj': 'journals.homeworkj',
'courses.examj': 'journals.examj',
'courses.bill': 'finance.bill',
'courses.price': 'finance.price',
'courses.servicerequest': 'finance.servicerequest',
'courses.selfbillrequest': 'finance.selfbillrequest',
'courses.selfbillhistory': 'finance.selfbillhistory',
'courses.achievementj': 'journals.achievementj'
}
_journal = []
_finance = []
_courses = []
_theme_count = 0
_theme_counts = {}
M_material = ''
_fixture = json.load(open('fixtures/courses.json'))
# Первая обработка
for i in _fixture:
if i['model'] in loader.keys():
i['model'] = loader[i['model']]
if i['model'] == 'courses.coursetheme':
# Проверяем существование реестра счетчиков по курсу
if i['fields']['course'] not in _theme_counts.keys():
_theme_counts[i['fields']['course']] = 0
if int(i['pk']) > _theme_count:
# Ловим последний ID темы
_theme_count = int(i['pk'])
if i['fields']['type'] == 'A':
i['fields']['price_type'] = 'E'
i['fields']['type'] = 'E'
# Считаем количество расширеных тем
else:
i['fields']['price_type'] = i['fields']['type']
# Ловим последнюю сортировку базовых тем курса
if i['fields']['type'] == 'B' and int(i['fields']['sort']) > _theme_counts[i['fields']['course']]:
_theme_counts[i['fields']['course']] = int(i['fields']['sort'])
if i['fields']['type'] == 'M':
# Ловим предэкзаменационные материалы
i['fields']['price_type'] = 'B'
M_material = i
M_material['fields']['sort'] = False
if i['model'] == 'courses.homework':
i['fields']['sort'] = '1'
if i['model'] == 'courses.course':
i['fields']['public'] = True
if i['model'] == 'courses.exam':
i['fields']['sort'] = '1'
if 'finance' in i['model']:
_finance.append(i)
elif 'courses' in i['model']:
_courses.append(i)
_theme_counts[M_material['fields']['course']] += 1
for i in _fixture:
if i['model'] == 'courses.exam':
# Создаю для каждого экзамена экзаменационную тему
if not M_material['fields']['sort'] and M_material['fields']['course'] == i['fields']['course']:
M_material['fields']['sort'] = int(_theme_counts[M_material['fields']['course']])
_theme_counts[M_material['fields']['course']] += 1
_courses.append(M_material)
_theme_count += 1 # Пересчет количества экзаменов
_courses.append({"model": "courses.coursetheme",
"pk": int(_theme_count), # Расчитать ID темы - последняя
"fields": {"type": "Ex",
"price_type": "B",
"icon": "",
"course": i['fields']['course'],
"sort": int(_theme_counts[i['fields']['course']]), # Расчитать сортировку
"title": "Экзаменационная тема",
"description": ""}
})
i['fields']['theme'] = int(_theme_count)
json.dump(_courses, open('fixtures/courses.json', 'w'))
json.dump(_finance, open('fixtures/finance.json', 'w'))
_fixture = json.load(open('fixtures/management.json'))
for i in _fixture:
if i['model'] == 'management.comment':
i['fields']['saw'] = []
tmp = {}
for key, value in i['fields'].items():
# Убрать не нужны поля
if key != 'public':
tmp[key] = value
i['fields'] = tmp
json.dump(_fixture, open('fixtures/management.json', 'w'))
print 'Закончил МЕРДЖ'

@ -1,228 +0,0 @@
# coding=utf-8
import os
import django
import sys
import simplejson as json
sys.path.append("/var/www/projects/lms/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from __migrate.post_fixtures import show_progress
from access.models import User
from courses.models import Exam, Homework, Lesson, Achievements, Course, CourseTheme
from journals.models import TeacherJ, AchievementJ, LessonJ, HomeworkJ, ExamJ, CourseThemeJ, HomeworkTry, check_journal
from storage.models import Storage
from management.models import Comment
_fixture = json.load(open('fixtures/courses.json'))
teachers = []
achss = []
lessonss = []
homeworks = []
exams = []
def new_index(model, key, obj):
if str(key) in pk_map[model]:
return obj.objects.get(id=pk_map[model][str(key)])
return None
# Пример записи маршрута
pk_map = json.load(open('pk_maps.json'))
if 'journals.teacherj' not in pk_map.keys():
pk_map['journals.teacherj'] = {}
if 'journals.achievementj' not in pk_map.keys():
pk_map['journals.achievementj'] = {}
if 'journals.lessonj' not in pk_map.keys():
pk_map['journals.lessonj'] = {}
if 'journals.homeworkj' not in pk_map.keys():
pk_map['journals.homeworkj'] = {}
if 'journals.examj' not in pk_map.keys():
pk_map['journals.examj'] = {}
for i in _fixture:
if i['model'] == 'courses.teacherj':
teachers.append(i)
elif i['model'] == 'courses.achievementj':
achss.append(i)
elif i['model'] == 'courses.lessonj':
lessonss.append(i)
elif i['model'] == 'courses.homeworkj':
homeworks.append(i)
elif i['model'] == 'courses.examj':
exams.append(i)
def achnivs():
print u'\nAchievementJ'
_now = 0
big_len = len(achss)
show_progress(big_len, _now)
for i in achss:
s = AchievementJ.objects.create(
group=i['fields']['group'],
title=i['fields']['title'],
text=i['fields']['text'],
student=new_index('access.user', i['fields']['student'], User),
achievement=new_index('courses.achievements', i['fields']['achievement'], Achievements),
got=i['fields']['got'],
date=i['fields']['date']
)
_now += 1
show_progress(big_len, _now)
pk_map['journals.achievementj'][str(i['pk'])] = str(s.id)
def tej():
print u'\nПереформирование журналов TeacherJ'
for i in teachers:
tj, c = TeacherJ.objects.get_or_create(student=new_index('access.user', i['fields']['student'], User),
course=new_index('courses.course', i['fields']['course'], Course))
# print i['fields']
if tj.start_date != i['fields']['start_date']:
tj.start_date = i['fields']['start_date']
if tj.teacher != new_index('access.user', i['fields']['teacher'], User):
tj.teacher = new_index('access.user', i['fields']['teacher'], User)
# check_journal(tj, tj.student, tj.course)
tj.save()
check_journal(tj)
pk_map['journals.teacherj'][str(i['pk'])] = str(tj.id)
print u'\nCreate CourseThemeJ'
for journal in TeacherJ.objects.all():
for theme in CourseTheme.objects.filter(course=journal.course):
c, c2 = CourseThemeJ.objects.get_or_create(material=theme, student=journal.student)
if c.parent != journal:
c.parent = journal
c.save()
def get_point(point, t, f):
if point:
return t
else:
return f
def lj():
print u'\nLessonJ'
_now = 0
big_len = len(lessonss)
show_progress(big_len, _now)
for i in lessonss:
# print i
c, c2 = LessonJ.objects.get_or_create(
student=new_index('access.user', i['fields']['student'], User),
material=new_index('courses.lesson', i['fields']['lesson'], Lesson),
# parent=CourseThemeJ.objects.get(student=new_index('access.user', i['fields']['student'], User),
# material=new_index('courses.lesson', i['fields']['lesson'], Lesson).theme)
)
c.success = bool(i['fields']['status'] == 'F')
c.date = get_point(i['fields']['status'] != 'N', i['fields']['date'], None)
c.f_date = get_point(i['fields']['status'] == 'F', i['fields']['f_date'], None)
c.save()
_now += 1
show_progress(big_len, _now)
pk_map['journals.lessonj'][str(i['pk'])] = str(c.id)
def create_try(parent, date):
return HomeworkTry.objects.create(
parent=parent,
material=parent.material,
student=parent.student,
teacher=parent.teacher,
date=date
)
def hj():
print u'\nHomeworkJ'
_now = 0
big_len = len(homeworks)
show_progress(big_len, _now)
for i in homeworks:
c, c2 = HomeworkJ.objects.get_or_create(
student=new_index('access.user', i['fields']['student'], User),
material=new_index('courses.homework', i['fields']['homework'], Homework)
# parent=CourseThemeJ.objects.get(student=new_index('access.user', i['fields']['student'], User),
# material=new_index('courses.homework', i['fields']['homework'],
# Homework).theme)
)
c.date = i['fields']['date']
c.f_date = i['fields']['f_date']
c.teacher = new_index('access.user', i['fields']['teacher'], User)
c.success = False
c.save()
comments = [new_index('management.comment', comment, Comment) for comment in i['fields']['comments']]
_try = None
for comment in comments:
must_del = False
if not _try:
_try = create_try(c, comment.date)
if '<span class="label label-success">Задача принята! </span><br>' in comment.text.encode('utf8'):
_try.f_date = comment.date
_try.success = True
must_del = True
if '<span class="label label-danger">Отправлено на доработку!</span><br>' in comment.text.encode('utf8'):
_try.f_date = comment.date
must_del = True
_try.comments.add(comment)
_try.save()
if must_del:
_try = None
must_del = False
_now += 1
show_progress(big_len, _now)
pk_map['journals.homeworkj'][str(i['pk'])] = str(c.id)
def exj():
print u'\nExamJ'
_now = 0
big_len = len(exams)
show_progress(big_len, _now)
for i in exams:
# print i
c, c2 = ExamJ.objects.get_or_create(
material=new_index('courses.exam', i['fields']['exam'], Exam),
student=new_index('access.user', i['fields']['student'], User)
# parent=CourseThemeJ.objects.get(student=new_index('access.user', i['fields']['student'], User),
# material___type='Ex',
# material__course=new_index('courses.exam', i['fields']['exam'],
# Exam).course)
)
c.teacher = new_index('access.user', i['fields']['teacher'], User)
c.date = i['fields']['date']
c.f_date = i['fields']['f_date']
c.success = False
c.diploma = new_index('storage.storage', i['fields']['diploma'], Storage)
c.save()
_now += 1
show_progress(big_len, _now)
pk_map['journals.examj'][str(i['pk'])] = str(c.id)
if __name__ == '__main__':
# achnivs()
lj()
hj()
exj()
tej()
json.dump(pk_map, open('pk_maps.json', 'w'))

@ -1,88 +0,0 @@
# coding=utf-8
import os
import django
import sys
import simplejson as json
sys.path.append("/var/www/projects/lms/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from __migrate.post_fixtures import show_progress
from storage.models import Storage
from access.models import User
from management.models import News, Comment, Feedback
_fixture = json.load(open('fixtures/management.json'))
user_pk = 1
findex = []
storage = []
crimg = []
def new_index(model, key, obj):
if str(key) in pk_map[model]:
return obj.objects.get(id=pk_map[model][str(key)])
return None
# Пример записи маршрута
pk_map = json.load(open('pk_maps.json'))
if 'management.news' not in pk_map.keys():
pk_map['management.news'] = {}
if 'management.comment' not in pk_map.keys():
pk_map['management.comment'] = {}
if 'management.feedback' not in pk_map.keys():
pk_map['management.feedback'] = {}
for i in _fixture:
if i['model'] == 'management.news':
findex.append(i)
elif i['model'] == 'management.comment':
storage.append(i)
elif i['model'] == 'management.feedback':
crimg.append(i)
print u'\nComments'
_now = 0
big_len = len(storage)
show_progress(big_len, _now)
for i in storage:
s = Comment.objects.create(
closed=i['fields']['closed'],
parent_id=i['fields']['parent_id'],
owner=new_index('access.user', i['fields']['owner'], User),
text=i['fields']['text'],
date=i['fields']['date'],
send=i['fields']['send']
)
for key in i['fields']['files']:
s.files.add(new_index('storage.storage', key, Storage))
_now += 1
show_progress(big_len, _now)
pk_map['management.comment'][str(i['pk'])] = str(s.id)
print u'\nFeedBack'
_now = 0
big_len = len(crimg)
show_progress(big_len, _now)
for i in crimg:
c = Feedback.objects.create(
closed=i['fields']['closed'],
name=i['fields']['name'],
email=i['fields']['email'],
phone=i['fields']['phone'],
text=i['fields']['text'],
date=i['fields']['date'],
send=i['fields']['send']
)
_now += 1
show_progress(big_len, _now)
pk_map['management.feedback'][str(i['pk'])] = str(c.id)
json.dump(pk_map, open('pk_maps.json', 'w'))

@ -1,100 +0,0 @@
# coding=utf-8
import os
import django
import sys
import simplejson as json
sys.path.append("/var/www/projects/lms/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from __migrate.post_fixtures import show_progress
from storage.models import FormatIndex, Storage, CroppedImage
_fixture = json.load(open('fixtures/storage.json'))
user_pk = 1
findex = []
storage = []
crimg = []
def new_index(model, key, obj):
if str(key) in pk_map[model]:
return obj.objects.get(id=pk_map[model][str(key)])
return None
# Пример записи маршрута
pk_map = json.load(open('pk_maps.json'))
if 'storage.formatindex' not in pk_map.keys():
pk_map['storage.formatindex'] = {}
if 'storage.storage' not in pk_map.keys():
pk_map['storage.storage'] = {}
if 'storage.croppedimage' not in pk_map.keys():
pk_map['storage.croppedimage'] = {}
for i in _fixture:
if i['model'] == 'storage.formatindex':
findex.append(i)
elif i['model'] == 'storage.storage':
storage.append(i)
elif i['model'] == 'storage.croppedimage':
crimg.append(i)
print u'\nFormatIndex'
_now = 0
big_len = len(findex)
show_progress(big_len, _now)
for i in findex:
f = FormatIndex.objects.create(
f_type=i['fields']['f_type'],
name=i['fields']['name'],
description=i['fields']['description'],
icon=i['fields']['icon'],
icon_class=i['fields']['icon_class'],
)
pk_map['storage.formatindex'][str(i['pk'])] = str(f.id)
_now += 1
show_progress(big_len, _now)
print u'\nStorage'
_now = 0
big_len = len(storage)
show_progress(big_len, _now)
for i in storage:
s = Storage.objects.create(
loaded=i['fields']['loaded'],
name=i['fields']['name'],
key=i['fields']['key'],
original=i['fields']['original'],
f_format=new_index('storage.formatindex', i['fields']['f_format'], FormatIndex),
description=i['fields']['description'],
date=i['fields']['date'],
error=i['fields']['error'],
)
pk_map['storage.storage'][str(i['pk'])] = str(s.id)
_now += 1
show_progress(big_len, _now)
print u'\nCroppedImg'
_now = 0
big_len = len(crimg)
show_progress(big_len, _now)
for i in crimg:
c = CroppedImage.objects.create(
original=new_index('storage.storage', i['fields']['original'], Storage),
big=i['fields']['big'],
middle=i['fields']['middle'],
small=i['fields']['small'],
cropped=i['fields']['cropped'],
)
pk_map['storage.croppedimage'][str(i['pk'])] = str(c.id)
_now += 1
show_progress(big_len, _now)
json.dump(pk_map, open('pk_maps.json', 'w'))

@ -1,116 +0,0 @@
# coding=utf-8
import os
import django
import sys
import simplejson as json
sys.path.append("/var/www/projects/lms/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from __migrate.post_fixtures import show_progress
from access.models import User, Subscription, ActionJ
_fixture = json.load(open('fixtures/access.json'))
user_pk = 1
users = []
subs = []
acts = []
actjs = []
# Пример записи маршрута
pk_map = json.load(open('pk_maps.json'))
if 'access.user' not in pk_map:
pk_map['access.user'] = {}
if 'access.subscription' not in pk_map:
pk_map['access.subscription'] = {}
if 'access.actionj' not in pk_map:
pk_map['access.actionj'] = {}
for i in _fixture:
if i['model'] == 'access.user':
users.append(i)
elif i['model'] == 'access.subscription':
subs.append(i)
elif i['model'] == 'access.actionj':
actjs.append(i)
print u'\nUsers'
_now = 0
big_len = len(users)
show_progress(big_len, _now)
for i in users:
u = User.objects.create(
password=i['fields']['password'],
email=i['fields']['email'],
changed_email=i['fields']['changed_email'],
phone=i['fields']['phone'],
back_phone=i['fields']['back_phone'],
status=i['fields']['status'],
in_role=i['fields']['in_role'],
deactivate=i['fields']['deactivate'],
city=i['fields']['city'],
b_day=i['fields']['b_day'],
token=i['fields']['token'],
activate_time=i['fields']['activate_time'],
reg_status=i['fields']['reg_status'],
is_active=i['fields']['is_active'],
is_admin=i['fields']['is_admin'],
is_staff=i['fields']['is_staff'],
avatar=i['fields']['avatar'],
fname=i['fields']['fname'],
name=i['fields']['name'],
oname=i['fields']['oname'],
skype='',
facebook='',
vk='',
linkedin='',
odnoklassniki='',
date_joined=i['fields']['date_joined']
)
_now += 1
show_progress(big_len, _now)
pk_map['access.user'][str(i['pk'])] = str(u.id)
print u'\nSubscriptions'
_now = 0
big_len = len(subs)
show_progress(big_len, _now)
for i in subs:
s = Subscription.objects.create(
owner=User.objects.get(id=pk_map['access.user'][str(i['fields']['owner'])]),
news=i['fields']['news'],
teacher=i['fields']['teacher'],
new_comments=i['fields']['new_comments'],
send_sms=i['fields']['send_sms'],
courses=i['fields']['courses'],
)
_now += 1
show_progress(big_len, _now)
pk_map['access.subscription'][str(i['pk'])] = str(s.id)
print u'\nActions'
_now = 0
big_len = len(actjs)
show_progress(big_len, _now)
for i in actjs:
a = ActionJ.objects.create(
student=User.objects.get(id=pk_map['access.user'][str(i['fields']['student'])]),
a_type=i['fields']['a_type'],
place=i['fields']['place'],
date=i['fields']['date'],
text=i['fields']['text'],
)
_now += 1
show_progress(big_len, _now)
pk_map['access.actionj'][str(i['pk'])] = str(a.id)
json.dump(pk_map, open('pk_maps.json', 'w'))

@ -1,121 +0,0 @@
# coding=utf-8
import os
import django
import sys
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from courses.models import CourseTheme, Course
from journals.models import HomeworkTry as HT, TeacherJ, CourseThemeJ, LessonJ, HomeworkJ, ExamJ
def split_ht():
# Разделить комментарии по попыткам
print '==== Разбиваю попытки'
big_length = HT.objects.all().count()
_now = 0
show_progress(big_length, _now)
for i in HT.objects.all():
# Получить все попытки
# Пройтись по комментариям по порядку
# Если в тексте преподавателя есть <span class="label label-danger">Отправлено на доработку!</span>
# <span class="label label-success">Задача принята! </span><br> - одобрено
do = True
for n in i.comments.all().order_by('id'):
if do:
_tmp = HT.objects.create(parent=i.parent, material=i.material, student=i.student, teacher=i.teacher,
date=i.date, f_date=i.f_date)
do = False
if '<span class="label label-success">Задача принята! </span><br>' in n.text.encode('utf8'):
#print 'Нашел одобрение'
_tmp.success = True
_tmp.f_date = n.date
_tmp.save()
do = True
elif '<span class="label label-danger">Отправлено на доработку!</span><br>' in n.text.encode('utf8'):
#print 'Нашел отказ'
_tmp.success = False
_tmp.f_date = n.date
_tmp.save()
do = True
#print 'Добавил комментарий в попытку {0}'.format(_tmp.id)
_tmp.comments.add(n)
i.delete()
_now += 1
show_progress(big_length, _now)
print ''
def CTJ_split():
print '==== Создаю журналы тем'
# TODO: Не нужно создавать тему там, где нет журналов?
# Присвоить журналы тем домашним работам/ урокам/ экзаменам
big_length = TeacherJ.objects.all().count()
_now = 0
show_progress(big_length, _now)
for journal in TeacherJ.objects.all():
for theme in CourseTheme.objects.filter(course=journal.course):
CTJ = CourseThemeJ.objects.create(parent=journal, material=theme, student=journal.student)
if CTJ.material.type == 'B':
for lesson in LessonJ.objects.filter(material__theme=theme, student=journal.student):
if lesson.parent != CTJ:
lesson.parent = CTJ
lesson.save()
for homework in HomeworkJ.objects.filter(material__theme=theme, student=journal.student):
if homework.parent != CTJ:
homework.parent = CTJ
homework.save()
elif CTJ.material.type == 'Ex':
try:
ex = ExamJ.objects.get(material__course=journal.course, student=journal.student)
except ExamJ.DoesNotExist:
pass
else:
ex.parent = CTJ
ex.save()
_now += 1
show_progress(big_length, _now, post=journal.id)
print ''
def empty_journals():
print '==== Создаю пустые журналы'
big_length = Course.objects.all().count()
_now = 0
show_progress(big_length, _now)
for course in Course.objects.all():
try:
TeacherJ.objects.create(course=course, student=None)
except:
continue
else:
_now += 1
show_progress(big_length, _now)
print ''
def show_progress(full, now, post=''):
# + Процесс отображения процентов выполнения
# Отображение процента выполнения
if full != 0:
progress = float(now / (full * 0.01))
else:
progress = '100'
sys.stdout.write(u'\rВыполнено: {0:6.4}% {1}'.format(progress, post))
sys.stdout.flush()
def rights():
os.system('chown www-data:www-data -R *')
def main():
rights()
#CTJ_split()
empty_journals()
#split_ht()
if __name__ == '__main__':
main()

@ -1,11 +0,0 @@
# coding=utf-8
import os
import django
print '==== Загружаю DJANGO'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from courses.models import Lesson, CourseMap
l = Lesson.objects.all().first()
CourseMap.objects.create(lesson=l, sort=0)

Binary file not shown.

@ -1,83 +0,0 @@
function parseGetParams() {
var $_GET = {};
var __GET = window.location.search.substring(1).split("&");
for(var i=0; i<__GET.length; i++) {
var getVar = __GET[i].split("=");
$_GET[getVar[0]] = typeof(getVar[1])=="undefined" ? "" : getVar[1];
}
return $_GET;
}
function in_array(value, array) {
for(var i=0; i<array.length; i++){
if(value == array[i]) return true;
}
return false;
}
function check_email(data){
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(data);
}
function not_empty(data){
var result = false;
if (data.length > 0){
result = true
}
return result;
}
function check_form(email, phone, data, error) {
$(error).fadeOut('fast');
if(check_email(email) && not_empty(phone)){
create_bill($(data), $(error))
} else {
$('[name=error_place]').html('Форма заполнена не верно').fadeIn();
}
}
function create_bill(form, error){
var get = parseGetParams();
if ('admitad_uid' in get){
var forms = $('forms');
var ad_ui = get['admitad_uid'];
var input = '<input readonly name="uid" style="display: none;" value="'+ad_ui+'">';
for (var i =0;i<forms.length;i++){
$(forms[i]).append(input)
}
}
$(error).fadeOut();
$.ajax({
type: 'POST',
url: 'https://lms.ru/access/create_bill/',
data: $(form).serialize(),
success: function(data) {
if (data.code == '0'){
$(error).html(data.response).fadeIn();
} else {
if (data['data']['gift']){
location.href=data['data']['pay_url']
} else {
$(error).html('Счет успешно добавлен').fadeIn();
}
}
}
});
}
function create_user(form, error){
$(error).fadeOut();
$.ajax({
type: 'POST',
url: 'https://lms.ru/access/create_user/',
data: $(form).serialize(),
success: function(data) {
if (data.code == '0'){
$(error).html(data.response).fadeIn();
} else {
$(error).html('Пользователь успешно зарегистрирован').fadeIn();
}
}
});
}

File diff suppressed because one or more lines are too long

@ -1,19 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src='jquery.min.js'></script>
<script type="text/javascript" src='form.js'></script>
</head>
<body>
<form onclick="return false;" name="bill_form">
<p name="error_place" style="background: #ffc; display: none;"></p>
<input name="email" placeholder="Почта" type="text">
<input name="phone" placeholder="Телефон" type="text">
<input name="token" value="iLeeoRvQM7gpAyAglTi3" readonly style="display: none;">
<input name="service" value="k7vNYr2bg7q0oAznexWfsmd9ik91OtuVjizKJQuuaRiJ3aOr5I" readonly style="display: none;">
<button onclick="check_form($('[name=email]').val(), $('[name=phone]').val(), $($(this).parent()), $('[name=error_place]'))">Отправить</button>
</form>
</body>
</html>

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Подключение оплаты со стороннего ресурса</title>
</head>
<body>
<form>
<input name="email">
<button onclick></button>
</form>
</body>
</html>

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script language="javascript" src="../static/js/prototype.js"></script>
<script language="javascript" src="../static/js/NTP.js"></script>
<script language="javascript">
NTP.sync();
</script>
</head>
<body>
</body>
</html>

File diff suppressed because it is too large Load Diff

@ -1,10 +0,0 @@
# coding=utf-8
import re
with open('1.txt', 'r') as myfile:
data=myfile.read()
r = re.compile(r"^[-a-z0-9!#$%&'*+/=?^_`{|}~]+(\.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*@([a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?\.)*(aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|[a-z][a-z])$")
n = re.compile(r'\w+$')
print r.findall(data)

@ -0,0 +1,62 @@
#! coding: utf-8
import os
import django
import sys
import os
from datetime import datetime
sys.path.append("/var/www/skillbox")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from lms.settings import BASE_DIR
from courses.models import Course
from finance.models import Price
from journals.models import TeacherJ, check_journal
def check_course_journal(course_id):
print('===========\nКурс: %s\n==============\n' % Course.objects.get(id=course_id).title)
print('Начало проверки журнала курса')
global_start = start = datetime.now()
course = Course.objects.get(id=course_id)
course.build_map()
finish = datetime.now()
print('Конец проверки журнала курса. Длительность: %s мсек\n' % (finish-start).microseconds)
print('Начало проверки услуг')
start = datetime.now()
all = Price.objects.filter(by_time=0, post_fire=0, course__id=course_id).count()
print('Количество услуг на проверку: %s' % all)
for i in Price.objects.filter(by_time=0, post_fire=0, course__id=course_id):
i.check_points()
finish = datetime.now()
print('Конец проверки услуг. Длительность: %s мсек\n' % (finish-start).microseconds)
print('Начало очистки двойных журналов')
start = datetime.now()
os.system('python clean_twice_course_journals.py %s' % course_id)
finish = datetime.now()
print('Конец очистки двойных журналов. Длительность: %s\n' % (finish-start).microseconds)
print('Начало проверки журналов')
all = TeacherJ.objects.filter(progress__gt=0, course__id=course_id).count()
print('Количество журналов на проверку: %s' % all)
for i in TeacherJ.objects.filter(progress__gt=0, course__id=course_id).order_by('-id'):
check_journal(i, from_console=True)
print('Конец проверки журналов. Длительность: %s сек\n' % (finish-start).microseconds)
print('Начало открытия уроков курса')
start = datetime.now()
os.system('python open_course_lesson.py %s' % course_id)
finish = datetime.now()
print('Конец открытия уроков курса. Длительность: %s\n' % (finish-start).microseconds)
global_finish = datetime.now()
print('==============================\nДлительность: %s сек' % (global_finish - global_start).seconds)
if __name__ == "__main__":
course_id = sys.argv[1]
check_course_journal(course_id)

@ -0,0 +1,74 @@
# coding=utf-8
import os
import django
import sys
import datetime
start = datetime.datetime.now()
sys.path.append("/var/www/skillbox/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from courses.models import Course, CourseTheme, Exam, Homework, Lesson
from journals.models import TeacherJ, CourseThemeJ, LessonJ, HomeworkJ, ExamJ
from access.models import User
from lms.tools import show_progress
def check_this(obj, collection):
if not collection.get(obj.material.id):
collection[obj.material.id] = True
else:
obj.delete()
def check_TJ(_course, _user):
try:
_tj = TeacherJ.objects.get(course=_course, student=_user)
except TeacherJ.DoesNotExist:
return None
except TeacherJ.MultipleObjectsReturned:
_tmp = TeacherJ.objects.filter(course=_course, student=_user).order_by('start_date')
_tj = _tmp[0]
for i in _tmp:
if i != _tj:
i.delete()
return _tj
course_id = sys.argv[1]
_all = User.objects.all().count()
_n = 0
_about_time = []
for _user in User.objects.all(): # todo only course users
_st = datetime.datetime.now()
_course = Course.objects.filter(id=course_id)
_l = dict({i.id: False for i in Lesson.objects.filter(course=_course)})
_h = dict({i.id: False for i in Homework.objects.filter(course=_course)})
_e = dict({i.id: False for i in Exam.objects.filter(course=_course)})
_t = dict({i.id: False for i in CourseTheme.objects.filter(course=_course)})
_tj = check_TJ(_course, _user)
if _tj:
for _cj in CourseThemeJ.objects.filter(parent=_tj):
check_this(_cj, _t)
for _lj in LessonJ.objects.filter(parent__parent=_tj):
check_this(_lj, _l)
for _hj in HomeworkJ.objects.filter(parent__parent=_tj):
check_this(_hj, _h)
for _ej in ExamJ.objects.filter(parent__parent=_tj):
check_this(_ej, _e)
_ft = datetime.datetime.now()
_about_time.append((_ft - _st).microseconds)
_average = (((_all - _n) * (sum(_about_time) / len(_about_time)))/1000000)/60
show_progress(_all, _n, post=' // "Удаление дуближей журналов" // Расчетное оставщееся время Этапа: {0:6.4} мин '.format(_average))
_n += 1
finish = datetime.datetime.now()
print('\nTIME: %s seconds' % (finish - start).seconds)

@ -1,3 +1,4 @@
# coding=utf-8
# Получить список файлов папки reports
# Выдать выбор отчета
# Запустить файл
@ -5,7 +6,7 @@ import os
import sys
BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
REPORTS = '/var/www/projects/codemy/_utils/reports'
REPORTS = '/var/www/skillbox/_utils/reports'
class CL:

@ -3,22 +3,22 @@ import os
import django
import sys
sys.path.append("/var/www/projects/codemy/")
sys.path.append("/var/www/skillbox/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from access.models import User
from finance.models import Price, Bill
users ={'anastasia.lednik@gmail.com', 'ivans@zeptolab.com', 'Kozingleb73@gmail.com', 'chaocharly@gmail.com', 'supreme1609@yandex.ru', 'julia.fedyaeva@mail.ru', 'me@leonidpotapov.com', 'axnaf@list.ru', 'yuri.sablatazh@gmail.com', 'strekozka_l@mail.ru', 'pavelulitin@fmf.ru', 's.zorin@artsofte.ru', 'mihail@kucherenko.tel', 'ikarp84@gmail.com', 'juliag@zeptolab.com', 'vr8853@gmail.com', 'o.tibirkova@yandex.ru', 'ivan.mesh@gmail.com', 'merabella00@yandex.ru', 'chavrikovev@gmail.com', 'azalmazal1@mail.ru', 'dimpolozkov@gmail.com', 'sidenkowow@mail.ru', 'evgeneva@gmail.com', 'olga@adt.ru', 'alexpallid@gmail.com', 'lllil@yandex.ru', 'reachi73@ya.ru', 'perepelkin.serge@gmail.com', 'el_spirito@bk.ru', 'ninon.sh@yandex.ru', 'smaslenikov@zeptolab.com', 'artemaminov@gmail.com', 'j4gg3rnaut@gmail.com', 'shavcat@ya.ru', 'rozzuvaeva@gmail.com', 'denis.mazaev@mail.ru', 'd.p.voropay@gmail.com', 'uasam@mail.ru', 'cornelldesign@mail.ru', 'jayalila108@mail.ru', 'vetldi@gmail.com', 'ggsurkov@gmail.com', 'freesleeper@gmail.com', 'ilya@iskros.com', 'rodina-vera@inbox.ru', 'hiirinasheveleva@gmail.com', 'lampardromanov@yandex.ru', 'kk.to-art@yandex.ru', 'zukoznik@mail.ru', 'annavolkova@at-consulting.ru', 'mister.ak90@mail.ru', 'tteya@mail.ru', 'egora@zeptolab.com', 'designprojectt@gmail.com', 'ottomy@bk.ru', 'alexander.samofalov@gmail.com', 'akonovalov108@gmail.com', 'kupa0611@gmail.com', 'vladimirprasoloff@gmail.com', 'appsdao@ya.ru', 'igor.n.tomko@gmail.com', '89226890628.sda@gmail.com', 'bara-bord@yandex.ru', 'chriswao@gmail.com', 'anastasiyabd@zeptolab.com', 'andrej.fin@gmail.com', 'litazavr@gmail.com', 'blckg0re@gmail.com', 'asiri.unholy@gmail.com', 'qq-brand@rambler.ru', 'delo@jet-mix.ru', 'hannakulikovast@gmail.com', 'kaiyoo@yandex.ru', 'ekaterinasch@zeptolab.com', 'artem.kudra@func.ru', 'irinash@zeptolab.com', 'nasgul@bk.ru', 'meetstone@yandex.ru', 'neo-quake@yandex.ru', 'Aka@make.st', 'giggslegenda@mail.ru', 'bebeeper@gmail.com', 'ez1982@yandex.RU', 'Hlebb@mail.ru', 'asylov@gmail.com', 'dirubis@gmail.com', 'nazarova-evg@yandex.ru', 'miragann@gmail.com', 'Grondarrin@gmail.com', 'eugened@zeptolab.com', 'o.slava@gmail.com', 'hellodrw@gmail.com', 'e.baranova@make.st', 'bvdesign@mail.ru', 'contrnik@yandex.ru', 'singlegreywolf@mail.ru', 'azatdraw@gmail.com', 'vaynberg.a@gmail.com', 'agnosst@gmail.com', 'tingaevva@mail.ru', 'ipashkov93@yandex.ru', 'anton.m.gook@gmail.com', 'Andreysh@zeptolab.com', 'proschebud@gmail.com', 'alik.vayner@gmail.com', 'd.lugansky@gmail.com', 'tanyas@zeptolab.com', 'markina108@gmail.com', 'gresmik@yandex.ru', 'Pvashkeba@mail.ru'}
users ={'kirillcapote@gmail.com', 'skyfallorigin@gmail.com', 'sadovnikoff@yandex.ru', 'grondarrin@gmail.com', 'fkaterina82@mail.ru', 'frtwork@gmail.com', 'yury.matskevich@gmail.com', 'ecoprint@mail.ru', 'yana1330@yandex.ru', 'rivera1985@mail.ru', 'paul.glukhov@gmail.com', 'elena.markina@xpage.ru', 'polinakomolova@gmail.com', 'etartakovskiy@gmail.com', 'p.jakubovskiy@gmail.com', 'malivanov@bk.ru', 'timplay@mail.ru', 'hello.kurban@gmail.com', 'ovm@aplayweb.ru', 'ux.dozer@gmail.com', 'pk.common@gmail.com', 'annapoluektova@yahoo.ca', 'nasti.vv@gmail.com', 'l4bor@protonmail.com', 'bogdashow@gmail.com', 'zhuck182@gmail.com', 'smannic@yandex.ru', 'victoriabutova@gmail.com', 'designprojectt@gmail.com', 'gartibald@gmail.com', 'alimova.lira@ya.ru', 'zaharenkoaleksey@yandex.ru', 'nataliannovgorod@gmail.com', 'kravtsova.kateryna@gmail.com', 'andrerm@ya.ru'}
no_exists = []
no_active = []
no_bill = set()
service = Price.objects.filter(course__id=20).exclude(cost=0)
service = list(Price.objects.filter(course__id=20).values_list('id', flat=True))
for i in users:
for i in users:
try:
user = User.objects.get(email=i)
except User.DoesNotExist:
@ -27,19 +27,13 @@ for i in users:
if not user.is_active:
no_active.append(i)
else:
good = True
for s in service:
bill = Bill.objects.filter(user=user, service=s)
if bill:
bill = bill.first()
if bill.status != 'F':
bill.status = 'F'
bill.save()
print(u'Смена статуса заказа: {0}'.format(bill.id))
else:
good = False
if not good:
if Bill.objects.filter(user=user, service__id__in=service).exists():
for bill in Bill.objects.filter(user=user, service__id__in=service):
if bill and bill.status != 'F':
bill.status = 'F'
bill.save()
print(u'Смена статуса заказа: {0}'.format(bill.id))
else:
no_bill.add(user.email)
print('u===============')

@ -0,0 +1,199 @@
# coding=utf-8
import os
import django
import sys
import datetime
sys.path.append("/var/www/skillbox")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from journals.models import CourseMap, LessonJ, TeacherJ, HomeworkTry
from lms.tools import show_progress
_NEED_OPEN = LessonJ.objects.get(material__id='1154', student__email='parabellum07@gmail.com')
_TEACHERJ_FILTER = {'progress__gte': 0}
_TEACHERJ_EXCLUDE = {'teacher': None}
_READL_FILTER = {'f_date': None}
_READL_EXCLUDE = {'date': None}
_SUCCESSL_FILTER = {'success': True}
_SUCCESSL_EXCLUDE = {'date': None}
def get_all_journals(course_id):
return TeacherJ.objects.filter(**_TEACHERJ_FILTER, course__id=course__id).exclude(**_TEACHERJ_EXCLUDE).order_by('id')
def get_all_journals_count():
return TeacherJ.objects.filter(**_TEACHERJ_FILTER).exclude(**_TEACHERJ_EXCLUDE).count()
def get_last_lessons(__journal):
# Получить последний читаемый уроки и выполненный
_READL_FILTER['student'] = __journal.student
_READL_FILTER['material__course'] = __journal.course
_SUCCESSL_FILTER['student'] = __journal.student
_SUCCESSL_FILTER['material__course'] = __journal.course
return (LessonJ.objects.filter(**_READL_FILTER).exclude(**_READL_EXCLUDE).order_by('id').last(),
LessonJ.objects.filter(**_SUCCESSL_FILTER).exclude(**_SUCCESSL_EXCLUDE).order_by('id').last())
def open_lesson_befor_this(_lessonJ):
# Погружается объект последнего журнала урока
# Получаем все уроки этого журнала
_map = CourseMap.objects.get(lesson=_lessonJ.material)
for i in CourseMap.objects.filter(course=_map.course).exclude(lesson=None):
if i.sort < _map.sort:
try:
_j = LessonJ.objects.get(
material__token=i.token,
student=_lessonJ.student,
material__course=i.course
)
except LessonJ.DoesNotExist as e:
print(e)
else:
check_to_success(_j)
def check_to_access(_journal):
# Проверка материала на доступ в прохождению
_journal.open_material()
def check_to_success(_journal):
# Проверка материала на завершенность
_journal.saw_this()
def check_lesson_after_hw(__journal, _target):
# Проверить - доступны ли уроки до ДЗ со статусом success
# Проверить - доступны ли видео до ДЗ не блокированного или пройденного
_last = HomeworkTry.objects.filter(
student=__journal.student,
material__course=__journal.course
).order_by('id').last()
# Если стутс - success
_candidate = None
if _last:
try:
_candidate = CourseMap.objects.get(
sort=int(CourseMap.objects.get(token=_last.material.token).sort)+1,
course=__journal.course
)
except CourseMap.DoesNotExist:
print('Ошибка получения карты журнала')
else:
# Проверить - доступен ли журнал для чтения
if _candidate.lesson:
__candidate = LessonJ.objects.get(
material__token=_candidate.token,
student=_target.student,
material__course=__journal.course
)
check_to_access(__candidate)
if _candidate and _candidate.lesson and \
int(CourseMap.objects.get(
token=_target.material.token,
course=__journal.course).sort) \
< int(_candidate.sort):
_target = LessonJ.objects.get(
material__token=_candidate.token,
student=_target.student,
material__course=__journal.course)
print('Цель изменена: %s' % _target.material.title)
return _target
def main(course_id):
start = datetime.datetime.now()
_ERRORS = set()
_WARNING = set()
#for i in open('error.log'):
# _ERRORS.add(i.strip())
_GOOD = 0
_now = 0
big = []
if _NEED_OPEN:
open_lesson_befor_this(_NEED_OPEN)
else:
if not _ERRORS:
_journals = get_all_journals(course_id)
_jcount = get_all_journals_count()
print('Количество журналов на проверку: %s' % _jcount)
else:
_journals = list([i for i in TeacherJ.objects.filter(student__email__in=_ERRORS)])
_jcount = len(_journals)
print('Журналы с ошибками: %s' % _jcount)
for __journal in _journals:
_start = datetime.datetime.now()
show_progress(_jcount, _now)
print('\nЖурнал: %s' % __journal.student.email)
try:
read, success = get_last_lessons(__journal)
except Exception as e:
print('!!! Ошибка обработки')
print(e)
if __journal.course.id == 20:
_WARNING.add(__journal.student.email)
_ERROR_MAILS = open('error.log', 'a+')
_ERROR_MAILS.write('%s\n' % __journal.student.email)
_ERROR_MAILS.close()
else:
print('%s // %s' % (read.material.title if read else ' - ', success.material.title if success else ' - '))
if not success and read:
_target = read
elif read and (int(CourseMap.objects.get(lesson=read.material).sort) > int(CourseMap.objects.get(lesson=success.material).sort)):
_target = read
elif success:
_target = success
else:
_target = None
if _target:
open_lesson_befor_this(check_lesson_after_hw(__journal, _target))
_GOOD += 1
_now += 1
_finish = datetime.datetime.now()
_time_result = (_finish - _start).seconds
print('\nTIME: %s seconds' % _time_result)
if int(_time_result) > 1:
big.append(__journal.student.email)
print('Добавлено на проверку')
print('===========\n')
finish = datetime.datetime.now()
print('\nTIME: %s seconds' % (finish - start).seconds)
print('Нужно обратить внимание:')
for i in _WARNING:
print(i)
#print('Самые длительные записи:')
#print(big)
if _ERRORS:
if _GOOD == _now:
print('Все ошибки исправлены')
else:
print('Количество ошибок: %s' % int(_now - _GOOD))
if __name__ == '__main__':
course_id = sys.argv[1]
main(course_id)

@ -11,7 +11,7 @@ django.setup()
from journals.models import CourseMap, LessonJ, TeacherJ, HomeworkTry
from lms.tools import show_progress
_NEED_OPEN = LessonJ.objects.get(material__id='1154', student__email='parabellum07@gmail.com')
_NEED_OPEN = LessonJ.objects.get(material__id='1154', student__email='parabellum07@gmail.com'.lower())
_TEACHERJ_FILTER = {'progress__gte': 0}
_TEACHERJ_EXCLUDE = {'teacher': None}

@ -4,7 +4,7 @@ import django
import sys
sys.path.append("/var/www/projects/codemy/")
sys.path.append("/var/www/skillbox/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
print('## Формирование списка почт всех студентов системы')

@ -3,7 +3,7 @@ import os
import django
import sys
sys.path.append("/var/www/projects/codemy/")
sys.path.append("/var/www/skillbox/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
print('## Отчет по распределению слушателей по курсу')
@ -32,4 +32,3 @@ print('ДЗ в статусе прохождения: {0}'.format(_homeworks.cou
for i in CourseTheme.objects.filter(course=_course).order_by('sort'):
print('{0}: {2} [{1}]'.format(i.sort, i.get_title(), HomeworkJ.objects.filter(f_date=None, parent__material=i).exclude(date=None).count()))

@ -5,7 +5,7 @@ import django
import sys
BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append("/var/www/projects/codemy/")
sys.path.append("/var/www/skillbox/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from access.models import User

@ -3,7 +3,7 @@ import os
import django
import sys
sys.path.append("/var/www/projects/codemy/")
sys.path.append("/var/www/skillbox/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
print('## Отчет по распределению слушателей по курсу')

@ -5,7 +5,7 @@ import django
import sys
BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append("/var/www/projects/codemy/")
sys.path.append("/var/www/skillbox/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from access.models import User

@ -3,7 +3,7 @@ import os
import django
import sys
sys.path.append("/var/www/projects/codemy/")
sys.path.append("/var/www/skillbox/")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()

@ -24,7 +24,7 @@ def find_user(request, context):
if request.user.is_authenticated() and request.user.in_role in ['T', 'S2', 'A']:
if request.GET.get('user'):
context['code'] = '1'
context['data'] = [{'str': str(user), 'ava': user.get_image_url(), 'email': user.email, 'id': user.id} for user in User.objects.filter(email__icontains=request.GET['user'])]
context['data'] = [{'str': str(user), 'ava': user.get_image_url(), 'email': user.get_email(), 'id': user.id} for user in User.objects.filter(email__icontains=request.GET['user'])]
else:
context['response'] = u'Параметры не переданы'
context['code'] = '0'
@ -103,7 +103,7 @@ def send_settings_data(request, context):
return context
if request.POST.get('user_settings_email') and check_email(request.POST['user_settings_email']):
if request.POST['user_settings_email'].lower() != request.user.email:
if request.POST['user_settings_email'].lower() != request.user.get_email():
email = request.POST['user_settings_email'].lower()
if not User.objects.filter(email=email).exists():
request.user.changed_email = request.POST['user_settings_email'].lower()
@ -136,7 +136,7 @@ def get_settings_data(request, context):
'name': request.user.name,
'oname': request.user.oname,
'phone': request.user.get_phone(),
'email': request.user.email,
'email': request.user.get_email(),
'city': request.user.city,
'bday': ''
}

@ -1,5 +1,6 @@
# encoding=utf-8
import random
import re
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
import datetime
@ -68,7 +69,7 @@ class UserManager(BaseUserManager):
user = self.model(email=email)
user.set_password(password)
user.token = random_string(length=10, postfix=user.email)
user.token = random_string(length=10, postfix=user.get_email())
user.save(using=self._db)
insert_in_system(user, sent_letter=sent_letter)
return user
@ -79,7 +80,7 @@ class UserManager(BaseUserManager):
user.is_active = True
user.superuser = True
user.is_staff = True
user.token = random_string(length=10, postfix=user.email)
user.token = random_string(length=10, postfix=user.get_email())
user.save(using=self._db)
return user
@ -279,6 +280,9 @@ class User(AbstractBaseUser):
def get_back_phone(self):
return self.back_phone
def get_email(self):
return self.email
def get_full_name(self):
result = u""
# Если есть фамилия пишем: Фамилия Имя Отчество
@ -339,6 +343,14 @@ class User(AbstractBaseUser):
return u"<span user-id='%s' action-type='user_data' class='pseudo_link' style='margin-right:0;'>%s</span>" \
% (self.id, self.get_short_name())
def check_phone(self, _type='actual'): # actual = self.phone, back = self.back_phone
phone = self.phone if _type == 'actual' else self.back_phone
return bool(len(''.join([n for n in phone if n in [str(x) for x in xrange(0,10)]])) > 9)
def clean_phone(self, _type='actual'):
return ''.join([n for n in self.phone if n in [str(x) for x in xrange(0,10)]]) if self.check_phone() else ''
class Meta:
verbose_name = u"Пользователя"
verbose_name_plural = u"Пользователи"

@ -3,10 +3,26 @@ chdir = %(project_path)s/
env = DJANGO_SETTINGS_MODULE=lms.settings
virtualenv = %(project_path)s/env
module = lms.wsgi:application
master = true
processes = 4
workers = 6
socket = %(project_path)s/app.sock
logto = /var/log/uwsgi/skillbox.uwsgi.log
master = true
#processes = 8
workers = 24
# TODO configure memory lims and cheaper limits
harakiri = 220s
# disable request logging HTTP/200
disable-logging = true
log-slow = 45s
log-5xx = true
log-4xx = true
log-big = 500000
stats = :5050
harakiri-verbose = true
enable-threads = true
thunder-lock = true
reload-mercy = 220s
worker-reload-mercy = 220s
mule-reload-mercy = 220s
chmod-socket = 666
vacuum = true
plugins = python35

@ -78,7 +78,8 @@ class Course(models.Model):
description = RedactorField(verbose_name=u'Описание', blank=True)
image = models.ImageField(verbose_name=u'Изображение', upload_to='course', blank=True)
big_image = models.ImageField(verbose_name=u'Большое изображение', upload_to='course', blank=True)
big_mobile_image = models.ImageField(verbose_name=u'Под мобилку', upload_to='course', blank=True, null=True, help_text=u'Большая картинка для мобильной версии')
big_mobile_image = models.ImageField(verbose_name=u'Под мобилку', upload_to='course', blank=True, null=True,
help_text=u'Большая картинка для мобильной версии')
page = models.URLField(verbose_name=u'Страничка описания', blank=True, default='')
preview = models.CharField(verbose_name=u'Трэйл', blank=True, default='', max_length=255)
teachers = models.ManyToManyField(User, verbose_name=u'Преподаватели', related_name='course_teachers')
@ -90,7 +91,9 @@ class Course(models.Model):
buy_icon = models.ImageField(verbose_name=u'Картинка покупки', upload_to='course', blank=True, null=True)
must_build = models.BooleanField(verbose_name=u'На переформировку', default=False)
keywords = models.ManyToManyField(Tags, verbose_name=u'Ключевые слова', blank=True)
recommend = models.ManyToManyField('self', verbose_name=u'Связанные курсы', blank=True, help_text=u'Курсы, которые стоит порекомендовать вместе с этим')
recommend = models.ManyToManyField('self', verbose_name=u'Связанные курсы', blank=True,
help_text=u'Курсы, которые стоит порекомендовать вместе с этим')
def __str__(self):
return self.title
@ -156,7 +159,7 @@ class Course(models.Model):
def get_description(self):
# Получить описание курса
return self.description
def get_skills(self):
# Получить скилы темы
result = []

@ -17,7 +17,7 @@ def new_request(request, context):
s = ServiceRequest.objects.create(
lead_name=urllib.parse.unquote(request.POST['lead_name'], encoding='utf8').replace("+", " "),
send_date=date,
data=str({i: urllib.parse.unquote(n, encoding='utf8').replace("+", " ") for i, n in request.POST.items()})
data=str({i: urllib.parse.unquote(n, encoding='utf8').replace("+", " ") for i, n in request.POST.items()}).replace('"', '')
)
if request.META.get('HTTP_REFERER'):
s.host = request.META.get('HTTP_REFERER')

@ -395,6 +395,9 @@ class ServiceRequest(models.Model):
'lead_name': self.get_lead_name()
}
if data['name'] == '':
data['name'] = 'empty'
urllib.request.urlopen(out_uri('https://skill-box.ru/amocrm/CreateLead.php', data))
if not self.send:
data['host'] = self.host

@ -1,3 +1,5 @@
#! coding: utf-8
from django.contrib import admin
from django.db.models import Q
from django.http import HttpResponse

@ -22,6 +22,16 @@ TEST_EMAIL = 'bez.b.unix@gmail.com'
TEACHER = 't@skillbox.ru'
SUPERVISOR = 's@skillbox.ru'
MANAGER = 'm@skillbox.ru'
MANAGERS = [
'maksim.shachkov@skillbox.ru',
'aleksey.zelentsov@skillbox.ru',
'roman.fatullaev@skillbox.ru',
'vladimir.kakaulin@skillbox.ru',
'dmitry.perepelitsa@skillbox.ru',
'timofey.trifonov@skillbox.ru',
'sergej.gavrilovich@skillbox.ru',
]
SUPPORT = 'hello@skillbox.ru'
SUPPORT_PHONE = '+7 (495) 984-41-77'
SUPPORT_TIME = '(с 10 до 19 по Москве)'

@ -5,7 +5,7 @@ from access.models import User
from lms.decors import api_decor
from lms.tools import out_date_format, condition_factory, user_fabric
from finance.models import Price, Bill, ServiceRequest
from management.letters import sent_new_bill, sent_clean_letter
from management.letters import sent_new_bill, sent_clean_letter, send_burning_course_letter
from management.models import News, Feedback, Comment
@ -94,7 +94,8 @@ def new_bill(request, context):
service = Price.objects.get(id=request.POST['new_bill_checked_service'])
bill = Bill.objects.create(user=user,
service=service,
manager=request.user, price=request.POST['new_bill_cost'],
manager=request.user,
price=request.POST['new_bill_cost'],
description=request.POST.get('new_bill_comment') if request.POST.get(
'new_bill_comment') else '')
sent_new_bill(bill)
@ -117,6 +118,7 @@ def new_bill(request, context):
return context
@api_decor(without_auth=False)
def sent_charge(request, context):
if request.user.in_role == 'S' or request.user.in_role == 'A':
@ -162,3 +164,11 @@ def read_comment(request, context):
if not comment.saw.filter(id=request.user.id).exists():
comment.saw.add(request.user)
return context
@api_decor(without_auth=False)
def burning_course(request):
course = Course.objects.get(id=request.GET['course'])
user = User.objects.get(id=request.GET['id'])
send_burning_course_letter(user, course)

@ -1,3 +1,5 @@
# coding=utf-8
from django.http import Http404
from lms.decors import response_decor
from management.models import Comment

@ -5,7 +5,7 @@ from django.template.loader import get_template
from lms.tools import out_date_format
from lms.settings import DOMAIN, DEFAULT_FROM_EMAIL, NAME
from management.mails import letter_decor
from random import choice
TEST_EMAIL = 'bez.b.unix@gmail.com'
@ -246,6 +246,9 @@ def sent_new_bill(bill):
'PRICE': bill.price,
'USER': bill.user.email,
'SERVICE': bill.get_name(),
'MANAGER': bill.manager.get_full_name(),
'MANAGER_EMAIL': bill.manager.get_email(),
'FILE': bill.service.course.get_description_file,
'DOMAIN': DOMAIN,
'NAME': NAME
}
@ -466,3 +469,69 @@ def free_week_end(bill, email):
'type': u'Продажи'
}
return data
@letter_decor()
def exam_is_nearly(user, course):
name = user.get_full_name()
email = user.get_email()
data = {
'title': u'Студент близится к экзамену',
'email': SUPPORT,
'text': u'' + student +' закончил 15 тему. Скоро будет сдавать экзамен. Готовьтесь \n'
u'Почта: ' + email + '\n'
u'id: ' + user.id + '\n'
u'Курс: ' + course + '\n',
'type': u'Оповещения',
}
return data
@letter_decor()
def exam_successfull(user, course):
student = user.get_full_name()
email = user.get_email()
phone = user.get_phone()
data = {
'title': u'Студент сдал экзамен',
'email': SUPPORT,
'text': u'' + student + 'сдал экзамен. Позвони ему и поздравь'
u'Информация о студенте:'
u'Почта: ' + email + '\n'
u'id: ' + user.id + '\n'
u'Телефон: ' + phone + '\n'
u'Курс: ' + course + '\n',
'type': u'Оповещения'
}
return data
@letter_decor()
def long_time_no_see():
data = {
'title': u'',
'email': TEST_EMAIL,
'text': u'',
'type': u'Оповещения'
}
return data
@letter_decor()
def send_burning_course_letter(user, course):
data = {
'title': u'Студент закончил временный курс',
'email': choice(MANAGERS),
'text': u'Чувак закончил временный курс или хочет посмотреть урок, который недоступен: ' + course + '\n'
u'Может стоит предложить купить весь курс?\n',
u'Информация о студенте:\n'
u'Почта: ' + user.email + '\n'
u'Имя: ' + user.get_full_name() + '\n'
u'Телефон: ' + user.get_phone() + '\n'
u'Курс: ' + course + '\n'
'type': u'Продажи'
}
return data

@ -12,6 +12,7 @@ def letter_decor():
text=data['text'],
_type=data['type'],
template=data['template'] if data.get('template') else '',
result=data['result'] if data.get('result') else None)
result=data['result'] if data.get('result') else None,
file=data['file'])
return _render_json
return wrap_response

@ -1,3 +1,5 @@
# coding=utf-8
from management.models import ModalPlace

@ -20,6 +20,7 @@ urlpatterns = [
url(r'sent_charge$', api.sent_charge),
url(r'new_feedback/$', api.new_feedback),
url(r'read_comment$', api.read_comment),
url(r'burning_course/$', api.burning_course),
url(r'faq/([0-9]{1,99})$', views.faq_one),
url(r'faq/$', views.faq),
url(r'progress_report/$', views.progress_report),

@ -1,3 +1,5 @@
# coding=utf-8
from django.http import Http404
from lms.decors import api_decor

@ -1,3 +1,5 @@
# coding=utf-8
from django.http import Http404
from lms.decors import response_decor
from practice.models import Workshop

@ -71,3 +71,4 @@ wcwidth==0.1.7
widgetsnbextension==1.2.6
xlwt==1.1.2
fabric

@ -6355,4 +6355,55 @@ box-shadow: 0 12px 35px 0 rgba(134, 173, 253, 0.4);
}
.label-progress:hover{
height: 10px;
}
}
#teacher_popup{
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
position: absolute;
top: 0px;
right: 0px;
z-index: 100000;
}
.teacher_popup{
border: 2px solid #fff;
position: absolute;
width: 400px;
height: 226px;
left: 50%;
margin-left: -200px;
margin-top: 150px;
font-size: 22px;
background-color: #f9f9f9;
font-size: 22px;
padding: 30px;
bottom: 400px;
}
.realy{
width: 100%;
height: 80px;
line-height: 40px;
text-align: center;
color: #000;
margin-bottom: 20px;
}
#yes, #no{
border: 1px solid #fff;
width: 168px;
height: 60px;
text-align: center;
line-height: 60px;
cursor: pointer;
}
#yes{
float: left;
font-size: 20px;
background-color: #27c24c;
border-radius: 7px 0 0 7px;
}
#no{
float: right;
font-size: 20px;
background-color: #f05050;
border-radius: 0 7px 7px 0;
}

@ -139,6 +139,16 @@ function open_service_request_window(course){
}
}
function send_letter_to_manager(course){
if ($('[name=REQUEST_USER_ID]').val() != 'None'){
$.ajax({
type: 'GET',
url: '/management/send_letter_to_manager',
data: {'id': $('[name=REQUEST_USER_ID]').val(), 'course': course},
success: function(){},
})
}
}
function open_journal_request_window() {
$('#journalAccess').modal('show');
}

@ -68,9 +68,23 @@ function send_homework_down_teacher(form, root){
show_system_message('Введите текст сообщения')
}
}
function show_popup(){
// нужно было сделать быстро - поэтому сделали гавно (с) skillbox
// нужно переделать под jquery
// сделать тоже самое и для кнопки отказать.
// Хороший способ передавать функцию отправки (up & down) сюда и здесь её запускать
popup = document.getElementById('teacher_popup')
popup.classList.toggle('hidden')
popup.onclick = function(e){
if e.target == this{
popup.classList.add('hidden')
}
}
}
function send_homework_up_teacher(form, root){
// Проверить комментарий
// Отправить
document.getElementById('teacher_popup').classList.add('hidden')
if (CKEDITOR.instances.homework_text.getData()){
$('[name=homework_text]').val(CKEDITOR.instances.homework_text.getData());
$.ajax({

@ -0,0 +1,127 @@
Жиров Олег, niozuki@mail.ru, 5016
Лавриненко Светлана, svelavs@gmail.com, 4648
Санжар Суршанов, sanzharsurshanov@gmail.com, 4749
Моторина Екатерина, katepainter@yandex.ru, 4424
Белонович Гаянэ, gb.gayane@gmail.com, 4747
Злобин Иван, baho9208@mail.ru, 4569
Киселев Сергей, kiselev_s_l@mail.ru, 5307
Мокичев Дмитрий, dmokichev@gmail.com, 5941
Якухина Кира, kira.yakuhina@gmail.com, 4917
Кулаев Виктор, geiz@yandex.ru, 4795
Зайидова Aнна, annazayidova@gmail.com, 5039
Демосюк Екатерина, ekde@wide-web.spb.ru, 5593
Анастасова Светлана, zvetaan@gmail.com, 4751
Киосов Георгий, goha@kiosov.com, 5240
Мирзаева Кира, jalalovna@yandex.ru, 5687
Донцов Александр, alex.dntv@gmail.com, 4659
Попов Александр, ap@ds-p.ru, 5362
Жоламанов Айдар, pobiz@inbox.ru, 4632
Ковальская Станислава, skovalska@mail.ru, 5597
Исаев Дмитрий, wrusha@yandex.ru, 4634
Павлов Иван, pavlov@complexsys.ru, 5069
Жарков Александр, alexzarkov@gmail.com, 5657
Тихонов Александр, 9330733@mail.ru, 4865
Залисский Артем, artemzig@gmail.com, 6030
Тмур Антон, anton.tmur@gmail.com, 5877
Масленников Михаил, mmaslennikov@mail.ru, 5510
Пешинский Евгений, jack@creo.od.ua, 5930
Тухачевский Дмитрий, tuhachevski@gmail.com, 5911
Копачинский Константин, fazeful@gmail.com, 6115
Рыжков Антон, tonyavec@gmail.com, 6029
Сипатов Андрей, madjaw@mail.ru, 296
Литвин Максим, corpas@gmail.com, 4730
Шульга Игорь, ishulga86@gmail.com, 5600
Макаров Алексей, avmakarov@asuproject.ru, 6122
Фадеева Елена, alpha5@yandex.ru, 5926
Палий Нина, slavinanm@gmail.com, 6117
Портнова Оксана, portnova.ok@yandex.ru, 5947
Копылова Христиана, blood4085@inbox.ru, 6037
Галин Олег, ogalin@aevrika.ru, 5932
Богданова Евгения, egysakova@gmail.com, 5945
Дёмушкин Виктор, dinozavrix@gmail.com, 5610
Бодров Илья, feyorz@gmail.com, 4652
Махаева Василиса, kornblumchen@yandex.ru, 5756
Трунова Ольга , trunovaon@gmail.com, 5759
Аплемах Антон, a@cdnvideo.ru, 6034
Павлов Алексей, kronos2k4@gmail.com, 4514
Манасян Георгий, gsm_elst@rambler.ru, 5939
Umnikov Aleksandr Сергеевич, strife88@mail.ru, 5919
Самородова Анастасия, polgolovy@gmail.com, 4736
Лемтюгова Катерина, lemma.ka@gmail.com, 4900
Свинин Александр Александрович, alexandersvinin@gmail.com, 4541
Поздняков Александр Сергеевич, alexpozdnyakof@gmail.com, 5459
Климов Василий, vklimovs@mail.ru, 6047
Воротникова Алена, alvo_05@mail.ru, 4742
Аникьев Ян, yanchus@mail.ru, 6041
Энч Андрей, captainanch@ya.ru, 5936
Вусс Ольга, lesiawuss@gmail.com, 6619
Крюков Денис, denis.kryukov@cyberiada.com, 5976
Пастухова Екатерина, k-pastukhova@yandex.ru, 6832
Кубасова Екатерина, cat.kubasova@yandex.ru, 6136
Сутырина Евгения, jeneva7@gmail.com, 6965
Вычик Павел, pavelvch@gmail.com, 7033
Семашко Эдуард, info@darneo.ru, 5584
Брюханов Денис, denisbryuhanov@gmail.com, 6962
Плахов Павел, pplahov@gmail.com, 6775
Подгорный Евгений, sonicmails@yandex.ru, 6977
Пионтковская Наталья, pnz_08@mail.ru, 5977
Ганина Ольга, onimfa@mail.ru, 6867
Коробицин Иван, korobajr@ya.ru, 5504
Денисов Владимир, dv@ilab.kz, 6208
Pavlovska Anastasiia, 702752@gmail.com, 5363
Карпов Александр Юрьевич, ikarp84@gmail.com, 6646
Афанасьев Ярослав, ya@rl.ru, 6633
Скробот Алексей, alekseyskrobot@gmail.com, 6942
K Sergey, 1ngeneer@mail.ru, 6032
Мельбурн Саша, sasha.melbourne@gmail.com, 5540
Гулин Евгений, gulin@labizum.ru, 4759
Литвин Артем, artemich92@mail.ru, 6779
Киреичев Игорь, wm5soft@gmail.com, 6061
Степанов Александр, alexsteptlt@mail.ru, 6616
Кропанев Женя, kropev@rarus.ru, 4757
Курылев Константин, cooryliof@gmail.com, 6241
Казарова Елена, strekozka_l@mail.ru, 8207
Епифанов Павел, pae1@europlan.ru, 6471
Долженков Роман, tooob52@gmail.com, 6976
Антоневич Алексей, atree2010@gmail.com, 7169
Burchilina Maria, merabella00@yandex.ru, 7770
Агарзаева Марина, agarzaeva@yandex.ru, 6939
Сидоренко Илья , ilya@iskros.com, 7564
Китов Владислав, vlkitov@gmail.com, 6038
Репкин Антон, tingmann@gmail.com, 5943
Протасевич Андрей, torus.andrey@gmail.com, 6062
Велькин Андрей, wellkin@gmail.com, 5974
Савченко Игорь, neo-quake@yandex.ru, 6752
Ромаметьева Евгения, zhenyusya14@gmail.com, 6063
Щербакова Ольга, olga@adt.ru, 7769
Пашкевич Алексей , aplusp@yandex.ru, 6328
Бурунин Игорь, burunin@gmail.com, 7974
Боев Максим, skp_15@mail.ru, 6966
Сухоставская Алла, alla.sukhostavskaya@gmail.com, 6739
Шашкова Ольга, shashnia@gmail.com, 7007
Малахова Екатерина, kononenko.e.p@gmail.com, 6312
Саросек Михаил, sarosekml@yandex.ru, 7026
Царенко Илья, itsarenko@gmail.com, 6724
Соловьева Анна, miragann@gmail.com, 7656
Дементьев Сергей, ldvmake@gmail.com, 8219
Борисова Ирина, i.k.borisova@gmail.com, 8362
Макеев Сергей , makini@ya.ru, 8313
Гук Антон, anton.m.gook@gmail.com, 8031
Колмогоров Дмитрий, kitt.diz@gmail.com, 7217
Фомина Елена, efomina@msk.vtb.ru, 6120
Назарова Евгения, nazarova-evg@yandex.ru, 7666
Сергиенко Ольга Александровна , jayalila108@mail.ru, 7275
Зарипов Алмаз, almazzar@gmail.com, 9381
Ахкямова Эльвира, juniperland@gmail.com, 4929
Рубцова Ирина, beruchie@yandex.ru, 6968
Багаммаева Мадина, galadriel2007@mail.ru, 6951
Четвериков Юрий, yuriy.chetverikov@gmail.com, 7168
Маклакова Мария, tuna1706@yandex.ru, 6580
Монаков Евгений, fridays365@gmail.com, 8637
Прохоров Алексей, alex@space-o.ru, 6436
Зайцев Никита, nickzaytzev@gmail.com, 6635
Кожевников Андрей, helloandrei@mail.ru, 9536
Лисивец Юрий Станиславович, lisivets@ya.ru, 7318
Келемзина Софья, sofiakelemzina@gmail.com, 6204
Зорина Алина, alinazoryna@gmail.com, 5973
Кунакулов Ахнаф, axnaf@list.ru, 7733

@ -146,7 +146,20 @@ html, body {background-image: none !important; background-color: transparent !im
<tbody><tr><td valign="top" style="padding: 0px;"><table cellpadding="0" cellspacing="0" width="100%">
<tbody><tr><td style="padding: 0px;"><table cellpadding="0" cellspacing="0" border="0" width="100%">
<tbody><tr><td valign="top" style="padding-top: 20px; padding-right: 30px; padding-bottom: 5px; padding-left: 30px;"><table cellpadding="0" cellspacing="0" border="0" width="100%">
<tbody><tr><td valign="top"><div style="text-align: left; font-family: Helvetica, Helvetica Neue, Arial; font-size: 14px; color: #000000; line-height: 14px; mso-line-height: exactly; vertical-align: middle;"><h1 style="font-family:Helvetica, Helvetica Neue, Arial; font-size: 20px; color: #000000; line-height: 32px; mso-line-height: exactly; vertical-align:middle;padding: 0; margin: 0;">{{ USER }}, вам выставлен счет для оплаты.</h1><p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;"><span style="color:#808080;">Состав заказа: </span>{{ SERVICE }}</p><p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;"><span style="color:#808080;">Сумма для оплаты: </span>{{ PRICE }} руб.</p><p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;">Чтобы выбрать способ оплаты и оплатить данный счет, воспользуйтесь ссылкой: <a href="{{ LINK }}" style="color: #22a8f2 !important; text-decoration: underline !important;" target="_blank"><font style=" color:#22a8f2;">{{ LINK }}</font></a></p><p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;">или кнопкой ниже</p><p style="padding: 0; margin: 0;">&nbsp;</p></div></td>
<tbody><tr><td valign="top"><div style="text-align: left; font-family: Helvetica, Helvetica Neue, Arial; font-size: 14px; color: #000000; line-height: 14px; mso-line-height: exactly; vertical-align: middle;"><h1 style="font-family:Helvetica, Helvetica Neue, Arial; font-size: 20px; color: #000000; line-height: 32px; mso-line-height: exactly; vertical-align:middle;padding: 0; margin: 0;">{{ USER }}, вам выставлен счет для оплаты.</h1>
<p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;">&nbsp;</p>
<p style="padding: 0; margin: 0;"><span style="color:#808080;">Состав заказа: </span>{{ SERVICE }}</p><p style="padding: 0; margin: 0;">&nbsp;</p>
<p style="padding: 0; margin: 0;"><span style="color:#808080;">Сумма для оплаты: </span>{{ PRICE }} руб.</p><p style="padding: 0; margin: 0;">&nbsp;</p>
<p style="padding: 0; margin: 0;">
<span style="color:#808080;">Ваш менеджер: </span> </p>
<p style="padding: 0; margin: 0;">&nbsp;</p>
<p> {{ MANAGER }} </p>
<p style="padding: 0; margin: 0;">&nbsp;</p>
<p>{{ MANAGER_EMAIL }}</p>
<p style="padding: 0; margin: 0;">&nbsp;</p>
{% if FILE %} <a href="{{ FILE }}">Программа курса</a> {% endif %}
<p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;">Чтобы выбрать способ оплаты и оплатить данный счет, воспользуйтесь ссылкой: <a href="{{ LINK }}" style="color: #22a8f2 !important; text-decoration: underline !important;" target="_blank"><font style=" color:#22a8f2;">{{ LINK }}</font></a></p><p style="padding: 0; margin: 0;">&nbsp;</p><p style="padding: 0; margin: 0;">или кнопкой ниже</p><p style="padding: 0; margin: 0;">&nbsp;</p></div></td>
</tr>
</tbody></table>
</td>

@ -5,6 +5,12 @@
<script src="/static/js/ckeditor/adapters/jquery.js"></script>
{% endblock %}
{% block content %}
<div id="teacher_popup" class="hidden">
<div class=teacher_popup>
<div class="realy">Вы уверены, что хотите принять домашнюю работу?</div>
<div id="no" onclick="show_popup()">Нет</div><div id="yes" onclick="send_homework_up_teacher('comment_send_form', 'form_file_load')">Да</div>
</div>
</div>
<div class="wrapper-md">
<h1 style=" margin-bottom: 20px;
margin-top: 0;">Тема №{{ theme.sort }}: {{ theme.title }}</h1>

Loading…
Cancel
Save