main.py 32 KB

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