SocialNetwork
/
app.py
393 строки · 11.1 Кб
1import datetime
2import os
3from pprint import pprint
4
5import humanize
6from flask import Flask, session, request, redirect, render_template, abort
7import spotipy
8
9from flask_restful import Api
10from flask_uploads import configure_uploads, patch_request_class
11
12import funcs_api
13import music
14import rest_api
15import utils.some
16import weather
17from data import db_session
18
19from flask_login import LoginManager, login_user, login_required, logout_user, current_user
20from flask_session import Session
21
22from data.posts import Post
23from data.users import User
24from forms.contacts import ContactInformation
25from forms.personal_info import PersonalInformation
26from forms.profile_settings import AccountSetting, SocialMedia, ChangePassword
27from forms.upload import photos, UploadPhoto
28from forms.user import RegisterUser, LoginUser
29
30from PIL import Image
31import random
32
33from utils.spotify import spotify_login_required, SCOPE, get_followed_artists, get_all_artist_tracks
34
35basedir = os.path.abspath(os.path.dirname(__file__))
36
37app = Flask(__name__)
38app.config['SECRET_KEY'] = os.urandom(64)
39app.config['SESSION_TYPE'] = 'filesystem'
40app.config['SESSION_FILE_DIR'] = './.flask_session/'
41app.config['SECRET_KEY'] = 'spotify_project_secret_key'
42app.config['UPLOADED_PHOTOS_DEST'] = os.path.join(basedir, 'static/uploaded_photos')
43Session(app)
44
45login_manager = LoginManager()
46login_manager.init_app(app)
47
48configure_uploads(app, photos)
49patch_request_class(app)
50
51api = Api(app)
52post_resource = rest_api.PostResource()
53post_list_resource = rest_api.PostListResource()
54
55
56def crop_center(pil_img, crop_width: int, crop_height: int) -> Image:
57"""
58Функция для обрезки изображения по центру.
59"""
60img_width, img_height = pil_img.size
61return pil_img.crop(((img_width - crop_width) // 2,
62(img_height - crop_height) // 2,
63(img_width + crop_width) // 2,
64(img_height + crop_height) // 2))
65
66
67def crop_max_square(pil_img):
68return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
69
70
71@login_manager.user_loader
72def load_user(user_id):
73db_sess = db_session.create_session()
74return db_sess.query(User).get(user_id)
75
76
77@app.route('/')
78@app.route('/index')
79@app.route('/news')
80@app.route('/newsfeed')
81@login_required
82def index():
83return redirect('/newsfeed/page1')
84
85
86@app.route('/newsfeed/page<int:page_num>')
87@login_required
88@spotify_login_required
89def newsfeed(page_num: int, spotify: spotipy.Spotify):
90db_sess = db_session.create_session()
91
92def format_date(date):
93date = date.split('-')
94year = int(date[0])
95month = int(date[1])
96day = int(date[2])
97return humanize.naturaltime(
98datetime.datetime.now() - datetime.datetime(year=year, month=month, day=day))
99
100params = {
101'spotify': spotify,
102'current_user': db_sess.query(User).get(current_user.id),
103'new_releases':
104spotify.new_releases(country='RU', limit=20, offset=20 * (page_num - 1))['albums'][
105'items'],
106'followed_artists': sorted(get_followed_artists(spotify), key=lambda x: x['popularity'],
107reverse=True)[:8:],
108'format_date': format_date,
109'page': page_num
110}
111
112return render_template('newsfeed.html', **params)
113
114
115@app.route('/anecdotes')
116@login_required
117def anecdotes():
118db_sess = db_session.create_session()
119user = db_sess.query(User).get(current_user.id)
120
121anec = funcs_api.get_anec().json['anecdote']
122
123params = {
124'current_user': user,
125'anec':anec
126}
127
128
129return render_template('anecs.html', **params)
130
131
132@app.route('/register', methods=['GET', 'POST'])
133def register():
134if current_user.is_authenticated:
135return redirect('/profile')
136db_sess = db_session.create_session()
137
138form = RegisterUser()
139
140if form.validate_on_submit():
141user = User()
142user.name = form.name.data
143user.surname = form.surname.data
144user.email = form.email.data
145user.set_password(form.password.data)
146
147db_sess.add(user)
148db_sess.commit()
149
150login_user(user, remember=form.remember_me.data)
151return redirect("/")
152
153params = {
154
155}
156
157return render_template('register.html', form=form, **params)
158
159
160@app.route('/login', methods=['GET', 'POST'])
161def login():
162if current_user.is_authenticated:
163return redirect('/profile')
164db_sess = db_session.create_session()
165form = LoginUser()
166if form.validate_on_submit():
167user = db_sess.query(User).filter(User.email == form.email.data).first()
168if user and user.check_password(form.password.data):
169login_user(user, remember=form.remember_me.data)
170return redirect("/profile")
171return render_template('login.html',
172message="Неправильный логин или пароль",
173form=form)
174
175params = {
176
177}
178
179return render_template('login.html', form=form, **params)
180
181
182@app.route('/logout')
183@login_required
184def logout():
185logout_user()
186return redirect("/login")
187
188
189@app.route('/profile', methods=['GET', 'POST'])
190@login_required
191def profile():
192db_sess = db_session.create_session()
193user = db_sess.query(User).get(current_user.id)
194
195posts = list(db_sess.query(Post).filter(Post.user_id == user.id))
196
197params = {
198'current_user': user,
199}
200
201return render_template('profile.html', posts=posts, **params)
202
203
204@app.route('/id<id>')
205@login_required
206def user(id, ):
207db_sess = db_session.create_session()
208user = db_sess.query(User).get(id)
209posts = db_sess.query(Post).filter(Post.user_id == user.id)
210
211curr_user = db_sess.query(User).get(current_user.id)
212
213params = {
214'current_user': curr_user,
215}
216
217return render_template('user.html', user=user, posts=list(posts), **params)
218
219
220@app.route('/friends')
221@login_required
222def friends():
223db_sess = db_session.create_session()
224
225params = {
226'current_user': db_sess.query(User).get(current_user.id),
227}
228
229return render_template('friends.html', **params)
230
231
232@app.route('/profile/edit', methods=['GET', 'POST'])
233@login_required
234def profile_edit():
235db_sess = db_session.create_session()
236
237params = {'current_user': db_sess.query(User).get(current_user.id),
238'messages': {}}
239
240user = db_sess.query(User).filter(User.id == current_user.id).first()
241
242personal_info = PersonalInformation()
243params['form'] = personal_info
244
245if personal_info.validate_on_submit():
246
247user.name = personal_info.name.data
248user.surname = personal_info.surname.data
249user.gender = personal_info.gender.data
250user.age = personal_info.age.data
251user.marital_status = personal_info.marital_status.data
252user.city = personal_info.city.data
253user.address = personal_info.address.data
254
255if personal_info.photo.data:
256filename = photos.save(personal_info.photo.data)
257file_url = photos.url(filename)
258
259os.chdir('static')
260os.chdir('uploaded_photos')
261
262fname = f'id{current_user.id}_avatar.jpg'
263
264if os.path.exists(fname):
265os.remove(fname)
266os.rename(filename, fname)
267
268crop_max_square(Image.open(fname)).save(fname)
269
270os.chdir('..')
271os.chdir('..')
272
273user.avatar = f'/static/uploaded_photos/{fname}'
274
275change_password = ChangePassword()
276params['change_password'] = change_password
277
278if change_password.validate_on_submit():
279if user.check_password(
280change_password.old_pass.data) and change_password.new_pass.data == change_password.new_pass_again.data:
281user.set_password(change_password.new_pass.data)
282db_sess.commit()
283return redirect('/logout')
284if not user.check_password(change_password.old_pass.data):
285params['messages']['old_pass'] = 'Wrong old password'
286if not change_password.new_pass.data == change_password.new_pass_again.data:
287params['messages']['new_pass_again'] = 'New passwords do not match'
288
289contact_info = ContactInformation()
290params['contact_info'] = contact_info
291if contact_info.validate_on_submit():
292if contact_info.email.data == current_user.email and contact_info.new_email.data == contact_info.new_email_again.data:
293if contact_info.new_email.data:
294user.email = contact_info.new_email_again.data
295if contact_info.email.data != current_user.email:
296params['messages']['email'] = 'Wrong old Email'
297if contact_info.new_email.data != contact_info.new_email_again.data:
298params['messages']['new_email_again'] = 'New Emails do not match'
299
300if contact_info.phone.data:
301user.phone = contact_info.phone.data
302if contact_info.url:
303user.url = contact_info.url.data
304
305if contact_info.vk.data:
306user.vk = contact_info.vk.data
307user.show_vk = contact_info.show_vk.data
308
309if contact_info.facebook.data:
310user.facebook = contact_info.facebook.data
311user.show_facebook = contact_info.show_facebook.data
312
313if contact_info.twitter.data:
314user.twitter = contact_info.twitter.data
315user.show_twitter = contact_info.show_twitter.data
316
317if contact_info.instagram.data:
318user.instagram = contact_info.instagram.data
319user.show_instagram = contact_info.show_instagram.data
320
321if contact_info.youtube.data:
322user.youtube = contact_info.youtube.data
323user.show_youtube = contact_info.show_youtube.data
324
325db_sess.commit()
326
327return render_template('edit_profile.html', **params)
328
329
330@app.route('/profile/privacy')
331@login_required
332def privacy_settings():
333db_sess = db_session.create_session()
334
335params = {
336'current_user': db_sess.query(User).get(current_user.id),
337}
338
339return render_template('comingsoon.html', **params)
340
341@app.route('/messages/<int:peer>')
342@login_required
343def chat(peer:int):
344db_sess = db_session.create_session()
345curr_user = db_sess.query(User).get(current_user.id)
346
347
348
349params = {
350'current_user': curr_user,
351
352}
353
354
355@app.errorhandler(404)
356def page_not_found(e):
357return render_template('404.html'), 404
358
359
360@app.errorhandler(401)
361def unauthorized(e):
362return redirect('/login')
363
364
365@app.route('/test')
366@login_required
367def test():
368db_sess = db_session.create_session()
369
370params = {
371'current_user': db_sess.query(User).get(current_user.id),
372}
373
374return render_template('test_page.html', **params)
375
376@app.route('/about')
377def about():
378return render_template('about.html')
379
380
381
382if __name__ == '__main__':
383db_session.global_init("db/database.db")
384
385app.register_blueprint(funcs_api.blueprint)
386app.register_blueprint(music.blueprint)
387app.register_blueprint(weather.blueprint)
388
389api.add_resource(rest_api.PostListResource, '/api/posts/<int:user_id>')
390api.add_resource(rest_api.PostResource, '/api/post/<int:post_id>')
391api.add_resource(rest_api.FriendsResource, '/api/friends/<int:user_id>/<int:friend_id>')
392
393app.run(threaded=True, port=8080, debug=True)
394