Skip to content

Commit 60285f9

Browse files
authored
Merge pull request #347 from Seluj78/feature/block
2 parents 817423c + 516c84a commit 60285f9

File tree

8 files changed

+152
-36
lines changed

8 files changed

+152
-36
lines changed

backend/PyMatcha/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@
178178
from PyMatcha.routes.api.recommendations import recommendations_bp
179179
from PyMatcha.routes.api.profile.images import images_bp
180180
from PyMatcha.routes.api.search import search_bp
181+
from PyMatcha.routes.api.profile.block import profile_block_bp
181182

182183
logging.debug("Registering Flask blueprints")
183184
application.register_blueprint(user_bp)
@@ -195,6 +196,7 @@
195196
application.register_blueprint(recommendations_bp)
196197
application.register_blueprint(images_bp)
197198
application.register_blueprint(search_bp)
199+
application.register_blueprint(profile_block_bp)
198200

199201
if application.debug:
200202
logging.debug("Registering debug route")

backend/PyMatcha/models/block.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""
2+
PyMatcha - A Python Dating Website
3+
Copyright (C) 2018-2019 jlasne/gmorer
4+
<jlasne@student.42.fr> - <lauris.skraucis@gmail.com>
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
"""
19+
from __future__ import annotations
20+
21+
import datetime
22+
import logging
23+
24+
from PyMatcha.utils import create_blocks_table
25+
from PyMatcha.utils.orm import Field
26+
from PyMatcha.utils.orm import Model
27+
28+
29+
class Block(Model):
30+
table_name = "blocks"
31+
32+
id = Field(int, modifiable=False)
33+
blocker_id = Field(int)
34+
blocked_id = Field(int)
35+
dt_blocked = Field(datetime.datetime, fmt="%Y-%m-%d %H:%M:%S")
36+
37+
@staticmethod
38+
def create(blocker_id: int, blocked_id: int, dt_blocked: datetime.datetime = datetime.datetime.utcnow()) -> Block:
39+
new_blocked = Block(blocker_id=blocker_id, blocked_id=blocked_id, dt_blocked=dt_blocked)
40+
new_blocked.save()
41+
logging.debug("Creating new block")
42+
return new_blocked
43+
44+
@classmethod
45+
def create_table(cls):
46+
create_blocks_table(cls.db)

backend/PyMatcha/models/user.py

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from typing import Optional
2727

2828
import Geohash
29+
from PyMatcha.models.block import Block
2930
from PyMatcha.models.image import Image
3031
from PyMatcha.models.like import Like
3132
from PyMatcha.models.match import Match
@@ -204,6 +205,7 @@ def to_dict(self) -> Dict:
204205
returned_dict["likes"]["sent"] = [like.to_dict() for like in self.get_likes_sent()]
205206
returned_dict["likes"]["received"] = [like.to_dict() for like in self.get_likes_received()]
206207
returned_dict["last_seen"] = timeago_format(self.date_lastseen, datetime.datetime.utcnow())
208+
returned_dict["blocks"] = [block.to_dict() for block in self.get_blocks()]
207209
returned_dict.pop("password")
208210
returned_dict.pop("previous_reset_token")
209211

@@ -233,59 +235,34 @@ def get_jwt_info(self):
233235

234236
def get_images(self):
235237
logging.debug("Getting all images for user {}".format(self.id))
236-
image_list = Image.get_multis(user_id=self.id)
237-
if not image_list:
238-
return []
239-
else:
240-
return image_list
238+
return Image.get_multis(user_id=self.id)
241239

242240
def get_tags(self):
243241
logging.debug("Getting all tags for user {}".format(self.id))
244-
tag_list = Tag.get_multis(user_id=self.id)
245-
if not tag_list:
246-
return []
247-
else:
248-
return tag_list
242+
return Tag.get_multis(user_id=self.id)
249243

250244
def get_views(self):
251245
logging.debug("Getting all views for user profile {}".format(self.id))
252-
view_list = View.get_multis(profile_id=self.id)
253-
if not view_list:
254-
return []
255-
else:
256-
return view_list
246+
return View.get_multis(profile_id=self.id)
257247

258248
def get_reports_received(self):
259249
logging.debug("Getting all reports received for user {}".format(self.id))
260-
reports_received_list = Report.get_multis(reported_id=self.id)
261-
if not reports_received_list:
262-
return []
263-
else:
264-
return reports_received_list
250+
return Report.get_multis(reported_id=self.id)
265251

266252
def get_reports_sent(self):
267253
logging.debug("Getting all reports sent for user {}".format(self.id))
268-
reports_sent_list = Report.get_multis(reporter_id=self.id)
269-
if not reports_sent_list:
270-
return []
271-
else:
272-
return reports_sent_list
254+
return Report.get_multis(reporter_id=self.id)
273255

274256
def get_likes_received(self):
275257
logging.debug("Getting all likes received for user {}".format(self.id))
276-
likes_received_list = Like.get_multis(liked_id=self.id)
277-
if not likes_received_list:
278-
return []
279-
else:
280-
return likes_received_list
258+
return Like.get_multis(liked_id=self.id)
281259

282260
def get_likes_sent(self):
283261
logging.debug("Getting all likes sent for user {}".format(self.id))
284-
likes_sent_list = Like.get_multis(liker_id=self.id)
285-
if not likes_sent_list:
286-
return []
287-
else:
288-
return likes_sent_list
262+
return Like.get_multis(liker_id=self.id)
263+
264+
def get_blocks(self):
265+
return Block.get_multis(blocker_id=self.id)
289266

290267
def already_likes(self, liked_id: int) -> bool:
291268
with self.db.cursor() as c:
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""
2+
PyMatcha - A Python Dating Website
3+
Copyright (C) 2018-2019 jlasne/gmorer
4+
<jlasne@student.42.fr> - <lauris.skraucis@gmail.com>
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
"""
19+
from flask import Blueprint
20+
from flask_jwt_extended import current_user
21+
from flask_jwt_extended import jwt_required
22+
from PyMatcha.models.block import Block
23+
from PyMatcha.models.user import get_user
24+
from PyMatcha.utils.errors import BadRequestError
25+
from PyMatcha.utils.errors import NotFoundError
26+
from PyMatcha.utils.success import Success
27+
28+
profile_block_bp = Blueprint("profile_block", __name__)
29+
30+
31+
@profile_block_bp.route("/profile/block/<uid>", methods=["POST"])
32+
@jwt_required
33+
def block_profile(uid):
34+
try:
35+
u = get_user(uid)
36+
except NotFoundError:
37+
raise NotFoundError(f"User {uid} not found.")
38+
if current_user.id == u.id:
39+
raise BadRequestError("Cannot block yourself.")
40+
try:
41+
Block.get_multi(blocker_id=current_user.id, blocked_id=u.id)
42+
except NotFoundError:
43+
Block.create(blocker_id=current_user.id, blocked_id=u.id)
44+
return Success(f"Successfully blocked {u.email}.")
45+
else:
46+
return BadRequestError("You already blocked this user.")
47+
48+
49+
@profile_block_bp.route("/profile/unblock/<uid>", methods=["POST"])
50+
@jwt_required
51+
def unblock_profile(uid):
52+
try:
53+
u = get_user(uid)
54+
except NotFoundError:
55+
raise NotFoundError(f"User {uid} not found.")
56+
try:
57+
block = Block.get_multi(blocker_id=current_user.id, blocked_id=u.id)
58+
except NotFoundError:
59+
raise BadRequestError("You didn't block this user.")
60+
else:
61+
block.delete()
62+
return Success("Unblock successful.")

