-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
334 lines (284 loc) · 12.6 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
from enum import unique
from flask import Flask, request, redirect, url_for, Response, flash, render_template
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.sql import func
from sqlalchemy.ext.declarative import declarative_base
from flask_login import UserMixin, LoginManager, login_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash
import locale
locale.setlocale(locale.LC_ALL, "tr")
# Flask ayarları yapılıyor
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret-key-goes-here'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
# SQLAlchemy nesnesi oluşturuluyor
db = SQLAlchemy(app)
# Flask Login Kütüphanesinin kurulumu yapılıyor
login_manager = LoginManager()
login_manager.init_app(app)
Base = declarative_base()
# Kullanıcı Takip Tablosu
follow = db.Table('user_followers',
db.Column('follower_id', db.Integer,
db.ForeignKey('user.id')),
db.Column('followed_id', db.Integer,
db.ForeignKey('user.id'))
)
# Kullanıcı Beğeni Tablosu
likes = db.Table('user_likes',
db.Column('user_id', db.Integer,
db.ForeignKey('user.id')),
db.Column('tweet_id', db.Integer,
db.ForeignKey('tweet.id'))
)
# Kullanıcı Retweet Tablosu
retweets = db.Table('user_retweets',
db.Column('user_id', db.Integer,
db.ForeignKey('user.id')),
db.Column('tweet_id', db.Integer,
db.ForeignKey('tweet.id')),
db.Column('created_at', db.DateTime(timezone=True),
server_default=func.now())
)
# Tweet Hashtag Tablosu
hashtags = db.Table('tweet_hashtags',
db.Column('tweet_id', db.Integer,
db.ForeignKey('tweet.id')),
db.Column('hashtag_id', db.Integer,
db.ForeignKey('hashtag.id'))
)
# Kullanıcı Modeli
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(120), nullable=False)
tweets = db.relationship('Tweet', order_by="Tweet.created_at")
following = db.relationship('User', secondary=follow, primaryjoin=(
follow.c.follower_id == id), secondaryjoin=(follow.c.followed_id == id), backref=db.backref('followers', lazy='dynamic'), lazy='dynamic')
likes = db.relationship('Tweet', secondary=likes, backref=db.backref(
'likes', lazy='dynamic'), lazy='dynamic')
retweets = db.relationship('Tweet', secondary=retweets, backref=db.backref(
'retweets', lazy='dynamic'))
created_at = db.Column(db.DateTime(timezone=True),
server_default=func.now())
def __repr__(self):
return '<User %r>' % self.username
# Tweet Modeli
class Tweet(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(280), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
created_at = db.Column(db.DateTime(timezone=True),
server_default=func.now())
user = db.relationship('User')
# Hashtag Modeli
class Hashtag(db.Model):
id = db.Column(db.Integer, primary_key=True)
tag = db.Column(db.String(100), unique=True)
tweets = db.relationship('Tweet', secondary=hashtags, backref=db.backref(
'hashtags', lazy='dynamic'), lazy='dynamic', order_by="Tweet.created_at")
# flask_login kütüphanesine cookie ile kullanıcıları nasıl eşletireceğini öğretiyoruz
@login_manager.user_loader
def user_loader(id):
# cookieden gelen id ile kullanıcıyı veritabanında arıyor
user = User.query.filter_by(id=id).first()
if user is None:
return
return user
# Kullanıcı ve Hashtag işlemlerini template içinde yapabilmek için gerekli kod
@app.context_processor
def inject_stage_and_region():
return dict(User_Query=User, Hashtag_Query=Hashtag)
# Anasayfa için home.html render ediliyor ve bütün tweetler gönderiliyor
@app.route('/')
# Bu sayfayı görebilmek için kullanıcının giriş yapması gerekli
@login_required
def home():
return render_template("home.html", Tweets=Tweet.query.all())
@app.route('/login', methods=['GET', 'POST'])
def login():
# Eğer isteğin methodu GET ise login.html sayfası gösteriliyor.
if request.method == 'GET':
return render_template("login.html")
# Formda verilen email ile kullanıcı aranıyor bulunur ve girilen şifre doğruysa login_user fonksiyonu çağırılıyor
user = User.query.filter_by(email=request.form.get('email')).first()
# check_password_hash pbkdf2 algoritması için doğrulama yapıyor
if user is not None and check_password_hash(user.password, request.form['password']):
login_user(user)
return redirect(url_for('home'))
# email veya şifre yanlış ise formda gözükmesi için hata fırlatılıyor
flash("Kulanıcı adı veya şifre yanlış")
# login sayfasına geri yönlendiriliyor
return redirect(url_for('login'))
# Giriş yapmamış kullanıcıları login sayfasına yönlendiren fonksiyon
@login_manager.unauthorized_handler
def unauthorized_callback():
return redirect('/login?next=' + request.path)
@app.route('/register', methods=['GET', 'POST'])
def register():
# Kayıt formuna yapılan istek GET methoduysa register.html sayfası gösteriliyor
if request.method == 'GET':
return render_template("register.html")
# Gönderilen formdaki emailin kullanılıp kullanılmadığına bakılıyor
if User.query.filter_by(email=request.form.get('email')).first() is None:
# Formda girilen verilerle yeni bir kullanıcı oluşturuluyor ve şifresi hashleniyor
user = User(name=request.form['name'],
username=request.form['username'],
email=request.form['email'],
password=generate_password_hash(request.form['password']))
# Oluşturulan kullanıcı veritabanına ekleniyor
db.session.add(user)
db.session.commit()
# Kullanıcı kayıt edildikten sonra giriş yaptırılıyor ve anasayfaya yönlendiriliyor
login_user(user)
return redirect(url_for('home'))
else:
# Eğer email varsa hata fırlatılıyor
flash("Email zaten var")
return redirect(url_for('register'))
@app.route('/follow', methods=['POST'])
@login_required
def follow():
# Takip edilecek kişinin idsi alınıyor
id = request.form.get("id")
# id yoksa anasayfaya yönlendiriliyor
if id is not None:
# verilen id ile ilişkili kullanıcı getiriliyor
user = User.query.get(id)
# kullanıcı bulunamadıysa anasayfaya yönlendiriliyor
if user is None:
return redirect(url_for("home"))
# kullanıcının takipçi listesine isteği gönderen kullanıcı ekleniyor
user.followers.append(current_user)
db.session.commit()
return redirect(url_for("home"))
@app.route('/unfollow', methods=['POST'])
@login_required
def unfollow():
# Takipten çıkarılacak kişinin idsi alınıyor
id = request.form.get("id")
# id yoksa anasayfaya yönlendiriliyor
if id is not None:
# verilen id ile ilişkili kullanıcı getiriliyor
user = User.query.get(id)
# kullanıcı bulunamadıysa anasayfaya yönlendiriliyor
if user is None:
return redirect(url_for("home"))
# kullanıcının takipçi listesinden isteği gönderen kullanıcı çıkarılıyor
user.followers.remove(current_user)
db.session.commit()
return redirect(url_for("home"))
@app.route('/like', methods=['POST'])
@login_required
def like():
# Beğenilecek tweetin idsi alınıyor
id = request.form.get("id")
# id yoksa anasayfaya yönlendiriliyor
if id is not None:
# verilen id ile ilişkili tweet getiriliyor
tweet = Tweet.query.get(id)
# tweet bulunamadıysa anasayfaya yönlendiriliyor
if tweet is None:
return redirect(url_for("home"))
# tweetin önceden beğenilip beğenilmediği kontrol ediliyor
if tweet.likes.filter_by(id=current_user.id).count() > 0:
return redirect(url_for("home"))
# tweetin beğeni listesine isteği gönderen kullanıcı ekleniyor
tweet.likes.append(current_user)
db.session.commit()
return redirect(url_for("home"))
@app.route('/unlike', methods=['POST'])
@login_required
def unlike():
# Beğenisi çekilecek tweetin idsi alınıyor
id = request.form.get("id")
# id yoksa anasayfaya yönlendiriliyor
if id is not None:
# verilen id ile ilişkili tweet getiriliyor
tweet = Tweet.query.get(id)
# tweet bulunamadıysa anasayfaya yönlendiriliyor
if tweet is None:
return redirect(url_for("home"))
# tweetin beğeni listesinden isteği gönderen kullanıcı siliniyor
tweet.likes.remove(current_user)
db.session.commit()
return redirect(url_for("home"))
@app.route('/retweet', methods=['POST'])
@login_required
def retweet():
id = request.form.get("id")
if id is not None:
tweet = Tweet.query.get(id)
if tweet is None:
return redirect(url_for("home"))
if tweet.retweets.filter_by(id=current_user.id).count() > 0:
return redirect(url_for("home"))
tweet.retweets.append(current_user)
db.session.commit()
return redirect(url_for("home"))
@app.route('/undo_retweet', methods=['POST'])
@login_required
def unretweet():
id = request.form.get("id")
if id is not None:
tweet = Tweet.query.get(id)
if tweet is None:
return redirect(url_for("home"))
tweet.retweets.remove(current_user)
db.session.commit()
return redirect(url_for("home"))
@app.route('/user/<path>')
def profile(path):
# kullanıcı adı ile ilişkili kullanıcı getiriliyor
user = User.query.filter_by(username=path).first()
if user is not None:
# varsa profile.html sayfasına kullanıcı bilgileri ve tweetleri gönderiliyor
return render_template("profile.html", User=user, Tweets=user.tweets+user.retweets)
# eğer kullanıcı yoksa 404 hatası döndürülüyor
return Response(status=404)
@app.route('/hashtag/<tag>')
def hashtag(tag):
# tag ile ilişkili hashtag getiriliyor
hashtag = Hashtag.query.filter_by(tag=tag).first()
if hashtag is not None:
# varsa hashtag.html sayfasına hashtag bilgileri gönderiliyor
return render_template("hashtag.html", Hashtag=hashtag)
# eğer hashtag yoksa 404 hatası döndürülüyor
return Response(status=404)
@app.route('/<username>/<id>')
def tweet(username, id):
# id ile ilişkilendirilmiş tweet getiriliyor
tweet = Tweet.query.get(id)
# tweet yoksa 404 hatası döndürülüyor
if tweet is None:
return Response(status=404)
# urldeki kullanıcı adı ile tweeti atan kişi eşleşmiyorsa 404 hatası döndürülüyor
if tweet.user.username != username:
return Response(status=404)
# tweet.html sayfasına tweet bilgileri gönderiliyor
return render_template("tweet.html", Tweet=tweet)
@app.route('/hashtags')
def hashtags():
# hashtags.html sayfasına bütün hashtagler ve bilgileri gönderiliyor
return render_template("hashtags.html", Hashtags=Hashtag.query.all())
@app.route('/bit', methods=[ 'POST'])
@login_required
def create_bit():
content = request.form.get("content")
tweet = Tweet(user_id=current_user.id,
content=content)
db.session.add(tweet)
for tag in content.split(" "):
if not tag.startswith("#"):
continue
t = Hashtag.query.filter_by(tag=tag[1:]).first()
if t is not None:
t.tweets.append(tweet)
else:
t = Hashtag(tag=tag[1:])
t.tweets.append(tweet)
db.session.add(t)
db.session.commit()
return redirect(url_for('home'))