Skip to content

Commit 6f0c2b8

Browse files
committed
Added reports + to_dict method
1 parent eec4b20 commit 6f0c2b8

File tree

13 files changed

+2410
-2034
lines changed

13 files changed

+2410
-2034
lines changed

PyMatcha.postman_collection.json

Lines changed: 2197 additions & 1978 deletions
Large diffs are not rendered by default.

backend/PyMatcha/models/report.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""
2+
PyMatcha - A Python Dating Website
3+
Copyright (C) 2018-2019 jlasne/gmorer
4+
<jlasne@student.42.fr> - <gmorer@student.42.fr>
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_reports_table
25+
from PyMatcha.utils.orm import Field
26+
from PyMatcha.utils.orm import Model
27+
28+
29+
class Report(Model):
30+
table_name = "reports"
31+
32+
id = Field(int, modifiable=False)
33+
reporter_id = Field(int)
34+
reported_id = Field(int)
35+
dt_reported = Field(datetime.datetime)
36+
details = Field(str)
37+
reason = Field(str)
38+
status = Field(str)
39+
40+
def before_init(self, data):
41+
pass
42+
43+
@staticmethod
44+
def create(
45+
reported_id: int,
46+
reporter_id: int,
47+
reason: str,
48+
details: str = None,
49+
dt_reported: datetime.datetime = datetime.datetime.utcnow(),
50+
) -> Report:
51+
new_report = Report(
52+
reported_id=reported_id, reporter_id=reporter_id, reason=reason, details=details, dt_reported=dt_reported
53+
)
54+
new_report.save()
55+
logging.debug("Creating new report")
56+
return new_report
57+
58+
@classmethod
59+
def create_table(cls):
60+
create_reports_table(cls.db)

backend/PyMatcha/models/tag.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from __future__ import annotations
2020

2121
import logging
22-
from typing import Dict
2322

2423
from PyMatcha.utils import create_tags_table
2524
from PyMatcha.utils.orm import Field
@@ -43,9 +42,6 @@ def create(user_id: int, name="") -> Tag:
4342
logging.debug("Creating new tag")
4443
return new_tag
4544

46-
def get_all_info(self) -> Dict:
47-
return {"id": self.id, "user_id": self.user_id, "name": self.name}
48-
4945
@classmethod
5046
def create_table(cls):
5147
create_tags_table(cls.db)