backend/PyMatcha/routes/api/search.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,15 @@ def search():
4343
query = _get_gender_query(current_user.orientation, current_user.gender)
4444
matches_id = [match.id for match in current_user.get_matches()]
4545
likes_sent_user_ids = [like.liked_id for like in current_user.get_likes_sent()]
46+
blocked_ids = [u.blocked_id for u in current_user.get_blocks()]
4647
returned_list = []
4748
for user in query:
4849
if user.id == current_user.id:
4950
continue
5051
if user.id in matches_id or user.id in likes_sent_user_ids:
5152
continue
53+
if user.id in blocked_ids:
54+
continue
5255

5356
user_age = (
5457
today.year - user.birthdate.year - ((today.month, today.day) < (user.birthdate.month, user.birthdate.day))
@@ -84,7 +87,6 @@ def search():
8487
common_tags = _get_common_tags(tags, user_tags)
8588
if not common_tags:
8689
# No tags has been found
87-
common_tags = []
8890
continue
8991

9092
user_dict = user.to_dict()

backend/PyMatcha/utils/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from PyMatcha.utils.password import hash_password
2+
from PyMatcha.utils.tables import _create_blocks_table
23
from PyMatcha.utils.tables import _create_images_table
34
from PyMatcha.utils.tables import _create_likes_table
45
from PyMatcha.utils.tables import _create_matches_table
@@ -17,6 +18,7 @@
1718
create_matches_table = _create_matches_table
1819
create_messages_table = _create_messages_table
1920
create_images_table = _create_images_table
21+
create_blocks_table = _create_blocks_table
2022

2123
__all__ = [
2224
"hash_password",
@@ -29,4 +31,5 @@
2931
"create_matches_table",
3032
"create_messages_table",
3133
"create_images_table",
34+
"create_blocks_table",
3235
]

backend/PyMatcha/utils/recommendations.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,16 @@ def create_user_recommendations(user_to_update):
3535

3636
matches_id = [match.id for match in user_to_update.get_matches()]
3737
likes_sent_user_ids = [like.liked_id for like in user_to_update.get_likes_sent()]
38+
blocked_ids = [u.blocked_id for u in user_to_update.get_blocks()]
3839

3940
for user in query:
4041
if user.id == user_to_update.id:
4142
continue
4243
if user.id in matches_id or user.id in likes_sent_user_ids:
4344
continue
45+
if user.id in blocked_ids:
46+
continue
47+
4448
score = 0
4549

4650
distance = _get_distance(user_to_update.geohash, user.geohash)

backend/PyMatcha/utils/tables.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,25 @@ def _create_images_table(db):
200200
c.close()
201201

202202

203+
def _create_blocks_table(db):
204+
with db.cursor() as c:
205+
logging.info("Creating table blocks.")
206+
c.execute(DISABLE_SQL_NOTES)
207+
c.execute(
208+
"""
209+
CREATE TABLE IF NOT EXISTS blocks
210+
(
211+
id INT auto_increment PRIMARY KEY,
212+
blocker_id INT NOT NULL,
213+
blocked_id INT NOT NULL,
214+
dt_blocked DATETIME DEFAULT NOW()
215+
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci ;
216+
"""
217+
)
218+
c.execute(ENABLE_SQL_NOTES)
219+
c.close()
220+
221+
203222
def create_tables(db):
204223
_create_user_table(db)
205224
_create_tags_table(db)
@@ -209,3 +228,4 @@ def create_tables(db):
209228
_create_matches_table(db)
210229
_create_messages_table(db)
211230
_create_images_table(db)
231+
_create_blocks_table(db)

0 commit comments

Comments
 (0)