main.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. import datetime
  2. import os
  3. import logging
  4. from flask import Flask, render_template, request, url_for
  5. from flask_login import login_user, current_user, LoginManager, logout_user, login_required
  6. from flask_wtf import CSRFProtect
  7. from flask_restful import abort
  8. from werkzeug.datastructures import CombinedMultiDict
  9. from werkzeug.utils import redirect
  10. from itsdangerous import URLSafeTimedSerializer, SignatureExpired
  11. from sqlalchemy import or_
  12. from json import loads
  13. from functions import check_password, mail, init_db_default, get_projects_data, get_user_data, save_project_logo, \
  14. overdue_quest_project, save_proof_quest, find_files_answer, file_tree, delete_project_data, delete_quest_data
  15. from forms.edit_profile import EditProfileForm
  16. from forms.login import LoginForm
  17. from forms.find_project import FindProjectForm
  18. from forms.register import RegisterForm
  19. from forms.project import ProjectForm, AddFileProject
  20. from forms.recovery import RecoveryForm, NewPasswordForm
  21. from forms.conf_delete_project import DeleteProjectForm
  22. from forms.task import Task, AnswerTask
  23. from data.users import User
  24. from data.quests import Quests
  25. from data.answer import Answer
  26. from data.proof_file import FileProof
  27. from data.files import Files
  28. from data.projects import Projects
  29. from data.staff_projects import StaffProjects
  30. from waitress import serve
  31. from data import db_session
  32. app = Flask(__name__)
  33. with open('incepted.config', 'r', encoding='utf-8') as file:
  34. file = file.read()
  35. file = loads(file)
  36. key = file["encrypt_key"]
  37. app.config['SECRET_KEY'] = key
  38. logging.basicConfig(level=logging.INFO, filename="logfiles/main.log", format="%(asctime)s %(levelname)s %(message)s",
  39. encoding='utf-8')
  40. csrf = CSRFProtect(app)
  41. s = URLSafeTimedSerializer(key)
  42. login_manager = LoginManager()
  43. login_manager.init_app(app)
  44. @app.route('/')
  45. def base():
  46. if not current_user.is_authenticated:
  47. return render_template('main.html', title='Главная')
  48. else:
  49. return redirect('/projects')
  50. @app.route('/showcase', methods=['GET', 'POST'])
  51. def showcase():
  52. if current_user.is_authenticated:
  53. return render_template('showcase.html', title='Витрина')
  54. else:
  55. return redirect('/login')
  56. @app.route('/project/<int:id_project>/quest/<int:id_task>/edit', methods=['GET', 'POST'])
  57. def edit_quest(id_project, id_task):
  58. if current_user.is_authenticated:
  59. data_session = db_session.create_session()
  60. current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
  61. current_task = data_session.query(Quests).filter(Quests.id == id_task).first()
  62. if current_project and current_task and current_task.project == current_project.id and (
  63. current_task.creator == current_user.id or current_project.creator == current_user.id):
  64. form = Task()
  65. if request.method == 'GET':
  66. form.name.data = current_task.name
  67. form.description.data = current_task.description
  68. form.deadline_time.data = current_task.deadline.time()
  69. form.deadline_date.data = current_task.deadline.date()
  70. if form.delete.data:
  71. delete_quest_data(current_task, data_session)
  72. data_session.delete(current_task)
  73. data_session.commit()
  74. return redirect(f'/project/{str(current_project.id)}')
  75. if form.validate_on_submit():
  76. if form.deadline_date.data and form.deadline_time.data:
  77. deadline = datetime.datetime.combine(form.deadline_date.data, form.deadline_time.data)
  78. else:
  79. deadline = None
  80. current_task.name = form.name.data if form.name.data else None
  81. current_task.description = form.description.data if form.description.data else None
  82. current_task.deadline = deadline
  83. data_session.commit()
  84. return redirect(f'/project/{str(current_project.id)}/quest/{str(current_task.id)}')
  85. return render_template('edit_task.html', title='Редактирование задачи', form=form, porject=current_project,
  86. task=current_task)
  87. else:
  88. abort(403)
  89. else:
  90. return redirect('/login')
  91. @app.route('/project/<int:id_project>/file/<int:id_file>/delete')
  92. def delete_file(id_project, id_file):
  93. if current_user.is_authenticated:
  94. from_path = request.args.get('from') if request.args.get('from') else ''
  95. data_session = db_session.create_session()
  96. current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
  97. current_file = data_session.query(Files).filter(Files.id == id_file).first()
  98. if current_project and current_file:
  99. if current_user.id in map(lambda x: x[0], data_session.query(StaffProjects.user).filter(
  100. StaffProjects.project == current_project.id).all()) or current_user.id == current_project.creator:
  101. current_proof = data_session.query(FileProof).filter(FileProof.file == id_file).all()
  102. os.remove(current_file.path)
  103. data_session.delete(current_file)
  104. if current_proof:
  105. quest = data_session.query(Answer.quest).filter(Answer.id == current_proof[0].answer).first()
  106. for i in current_proof:
  107. data_session.delete(i)
  108. data_session.commit()
  109. if from_path == 'project':
  110. return redirect(f'/project/{current_project.id}')
  111. return redirect(f'/project/{current_project.id}/quest/{quest[0]}')
  112. data_session.commit()
  113. return redirect(f'/project/{current_project.id}')
  114. else:
  115. abort(403)
  116. else:
  117. abort(404)
  118. else:
  119. return redirect('/login')
  120. @app.route('/project/<int:id_project>/quest/<int:id_task>', methods=['GET', 'POST'])
  121. def task_project(id_project, id_task):
  122. if current_user.is_authenticated:
  123. data_session = db_session.create_session()
  124. current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
  125. current_task = data_session.query(Quests).filter(Quests.id == id_task).first()
  126. if current_project and current_task and current_task.project == current_project.id:
  127. form = AnswerTask()
  128. current_answer = data_session.query(Answer).filter(Answer.quest == current_task.id).first()
  129. list_files = None
  130. if form.submit.data and request.method == 'POST':
  131. if current_answer:
  132. current_answer.text = form.text.data
  133. current_answer.date_edit = datetime.datetime.now()
  134. current_task.realized = form.realized.data
  135. data_session.commit()
  136. if form.file.data[0].filename:
  137. files = list(
  138. map(lambda x: save_proof_quest(current_project, x, current_user.id), form.file.data))
  139. for i in files:
  140. if not data_session.query(FileProof).filter(FileProof.answer == current_answer.id,
  141. FileProof.file == i).first():
  142. proof_file = FileProof(
  143. answer=current_answer.id,
  144. file=i
  145. )
  146. data_session.add(proof_file)
  147. data_session.commit()
  148. else:
  149. if form.file.data[0].filename:
  150. files = list(
  151. map(lambda x: save_proof_quest(current_project, x, current_user.id), form.file.data))
  152. else:
  153. files = False
  154. current_task.realized = form.realized.data
  155. current_answer = Answer(
  156. quest=current_task.id,
  157. text=form.text.data,
  158. creator=current_user.id,
  159. date_create=datetime.datetime.now(),
  160. date_edit=datetime.datetime.now()
  161. )
  162. data_session.add(current_answer)
  163. data_session.flush()
  164. data_session.refresh(current_answer)
  165. if files:
  166. for i in files:
  167. proof_file = FileProof(
  168. answer=current_answer.id,
  169. file=i
  170. )
  171. data_session.add(proof_file)
  172. data_session.commit()
  173. return redirect(f'/project/{current_project.id}')
  174. if current_answer and request.method == 'GET':
  175. form.text.data = current_answer.text
  176. form.realized.data = current_task.realized
  177. files = data_session.query(FileProof).filter(FileProof.answer == current_answer.id).all()
  178. if files:
  179. list_files = list(map(lambda x: find_files_answer(x.file), files))
  180. return render_template('answer.html', title='Решение', project=current_project, task=current_task,
  181. form=form, list_files=list_files)
  182. else:
  183. abort(404)
  184. else:
  185. return redirect('/login')
  186. @app.route('/project/<int:id_project>/quest/new', methods=['GET', 'POST'])
  187. def new_task_project(id_project):
  188. if current_user.is_authenticated:
  189. data_session = db_session.create_session()
  190. current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
  191. if current_project:
  192. form = Task()
  193. if form.validate_on_submit():
  194. if form.deadline_date.data and form.deadline_time.data:
  195. deadline = datetime.datetime.combine(form.deadline_date.data, form.deadline_time.data)
  196. else:
  197. deadline = None
  198. quest = Quests(
  199. project=current_project.id,
  200. creator=current_user.id,
  201. name=form.name.data if form.name.data else None,
  202. description=form.description.data if form.description.data else None,
  203. date_create=datetime.datetime.now(),
  204. deadline=deadline,
  205. realized=False
  206. )
  207. data_session.add(quest)
  208. data_session.commit()
  209. return redirect(f'/project/{str(current_project.id)}')
  210. return render_template('new_task.html', title='Новая задача', form=form, porject=current_project)
  211. else:
  212. abort(404)
  213. else:
  214. return redirect('/login')
  215. @app.route('/project/<int:id_project>/edit', methods=['GET', 'POST'])
  216. def edit_project(id_project):
  217. if current_user.is_authenticated:
  218. data_session = db_session.create_session()
  219. current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
  220. if current_project:
  221. staff = data_session.query(StaffProjects).filter(StaffProjects.project == current_project.id).all()
  222. if current_user.id == current_project.creator:
  223. list_users = list(
  224. map(lambda x: get_user_data(x),
  225. data_session.query(User).filter(User.id != current_user.id, User.activated == 1).all()))
  226. staff = list(map(lambda x: get_user_data(x), data_session.query(User).filter(
  227. User.id.in_(list(map(lambda x: x.user, staff)))).all())) if staff else []
  228. form = ProjectForm()
  229. if form.save.data:
  230. new_staff = []
  231. for i in list_users:
  232. if request.form.getlist(f"choose_{i['login']}") and i['id'] != current_user.id:
  233. new_staff.append(i)
  234. if i not in staff:
  235. new_staffer = StaffProjects(
  236. user=i['id'],
  237. project=current_project.id,
  238. role='user',
  239. permission=3
  240. )
  241. data_session.add(new_staffer)
  242. data_session.commit()
  243. if sorted(new_staff, key=lambda x: x['id']) != sorted(staff, key=lambda x: x['id']):
  244. for i in staff:
  245. if i not in new_staff:
  246. data_session.delete(data_session.query(StaffProjects).filter(
  247. StaffProjects.user == i['id'], StaffProjects.project == current_project.id).first())
  248. data_session.commit()
  249. if form.logo.data:
  250. current_project.photo = save_project_logo(form.logo.data)
  251. data_session.commit()
  252. current_project.name = form.name.data
  253. current_project.description = form.description.data
  254. data_session.commit()
  255. return redirect(f'/project/{current_project.id}')
  256. if form.del_photo.data:
  257. os.remove(current_project.photo)
  258. current_project.photo = 'static/images/none_project.png'
  259. data_session.commit()
  260. return redirect(f'/project/{current_project.id}/edit')
  261. form.name.data = current_project.name
  262. form.description.data = current_project.description
  263. return render_template('edit_project.html', title='Изменение проекта', form=form, list_users=list_users,
  264. staff=staff, project=current_project)
  265. else:
  266. abort(403)
  267. else:
  268. abort(404)
  269. else:
  270. return redirect('/login')
  271. @app.route('/project/<int:id_project>', methods=['POST', 'GET'])
  272. def project(id_project):
  273. if current_user.is_authenticated:
  274. data_session = db_session.create_session()
  275. current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
  276. if current_project:
  277. staff = data_session.query(StaffProjects).filter(StaffProjects.project == current_project.id).all()
  278. if current_user.id == current_project.creator or current_user.id in list(map(lambda x: x.user, staff)):
  279. staff = list(map(lambda x: get_user_data(x), data_session.query(User).filter(
  280. User.id.in_(list(map(lambda x: x.user, staff)))).all())) if staff else []
  281. quests = data_session.query(Quests).filter(Quests.project == current_project.id).all()
  282. if quests:
  283. quests_sort = sorted(list(filter(lambda x: x.deadline is not None, quests)),
  284. key=lambda x: (x.realized, x.deadline))
  285. quests = list(filter(lambda x: x.realized == 0, quests_sort)) + list(
  286. filter(lambda x: x.deadline is None, quests)) + list(
  287. filter(lambda x: x.realized == 1, quests_sort))
  288. quests = list(map(lambda x: overdue_quest_project(x), quests))
  289. files_list = file_tree(f'static/app_files/all_projects/{current_project.id}')
  290. form_file = AddFileProject()
  291. if form_file.validate_on_submit():
  292. if form_file.file.data[0].filename:
  293. files = list(
  294. map(lambda x: save_proof_quest(current_project, x, current_user.id), form_file.file.data))
  295. return redirect(f'/project/{str(current_project.id)}')
  296. return render_template('project.html',
  297. project=current_project,
  298. title=current_project.name,
  299. staff=staff,
  300. quests=quests,
  301. file_tree=files_list,
  302. form_file=form_file)
  303. else:
  304. abort(403)
  305. else:
  306. abort(404)
  307. else:
  308. return redirect('/login')
  309. @app.route('/recovery/confirmation/<token>', methods=['GET', 'POST'])
  310. def conf_recovery(token):
  311. try:
  312. user_email = s.loads(token, max_age=86400)
  313. data_session = db_session.create_session()
  314. user = data_session.query(User).filter(User.email == user_email).first()
  315. if user:
  316. form = NewPasswordForm()
  317. if form.validate_on_submit():
  318. if form.password.data != form.repeat_password.data:
  319. return render_template('recovery.html', title='Восстановление', form=form, recovery=0,
  320. message='Пароли не совпадают')
  321. status_password = check_password(form.password.data)
  322. if status_password != 'OK':
  323. return render_template('recovery.html', title='Восстановление', form=form, recovery=0,
  324. message=str(status_password))
  325. user.set_password(form.password.data)
  326. data_session.commit()
  327. mail(f'Для аккаунта {user.login}, успешно был обновлен пароль', user.email,
  328. 'Изменение пароля')
  329. return redirect('/login?message=Пароль обновлен')
  330. return render_template('recovery.html', title='Восстановление', form=form, recovery=0, message='')
  331. else:
  332. return redirect('/login?message=Пользователь не найден&danger=True')
  333. except SignatureExpired:
  334. return redirect('/login?message=Срок действия ссылки истек&danger=True')
  335. @app.route('/recovery', methods=['GET', 'POST'])
  336. def recovery():
  337. if not current_user.is_authenticated:
  338. form = RecoveryForm()
  339. if form.validate_on_submit():
  340. token = s.dumps(form.email.data)
  341. link_conf = url_for('conf_recovery', token=token, _external=True)
  342. mail(f'Для сбросы пароля пройдите по ссылке: {link_conf}', form.email.data,
  343. 'Восстановление доступа')
  344. return redirect('/login?message=Мы выслали ссылку для сброса вам на почту')
  345. return render_template('recovery.html', title='Восстановление пароля', form=form, recovery=True, message='')
  346. else:
  347. return redirect('/')
  348. @app.route('/project/<int:id_project>/delete', methods=['GET', 'POST'])
  349. def delete_project(id_project):
  350. if current_user.is_authenticated:
  351. data_session = db_session.create_session()
  352. project_del = data_session.query(Projects).filter(Projects.id == id_project).first()
  353. if project_del:
  354. if project_del.creator == current_user.id:
  355. form = DeleteProjectForm()
  356. if form.validate_on_submit():
  357. if str(form.conf.data).lower().strip() != f'delete/{str(project_del.name)}'.lower().strip():
  358. return render_template('delete_project.html', title='Удаление проекта', form=form,
  359. project=project_del,
  360. message='Вы не правильно ввели фразу')
  361. delete_project_data(project_del, data_session)
  362. return redirect('/projects')
  363. return render_template('delete_project.html', title='Удаление проекта', form=form, project=project_del,
  364. message='')
  365. else:
  366. abort(403)
  367. else:
  368. abort(404)
  369. else:
  370. return redirect('/login')
  371. @app.route('/user/<string:_login>', methods=['GET', 'POST'])
  372. def user_view(_login):
  373. if current_user.is_authenticated:
  374. data_session = db_session.create_session()
  375. user = data_session.query(User).filter(User.login == _login).first()
  376. if user:
  377. current_projects = data_session.query(Projects).filter(or_(Projects.creator == user.id, Projects.id.in_(
  378. list(map(lambda x: x[0], data_session.query(
  379. StaffProjects.project).filter(
  380. StaffProjects.user == user.id).all()))))).all()
  381. resp = list(map(lambda x: get_projects_data(x), current_projects))
  382. return render_template('user_view.html',
  383. title=user.name if user.name else '' + ' ' + user.surname if user.surname else '',
  384. user=user,
  385. list_projects=resp)
  386. else:
  387. abort(404)
  388. else:
  389. return redirect('/login')
  390. @app.route('/projects/new', methods=['GET', 'POST'])
  391. def new_project():
  392. if current_user.is_authenticated:
  393. form = ProjectForm()
  394. data_session = db_session.create_session()
  395. list_users = list(
  396. map(lambda x: get_user_data(x), data_session.query(User).filter(User.id != current_user.id).all()))
  397. if form.validate_on_submit():
  398. current_project = Projects(
  399. name=form.name.data,
  400. description=form.description.data,
  401. date_create=datetime.datetime.now(),
  402. creator=current_user.id
  403. )
  404. current_project.photo = save_project_logo(
  405. form.logo.data) if form.logo.data else 'static/images/none_project.png'
  406. data_session.add(current_project)
  407. data_session.flush()
  408. data_session.refresh(current_project)
  409. for i in list_users:
  410. if request.form.getlist(f"choose_{i['login']}") and i['id'] != current_user.id:
  411. new_staffer = StaffProjects(
  412. user=i['id'],
  413. project=current_project.id,
  414. role='user',
  415. permission=3
  416. )
  417. data_session.add(new_staffer)
  418. data_session.commit()
  419. os.mkdir(f'static/app_files/all_projects/{str(current_project.id)}')
  420. return redirect('/projects')
  421. return render_template('new_project.html', title='Новый проект', form=form, list_users=list_users)
  422. else:
  423. return redirect('/login')
  424. @app.route('/projects', methods=['GET', 'POST'])
  425. def projects():
  426. if current_user.is_authenticated:
  427. find = False
  428. form = FindProjectForm()
  429. data_session = db_session.create_session()
  430. resp = []
  431. current_projects = \
  432. data_session.query(Projects).filter(or_(Projects.creator == current_user.id,
  433. Projects.id.in_(
  434. list(map(lambda x: x[0],
  435. data_session.query(
  436. StaffProjects.project).filter(
  437. StaffProjects.user
  438. == current_user.id).all()))))).all()
  439. if form.validate_on_submit():
  440. new_resp = []
  441. for i in range(len(current_projects)):
  442. if str(form.project.data).lower().strip() in str(current_projects[i].name).lower().strip():
  443. new_resp.append(current_projects[i])
  444. current_projects = new_resp
  445. find = True
  446. resp = list(map(lambda x: get_projects_data(x), current_projects))
  447. return render_template('projects.html', title='Проекты', list_projects=resp, form=form, find=find)
  448. else:
  449. return redirect('/login')
  450. @app.route('/profile', methods=['GET', 'POST'])
  451. def profile():
  452. if current_user.is_authenticated:
  453. form = EditProfileForm(
  454. CombinedMultiDict((request.files, request.form)),
  455. email=current_user.email,
  456. name=current_user.name,
  457. surname=current_user.surname,
  458. about=current_user.about,
  459. birthday=current_user.birthday
  460. )
  461. if form.del_photo.data:
  462. data_session = db_session.create_session()
  463. user = data_session.query(User).filter(User.id == current_user.id).first()
  464. if not user:
  465. return render_template('profile.html', title='Профиль', form=form,
  466. message='Ошибка, пользователь ненайден')
  467. os.remove(current_user.photo)
  468. user.photo = 'static/images/none_logo.png'
  469. data_session.commit()
  470. if form.validate_on_submit():
  471. data_session = db_session.create_session()
  472. user = data_session.query(User).filter(User.id == current_user.id).first()
  473. if not user:
  474. return render_template('profile.html', title='Профиль', form=form,
  475. message='Ошибка, пользователь ненайден')
  476. if form.email.data != current_user.email:
  477. token = s.dumps(form.email.data)
  478. link_conf = url_for('confirmation', token=token, _external=True)
  479. mail(f'Для изменения почты пройдите по ссылке: {link_conf}', form.email.data,
  480. 'Изменение почты')
  481. user.activated = False
  482. user.email = form.email.data
  483. if form.photo.data:
  484. with open(f'static/app_files/user_logo/{current_user.login}.png', 'wb') as file:
  485. form.photo.data.save(file)
  486. user.photo = f'static/app_files/user_logo/{current_user.login}.png'
  487. user.name = form.name.data
  488. user.surname = form.surname.data
  489. user.about = form.about.data
  490. user.birthday = form.birthday.data
  491. data_session.commit()
  492. return redirect('/profile')
  493. return render_template('profile.html', title='Профиль', form=form, message='')
  494. else:
  495. return redirect('/login')
  496. @login_manager.user_loader
  497. def load_user(user_id):
  498. db_sess = db_session.create_session()
  499. return db_sess.query(User).get(user_id)
  500. @app.route('/login', methods=['GET', 'POST'])
  501. def login():
  502. if not current_user.is_authenticated:
  503. message = request.args.get('message') if request.args.get('message') else ''
  504. danger = request.args.get('danger') if request.args.get('danger') else False
  505. form = LoginForm()
  506. if form.validate_on_submit():
  507. data_session = db_session.create_session()
  508. user = data_session.query(User).filter(User.email == form.login.data).first()
  509. if not user:
  510. user = data_session.query(User).filter(User.login == form.login.data).first()
  511. if user and user.check_password(form.password.data):
  512. if user.activated:
  513. login_user(user, remember=form.remember_me.data)
  514. logging.info(f'{user.login} logged in')
  515. return redirect('/projects')
  516. else:
  517. return render_template('login.html',
  518. message="Ваша почта не подтверждена",
  519. danger=True,
  520. form=form)
  521. return render_template('login.html',
  522. message="Неправильный логин или пароль",
  523. danger=True,
  524. form=form)
  525. return render_template('login.html', title='Авторизация', form=form, message=message,
  526. danger=danger)
  527. else:
  528. return redirect('/projects')
  529. @app.route('/logout')
  530. @login_required
  531. def logout():
  532. logging.info(f'{current_user.login} logged out')
  533. logout_user()
  534. return redirect("/")
  535. @app.route('/register', methods=['GET', 'POST'])
  536. def register():
  537. if not current_user.is_authenticated:
  538. form = RegisterForm()
  539. if form.validate_on_submit():
  540. data_session = db_session.create_session()
  541. if data_session.query(User).filter(User.login == form.login.data).first():
  542. return render_template('register.html', form=form, message="Такой пользователь уже есть",
  543. title='Регистрация')
  544. if data_session.query(User).filter(User.email == form.email.data).first():
  545. return render_template('register.html', form=form, message="Такая почта уже есть", title='Регистрация')
  546. status_password = check_password(form.password.data)
  547. if status_password != 'OK':
  548. return render_template('register.html', form=form, message=status_password, title='Регистрация')
  549. user = User(
  550. email=form.email.data,
  551. name=form.name.data,
  552. login=form.login.data,
  553. activity=datetime.datetime.now(),
  554. data_reg=datetime.date.today(),
  555. photo='static/images/none_logo.png',
  556. role=1
  557. )
  558. user.set_password(form.password.data)
  559. data_session.add(user)
  560. data_session.commit()
  561. token = s.dumps(form.email.data)
  562. link_conf = url_for('confirmation', token=token, _external=True)
  563. mail(f'Для завершения регистрации пройдите по ссылке: {link_conf}', form.email.data,
  564. 'Подтверждение регистрации')
  565. logging.info(f'{form.login.data} was registered')
  566. return redirect('/login?message=Мы выслали ссылку для подтверждения почты')
  567. return render_template('register.html', form=form, message='', title='Регистрация')
  568. else:
  569. return redirect('/projects')
  570. @app.route('/confirmation/<token>')
  571. def confirmation(token):
  572. try:
  573. user_email = s.loads(token, max_age=86400)
  574. data_session = db_session.create_session()
  575. user = data_session.query(User).filter(User.email == user_email).first()
  576. if user:
  577. user.activated = True
  578. data_session.commit()
  579. logging.info(f'{user.login} has been confirmed')
  580. return redirect('/login?message=Почта успешно подтверждена')
  581. else:
  582. return redirect('/login?message=Пользователь не найден&danger=True')
  583. except SignatureExpired:
  584. data_session = db_session.create_session()
  585. users = data_session.query(User).filter(
  586. User.activated == 0 and User.activated < datetime.datetime.now() - datetime.timedelta(days=1)).all()
  587. if users:
  588. list(map(lambda x: data_session.delete(x), users))
  589. data_session.commit()
  590. return redirect('/login?message=Срок действия ссылки истек, данные удалены&danger=True')
  591. @app.errorhandler(500)
  592. def internal_server_error(error):
  593. return render_template('page_error.html', title='Ошибка сервера', error='500', message='Технические шоколадки')
  594. @app.errorhandler(404)
  595. def page_not_found(error):
  596. return render_template('page_error.html', title='Страница не найдена', error='404', message='Страница не найдена')
  597. @app.errorhandler(403)
  598. def access_error(error):
  599. return render_template('page_error.html', title='Ошибка доступа', error='403', message='Доступ сюда запрещен')
  600. def main():
  601. db_path = 'db/incepted.db'
  602. db = os.path.exists(db_path)
  603. db_session.global_init(db_path)
  604. if not db:
  605. init_db_default()
  606. serve(app, host='0.0.0.0', port=5000, threads=10)
  607. if __name__ == '__main__':
  608. try:
  609. main()
  610. except Exception as error:
  611. logging.warning(f'{error}')