backend/PyMatcha/models/user.py

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import PyMatcha.models.user_image as user_image
3131
from PyMatcha.errors import ConflictError
3232
from PyMatcha.errors import NotFoundError
33+
from PyMatcha.models.report import Report
3334
from PyMatcha.models.tag import Tag
3435
from PyMatcha.models.view import View
3536
from PyMatcha.utils import create_user_table
@@ -208,27 +209,10 @@ def register(email: str, username: str, password: str, first_name: str, last_nam
208209
logging.debug("New user {} created".format(new_user.email))
209210
return new_user
210211

211-
def get_all_info(self) -> Dict:
212-
return {
213-
"id": self.id,
214-
"first_name": self.first_name,
215-
"last_name": self.last_name,
216-
"email": self.email,
217-
"username": self.username,
218-
"bio": self.bio,
219-
"gender": self.gender,
220-
"orientation": self.orientation,
221-
"birthdate": self.birthdate,
222-
"geohash": self.geohash,
223-
"tags": [t.name for t in self.get_tags()],
224-
"heat_score": self.heat_score,
225-
"is_online": self.is_online,
226-
"date_joined": self.date_joined,
227-
"date_lastseen": self.date_lastseen,
228-
"is_profile_completed": self.is_profile_completed,
229-
"is_confirmed": self.is_confirmed,
230-
"confirmed_on": self.confirmed_on,
231-
}
212+
def to_dict(self) -> Dict:
213+
returned_dict = super().to_dict()
214+
returned_dict["tags"] = [t.to_dict() for t in self.get_tags()]
215+
return returned_dict
232216

233217
@classmethod
234218
def create_table(cls):
@@ -254,7 +238,7 @@ def get_images(self) -> List[UserImage]:
254238
image_list.append(UserImage(image))
255239
return image_list
256240

257-
def get_base_info(self):
241+
def get_jwt_info(self):
258242
return {
259243
"id": self.id,
260244
"email": self.email,
@@ -302,6 +286,48 @@ def get_views(self):
302286
views_list.append(View(v))
303287
return views_list
304288

289+
def get_reports_received(self):
290+
logging.debug("Getting all reports received for user {}".format(self.id))
291+
with self.db.cursor() as c:
292+
c.execute(
293+
"""
294+
SELECT reports.id as id, reports.reported_id as reported_id,
295+
reports.reporter_id as reporter_id, reports.dt_reported as dt_reported,
296+
reports.details as details, reports.reason as reason, reports.status as status
297+
FROM users
298+
INNER JOIN reports on users.id = reports.reported_id
299+
WHERE users.id = CAST({} AS UNSIGNED)
300+
""".format(
301+
self.id
302+
)
303+
)
304+
reports = c.fetchall()
305+
reports_list = []
306+
for r in reports:
307+
reports_list.append(Report(r))
308+
return reports_list
309+
310+
def get_reports_sent(self):
311+
logging.debug("Getting all reports sent for user {}".format(self.id))
312+
with self.db.cursor() as c:
313+
c.execute(
314+
"""
315+
SELECT reports.id as id, reports.reported_id as reported_id,
316+
reports.reporter_id as reporter_id, reports.dt_reported as dt_reported,
317+
reports.details as details, reports.reason as reason, reports.status as status
318+
FROM users
319+
INNER JOIN reports on users.id = reports.reporter_id
320+
WHERE users.id = CAST({} AS UNSIGNED)
321+
""".format(
322+
self.id
323+
)
324+
)
325+
reports = c.fetchall()
326+
reports_list = []
327+
for r in reports:
328+
reports_list.append(Report(r))
329+
return reports_list
330+
305331

306332
def get_user(uid: Any[int, str]) -> Optional[User]:
307333
not_found = 0

backend/PyMatcha/models/user_image.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@
1616
You should have received a copy of the GNU General Public License
1717
along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
"""
19-
2019
from __future__ import annotations
2120

2221
import logging
2322
from datetime import datetime
24-
from typing import Dict
2523

2624
from PyMatcha.utils import create_user_images_table
27-
from PyMatcha.utils.orm import Model, Field
25+
from PyMatcha.utils.orm import Field
26+
from PyMatcha.utils.orm import Model
2827

2928

3029
class UserImage(Model):
@@ -48,15 +47,6 @@ def create(
4847
logging.debug("Creating new user image")
4948
return new_image
5049

51-
def get_all_info(self) -> Dict:
52-
return {
53-
"id": self.id,
54-
"user_id": self.user_id,
55-
"description": self.description,
56-
"timestamp": self.timestamp,
57-
"is_primary": self.is_primary,
58-
}
59-
6050
@classmethod
6151
def create_table(cls):
6252
create_user_images_table(cls.db)

backend/PyMatcha/models/view.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
import datetime
2222
import logging
23-
from typing import Dict
2423

2524
from PyMatcha.utils import create_views_table
2625
from PyMatcha.utils.orm import Field
@@ -45,9 +44,6 @@ def create(profile_id: int, viewer_id: int, dt_seen: datetime.datetime = datetim
4544
logging.debug("Creating new view")
4645
return new_view
4746

48-
def get_all_info(self) -> Dict:
49-
return {"id": self.id, "profile_id": self.profile_id, "viewer_id": self.viewer_id, "dt_seen": self.dt_seen}
50-
5147
@classmethod
5248
def create_table(cls):
5349
create_views_table(cls.db)

backend/PyMatcha/routes/api/auth.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ def auth_login():
192192
if not u.is_confirmed:
193193
current_app.logger.debug("/auth/login -> User is trying to login unconfirmed")
194194
raise UnauthorizedError("User needs to be confirmed first.", "Try again when you have confirmed your email")
195-
access_token = fjwt.create_access_token(identity=u.get_base_info(), fresh=True)
196-
refresh_token = fjwt.create_refresh_token(identity=u.get_base_info())
195+
access_token = fjwt.create_access_token(identity=u.get_jwt_info(), fresh=True)
196+
refresh_token = fjwt.create_refresh_token(identity=u.get_jwt_info())
197197
access_jti = fjwt.get_jti(access_token)
198198
refresh_jti = fjwt.get_jti(refresh_token)
199199

backend/PyMatcha/routes/api/debug.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from flask import jsonify
88
from PyMatcha import redis
99
from PyMatcha.errors import NotFoundError
10+
from PyMatcha.models.report import Report
1011
from PyMatcha.models.view import View
1112
from PyMatcha.success import Success
1213
from PyMatcha.success import SuccessDeleted
@@ -83,3 +84,29 @@ def debug_show_redis():
8384
value = redis.get(str(key))
8485
ret["jtis"][key] = value
8586
return jsonify(ret), 200
87+
88+
89+
@debug_bp.route("/debug/reports", methods=["DELETE"])
90+
@debug_token_required
91+
def delete_reports():
92+
Report.drop_table()
93+
Report.create_table()
94+
return "", 204
95+
96+
97+
@debug_bp.route("/debug/reports")
98+
@debug_token_required
99+
def debug_get_all_reports():
100+
report_list = []
101+
for r in Report.select_all():
102+
report_list.append(r.to_dict())
103+
return jsonify(report_list)
104+
105+
106+
@debug_bp.route("/debug/reports/<uid>")
107+
@debug_token_required
108+
def debug_get_user_reports(uid):
109+
u = get_user(uid)
110+
reports_received = [r.to_dict() for r in u.get_reports_received()]
111+
reports_sent = [r.to_dict() for r in u.get_reports_sent()]
112+
return jsonify({"reports_received": reports_received, "reports_sent": reports_sent}), 200

backend/PyMatcha/routes/api/profile.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from PyMatcha.errors import BadRequestError
2929
from PyMatcha.errors import NotFoundError
3030
from PyMatcha.errors import UnauthorizedError
31+
from PyMatcha.models.report import Report
3132
from PyMatcha.models.tag import Tag
3233
from PyMatcha.models.view import View
3334
from PyMatcha.success import Success
@@ -198,7 +199,7 @@ def edit_geolocation():
198199
def get_profile_views():
199200
current_user = fjwt.current_user
200201
profile_views = current_user.get_views()
201-
profile_views = [v.get_all_info() for v in profile_views]
202+
profile_views = [v.to_dict() for v in profile_views]
202203
return SuccessOutput("views", profile_views)
203204

204205

@@ -214,4 +215,30 @@ def view_profile(uid):
214215
if current_user.id != u.id:
215216
View.create(profile_id=u.id, viewer_id=current_user.id)
216217

217-
return SuccessOutput("profile", u.get_all_info())
218+
return SuccessOutput("profile", u.to_dict())
219+
220+
221+
@profile_bp.route("/profile/report/<uid>", methods=["POST"])
222+
@validate_params({"reason": str}, {"details": str})
223+
@fjwt.jwt_required
224+
def report_profile(uid):
225+
current_user = fjwt.current_user
226+
data = request.get_json()
227+
reason = data["reason"]
228+
229+
if reason not in ["harassment", "bot", "spam", "inappropriate content"]:
230+
raise BadRequestError("Reason must be 'harassment', 'bot', 'spam' or 'inappropriate content'", "Try again")
231+
232+
try:
233+
details = data["details"]
234+
except KeyError:
235+
details = None
236+
try:
237+
u = get_user(uid)
238+
except NotFoundError:
239+
raise NotFoundError(f"User {uid} not found", "try again")
240+
if current_user.id == u.id:
241+
raise BadRequestError("Cannot report yourself", "Try again")
242+
Report.create(reporter_id=current_user.id, reported_id=u.id, reason=reason, details=details)
243+
244+
return Success(f"Report created on user {u.id} {u.get_reports_sent()} {u.get_reports_received()}")

backend/PyMatcha/routes/api/user.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def get_all_users():
3636
current_app.logger.info("/users/ -> Call")
3737
user_list = []
3838
for u in User.select_all():
39-
user_list.append(u.get_all_info())
39+
user_list.append(u.to_dict())
4040
current_app.logger.info("/users/ -> Returning all users list")
4141
return jsonify(user_list)
4242

@@ -51,7 +51,7 @@ def get_one_user(uid):
5151
raise NotFoundError("User {} not found".format(uid), "Check given uid and try again")
5252
else:
5353
current_app.logger.info("/users/{} -> Returning info on user {}".format(uid, uid))
54-
return jsonify(u.get_all_info())
54+
return jsonify(u.to_dict())
5555

5656

5757
@user_bp.route("/users/online", methods=["GET"])

0 commit comments

Comments
 (0)