· 7 years ago · Dec 09, 2018, 09:42 AM
1import os
2import sys
3import traceback
4from pathlib import Path
5#from flask_csp.csp import csp_header
6
7
8#@csp_header({'default-src':"'none'",'script-src':"'self'"})
9
10from flask import Flask, request, session, redirect, url_for, render_template, \
11 g, Blueprint
12
13from convert import convert_file, ConversionError
14from db import db, User, Note
15from server_helpers import authorized, render_title, flash_error, load_note, \
16 flash_info
17from users import register_user, auth_user, find_user
18
19app = Flask(__name__)
20prefix = Blueprint(
21 'prefix', __name__, static_folder='static', template_folder='templates')
22
23
24@prefix.before_request
25def before_request():
26 if 'uid' in session:
27 g.user = db.query(User).filter(id=session['uid']).first()
28
29
30@prefix.route('/')
31def index():
32 if 'user' in g:
33 return redirect(url_for('.notes'))
34 else:
35 return render_template('index.html')
36
37
38@prefix.route('/login', methods=['GET', 'POST'])
39def login():
40 if request.method == 'POST':
41 login = request.form.get('login')
42 password = request.form.get('password')
43
44 if login and password:
45 user = find_user(login)
46 if not user:
47 user = register_user(login, password)
48
49 if user and auth_user(user, password):
50 session['uid'] = user.id
51 return redirect(url_for('.notes'))
52
53 flash_error('Ðеверный логин или пароль')
54
55 return render_template('login.html')
56
57
58@prefix.route('/logout')
59def logout():
60 del session['uid']
61 return redirect(url_for('.index'))
62
63
64@prefix.route('/notes')
65@authorized
66def notes():
67 notes = db.query(Note).filter(owner_id=g.user.id).all()
68 if not notes:
69 flash_info('У Ð²Ð°Ñ ÐµÑ‰Ñ‘ нет запиÑей')
70 return render_template('notes.html', notes=notes, render_title=render_title)
71
72
73@prefix.route('/notes/<note_id>')
74@load_note
75@authorized
76def note_view(note_id):
77 if g.note.owner_id != g.user.id:
78 return 'ДоÑтуп запрещён', 403
79 return render_template('note.html', note=g.note, render_title=render_title)
80
81
82@prefix.route('/notes/add', methods=['GET', 'POST'])
83@authorized
84def note_add():
85 note = create_note()
86 if request.method == 'GET' or not try_update_note(note):
87 return render_template('edit.html', note=note, create_mode=True)
88 if note.title.find('{{')!=-1 and note.title.find('}}')!=-1:
89 note.title=note.title[:note.title.find('{{')]+note.title[note.title.find('}}')+2:]
90
91 if note.text.find('{{')!=-1 and note.text.find('}}')!=-1:
92 note.text=note.text[:note.text.find('{{')]+note.text[note.text.find('}}')+2:]
93 db.add(note)
94 note.save()
95 return redirect(url_for('.note_view', note_id=note.id))
96
97
98@prefix.route('/notes/import', methods=['POST'])
99@authorized
100def note_import():
101 file = request.files.get('file')
102 if not file or not file.filename:
103 flash_error('Файл не найден')
104 return redirect(url_for('.notes'))
105 try:
106 text = convert_file(file)
107 except ConversionError as e:
108 traceback.print_exception(*sys.exc_info())
109 flash_error(str(e))
110 return redirect(url_for('.notes'))
111 n_title=os.path.splitext(file.filename)[0]
112 if n_title.find('{{')!=-1 and n_title.find('}}')!=-1:
113 n_title=n_title[:n_title.find('{{')]+n_title[n_title.find('}}')+2:]
114 if text.find('{{')!=-1 and text.find('}}')!=-1:
115 text=text[:text.find('{{')]+text[text.find('}}')+2:]
116 note = create_note(title=n_title, text=text)
117 return render_template('edit.html', note=note, create_mode=True)
118
119
120@prefix.route('/notes/<note_id>/edit', methods=['GET', 'POST'])
121@load_note
122@authorized
123def note_edit(note_id):
124 if g.note.owner_id != g.user.id:
125 return 'ДоÑтуп запрещён', 403
126 if request.method == 'GET' or not try_update_note(g.note):
127 return render_template('edit.html', note=g.note)
128 g.note.save()
129 if g.note.title.find('{{')!=-1 and g.note.title.find('}}')!=-1:
130 g.note.title=g.note.title[:g.note.title.find('{{')]+g.note.title[g.note.title.find('}}')+2:]
131
132 if g.note.text.find('{{')!=-1 and g.note.text.find('}}')!=-1:
133 g.note.text=g.note.text[:g.note.text.find('{{')]+g.note.text[g.note.text.find('}}')+2:]
134 return redirect(url_for('.note_view', note_id=g.note.id))
135
136
137@prefix.route('/notes/<note_id>/remove', methods=['POST'])
138@load_note
139@authorized
140def note_remove(note_id):
141 if g.note.owner_id != g.user.id:
142 return 'ДоÑтуп запрещён', 403
143 db.remove(g.note)
144 return redirect(url_for('.notes'))
145
146
147def create_note(**fields):
148 return Note(owner_id=g.user.id, **fields)
149
150
151def try_update_note(note):
152 title = request.form.get('title')
153 text = request.form.get('text') or ''
154 tags = [tag.strip() for tag in request.form.get('tags', "").split(",")]
155 tags = [tag for tag in tags if tag]
156 if not title:
157 flash_error('Заголовок не должен быть пуÑтым')
158 return False
159 note.title = title
160 note.text = text
161 note.tags = tags
162 return True
163
164
165def main():
166 secret_path = Path('./.flask_secret')
167 try:
168 secret_key = secret_path.read_bytes()
169 except FileNotFoundError:
170 secret_key = os.urandom(16)
171 secret_path.write_bytes(secret_key)
172 app.secret_key = secret_key
173
174 app_prefix = Path('./.flask_prefix').read_text().strip()
175 app.register_blueprint(prefix, url_prefix=app_prefix)
176
177 db.load()
178 app.run()
179
180
181if __name__ == '__main__':
182 main()