main.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. import datetime
  2. import os
  3. from flask import Flask, render_template, request, url_for
  4. from flask_login import login_user, current_user, LoginManager, logout_user, login_required
  5. from flask_wtf import CSRFProtect
  6. from flask_restful import abort
  7. from werkzeug.datastructures import CombinedMultiDict
  8. from werkzeug.utils import redirect
  9. from itsdangerous import URLSafeTimedSerializer, SignatureExpired
  10. from sqlalchemy import or_
  11. from functions import check_password, mail, init_db_default, get_projects_data, get_user_data, save_project_logo
  12. from forms.edit_profile import EditProfileForm
  13. from forms.login import LoginForm
  14. from forms.register import RegisterForm
  15. from forms.new_project import NewProjectForm
  16. from data.users import User
  17. from data.files import Files
  18. from data.projects import Projects
  19. from data.staff_projects import StaffProjects
  20. from waitress import serve
  21. from data import db_session
  22. app = Flask(__name__)
  23. key = 'test_secret_key'
  24. app.config['SECRET_KEY'] = key
  25. csrf = CSRFProtect(app)
  26. s = URLSafeTimedSerializer(key)
  27. login_manager = LoginManager()
  28. login_manager.init_app(app)
  29. @app.route('/')
  30. def base():
  31. if not current_user.is_authenticated:
  32. return render_template('main.html', title='Главная')
  33. else:
  34. return redirect('/projects')
  35. @app.route('/projects/delete/<int:id_project>', methods=['GET', 'POST'])
  36. def delete_project(id_project):
  37. if current_user.is_authenticated:
  38. data_session = db_session.create_session()
  39. project_del = data_session.query(Projects).filter(Projects.id == id_project).first()
  40. if project_del:
  41. if project_del.creator == current_user.id:
  42. staff = data_session.query(StaffProjects).filter(StaffProjects.project == id_project).all()
  43. for i in staff:
  44. data_session.delete(i)
  45. if 'none_project' not in project_del.photo:
  46. os.remove(project_del.photo)
  47. data_session.delete(project_del)
  48. data_session.commit()
  49. data_session.close()
  50. return redirect('/projects')
  51. else:
  52. abort(403)
  53. else:
  54. abort(404)
  55. else:
  56. return redirect('/login')
  57. @app.route('/user/<string:_login>', methods=['GET', 'POST'])
  58. def user_view(_login):
  59. if current_user.is_authenticated:
  60. data_session = db_session.create_session()
  61. user = data_session.query(User).filter(User.login == _login).first()
  62. if user:
  63. projects = data_session.query(Projects).filter(or_(Projects.creator == user.id, Projects.id.in_(
  64. list(map(lambda x: x[0], data_session.query(
  65. StaffProjects.project).filter(
  66. StaffProjects.user == user.id).all()))))).all()
  67. resp = list(map(lambda x: get_projects_data(x), projects))
  68. return render_template('user_view.html', title=user.name + ' ' + user.surname, user=user,
  69. list_projects=resp)
  70. else:
  71. abort(404)
  72. else:
  73. return redirect('/login')
  74. @app.route('/projects/new', methods=['GET', 'POST'])
  75. def new_project():
  76. if current_user.is_authenticated:
  77. form = NewProjectForm()
  78. data_session = db_session.create_session()
  79. list_users = list(
  80. map(lambda x: get_user_data(x), data_session.query(User).filter(User.id != current_user.id).all()))
  81. if form.validate_on_submit():
  82. project = Projects(
  83. name=form.name.data,
  84. description=form.description.data,
  85. date_create=datetime.datetime.now(),
  86. creator=current_user.id
  87. )
  88. project.photo = save_project_logo(form.logo.data) if form.logo.data else 'static/images/none_project.png'
  89. data_session.add(project)
  90. data_session.flush()
  91. data_session.refresh(project)
  92. for i in list_users:
  93. if request.form.getlist(f"choose_{i['login']}") and i['id'] != current_user.id:
  94. new_staffer = StaffProjects(
  95. user=i['id'],
  96. project=project.id,
  97. role='user',
  98. permission=3
  99. )
  100. data_session.add(new_staffer)
  101. data_session.commit()
  102. data_session.close()
  103. return redirect('/projects')
  104. data_session.close()
  105. return render_template('new_project.html', title='Новый проект', form=form, list_users=list_users)
  106. else:
  107. return redirect('/login')
  108. @app.route('/projects', methods=['GET', 'POST'])
  109. def project():
  110. if current_user.is_authenticated:
  111. data_session = db_session.create_session()
  112. resp = []
  113. if request.method == 'POST':
  114. pass
  115. else:
  116. projects = data_session.query(Projects).filter(or_(Projects.creator == current_user.id, current_user.id in
  117. data_session.query(StaffProjects.project).filter(
  118. StaffProjects.user == current_user.id).all())).all()
  119. resp = list(map(lambda x: get_projects_data(x), projects))
  120. return render_template('projects.html', title='Проекты', list_projects=resp)
  121. else:
  122. return redirect('/login')
  123. @app.route('/profile', methods=['GET', 'POST'])
  124. def profile():
  125. if current_user.is_authenticated:
  126. form = EditProfileForm(
  127. CombinedMultiDict((request.files, request.form)),
  128. email=current_user.email,
  129. name=current_user.name,
  130. surname=current_user.surname,
  131. about=current_user.about,
  132. birthday=current_user.birthday
  133. )
  134. if form.del_photo.data:
  135. data_session = db_session.create_session()
  136. user = data_session.query(User).filter(User.id == current_user.id).first()
  137. if not user:
  138. return render_template('profile.html', title='Профиль', form=form,
  139. message='Ошибка, пользователь ненайден')
  140. os.remove(current_user.photo)
  141. user.photo = 'static/images/none_logo.png'
  142. data_session.commit()
  143. data_session.close()
  144. if form.validate_on_submit():
  145. data_session = db_session.create_session()
  146. user = data_session.query(User).filter(User.id == current_user.id).first()
  147. if not user:
  148. return render_template('profile.html', title='Профиль', form=form,
  149. message='Ошибка, пользователь ненайден')
  150. if form.email.data != current_user.email:
  151. pass
  152. if form.photo.data:
  153. with open(f'static/app_files/user_logo/{current_user.login}.png', 'wb') as file:
  154. form.photo.data.save(file)
  155. user.photo = f'static/app_files/user_logo/{current_user.login}.png'
  156. user.name = form.name.data
  157. user.surname = form.surname.data
  158. user.about = form.about.data
  159. user.birthday = form.birthday.data
  160. data_session.commit()
  161. data_session.close()
  162. return redirect('/profile')
  163. return render_template('profile.html', title='Профиль', form=form, message='')
  164. else:
  165. return redirect('/login')
  166. @login_manager.user_loader
  167. def load_user(user_id):
  168. db_sess = db_session.create_session()
  169. return db_sess.query(User).get(user_id)
  170. @app.route('/login', methods=['GET', 'POST'])
  171. def login():
  172. if not current_user.is_authenticated:
  173. message = request.args.get('message') if request.args.get('message') else ''
  174. danger = request.args.get('danger') if request.args.get('danger') else False
  175. form = LoginForm()
  176. if form.validate_on_submit():
  177. data_session = db_session.create_session()
  178. user = data_session.query(User).filter(User.email == form.login.data).first()
  179. if not user:
  180. user = data_session.query(User).filter(User.login == form.login.data).first()
  181. data_session.close()
  182. if user and user.check_password(form.password.data):
  183. if user.activated:
  184. login_user(user, remember=form.remember_me.data)
  185. return redirect('/projects')
  186. else:
  187. return render_template('login.html',
  188. message="Ваша почта не подтверждена",
  189. danger=True,
  190. form=form)
  191. return render_template('login.html',
  192. message="Неправильный логин или пароль",
  193. danger=True,
  194. form=form)
  195. return render_template('login.html', title='Авторизация', form=form, message=message,
  196. danger=danger)
  197. else:
  198. return redirect('/projects')
  199. @app.route('/logout')
  200. @login_required
  201. def logout():
  202. logout_user()
  203. return redirect("/")
  204. @app.route('/register', methods=['GET', 'POST'])
  205. def register():
  206. if not current_user.is_authenticated:
  207. form = RegisterForm()
  208. if form.validate_on_submit():
  209. data_session = db_session.create_session()
  210. if data_session.query(User).filter(User.login == form.login.data).first():
  211. return render_template('register.html', form=form, message="Такой пользователь уже есть",
  212. title='Регистрация')
  213. if data_session.query(User).filter(User.email == form.email.data).first():
  214. return render_template('register.html', form=form, message="Такая почта уже есть", title='Регистрация')
  215. status_password = check_password(form.password.data)
  216. if status_password != 'OK':
  217. return render_template('register.html', form=form, message=status_password, title='Регистрация')
  218. user = User(
  219. email=form.email.data,
  220. name=form.name.data,
  221. login=form.login.data,
  222. activity=datetime.datetime.now(),
  223. data_reg=datetime.date.today(),
  224. photo='static/images/none_logo.png',
  225. role=1
  226. )
  227. user.set_password(form.password.data)
  228. data_session.add(user)
  229. data_session.commit()
  230. data_session.close()
  231. token = s.dumps(form.email.data)
  232. link_conf = url_for('confirmation', token=token, _external=True)
  233. mail(f'Для завершения регистрации пройдите по ссылке: {link_conf}', form.email.data,
  234. 'Подтверждение регистрации')
  235. return redirect('/login?message=Мы выслали ссылку для подтверждения почты')
  236. return render_template('register.html', form=form, message='', title='Регистрация')
  237. else:
  238. return redirect('/projects')
  239. @app.route('/confirmation/<token>')
  240. def confirmation(token):
  241. try:
  242. user_email = s.loads(token, max_age=86400)
  243. data_session = db_session.create_session()
  244. user = data_session.query(User).filter(User.email == user_email).first()
  245. if user:
  246. user.activated = True
  247. data_session.commit()
  248. data_session.close()
  249. return redirect('/login?message=Почта успешно подтверждена')
  250. else:
  251. return redirect('/login?message=Пользователь не найден&danger=True')
  252. except SignatureExpired:
  253. data_session = db_session.create_session()
  254. users = data_session.query(User).filter(
  255. User.activated == 0 and User.activated < datetime.datetime.now() - datetime.timedelta(days=1)).all()
  256. if users:
  257. list(map(lambda x: data_session.delete(x), users))
  258. data_session.commit()
  259. data_session.close()
  260. return redirect('/login?message=Срок действия ссылки истек, данные удалены&danger=True')
  261. @app.errorhandler(404)
  262. def page_not_found(error):
  263. return render_template('page_error.html', title='Страница не найдена', error='404', message='Страница не найдена')
  264. @app.errorhandler(403)
  265. def page_not_found(error):
  266. return render_template('page_error.html', title='Ошибка доступа', error='403', message='Доступ сюда запрещен')
  267. def main():
  268. db_path = 'db/incepted.db'
  269. db = os.path.exists(db_path)
  270. db_session.global_init(db_path)
  271. if not db:
  272. init_db_default()
  273. serve(app, host='0.0.0.0', port=5000)
  274. if __name__ == '__main__':
  275. main()