Skip to content

Commit 7922a7b

Browse files
authored
Merge pull request #151 from Seluj78/view_profile
2 parents 62e2dd5 + aca58eb commit 7922a7b

File tree

13 files changed

+3090
-1866
lines changed

13 files changed

+3090
-1866
lines changed

PyMatcha.postman_collection.json

Lines changed: 2714 additions & 1816 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: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
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
35+
from PyMatcha.models.view import View
3436
from PyMatcha.utils import create_user_table
3537
from PyMatcha.utils import hash_password
3638
from PyMatcha.utils.orm import Field
@@ -207,27 +209,13 @@ def register(email: str, username: str, password: str, first_name: str, last_nam
207209
logging.debug("New user {} created".format(new_user.email))
208210
return new_user
209211

210-
def get_all_info(self) -> Dict:
211-
return {
212-
"id": self.id,
213-
"first_name": self.first_name,
214-
"last_name": self.last_name,
215-
"email": self.email,
216-
"username": self.username,
217-
"bio": self.bio,
218-
"gender": self.gender,
219-
"orientation": self.orientation,
220-
"birthdate": self.birthdate,
221-
"geohash": self.geohash,
222-
"tags": [t.name for t in self.get_tags()],
223-
"heat_score": self.heat_score,
224-
"is_online": self.is_online,
225-
"date_joined": self.date_joined,
226-
"date_lastseen": self.date_lastseen,
227-
"is_profile_completed": self.is_profile_completed,
228-
"is_confirmed": self.is_confirmed,
229-
"confirmed_on": self.confirmed_on,
230-
}
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+
returned_dict["reports"] = {"sent": [], "received": []}
216+
returned_dict["reports"]["sent"] = [r.to_dict() for r in self.get_reports_sent()]
217+
returned_dict["reports"]["received"] = [r.to_dict() for r in self.get_reports_received()]
218+
return returned_dict
231219

232220
@classmethod
233221
def create_table(cls):
@@ -253,7 +241,7 @@ def get_images(self) -> List[UserImage]:
253241
image_list.append(UserImage(image))
254242
return image_list
255243

256-
def get_base_info(self):
244+
def get_jwt_info(self):
257245
return {
258246
"id": self.id,
259247
"email": self.email,
@@ -281,6 +269,68 @@ def get_tags(self):
281269
tags_list.append(Tag(t))
282270
return tags_list
283271

272+
def get_views(self):
273+
logging.debug("Getting all views for user profile {}".format(self.id))
274+
with self.db.cursor() as c:
275+
c.execute(
276+
"""
277+
SELECT views.id as id, views.profile_id as profile_id,
278+
views.viewer_id as viewer_id, views.dt_seen as dt_seen
279+
FROM users
280+
INNER JOIN views on users.id = views.profile_id
281+
WHERE users.id = CAST({} AS UNSIGNED)
282+
""".format(
283+
self.id
284+
)
285+
)
286+
views = c.fetchall()
287+
views_list = []
288+
for v in views:
289+
views_list.append(View(v))
290+
return views_list
291+
292+
def get_reports_received(self):
293+
logging.debug("Getting all reports received for user {}".format(self.id))
294+
with self.db.cursor() as c:
295+
c.execute(
296+
"""
297+
SELECT reports.id as id, reports.reported_id as reported_id,
298+
reports.reporter_id as reporter_id, reports.dt_reported as dt_reported,
299+
reports.details as details, reports.reason as reason, reports.status as status
300+
FROM users
301+
INNER JOIN reports on users.id = reports.reported_id
302+
WHERE users.id = CAST({} AS UNSIGNED)
303+
""".format(
304+
self.id
305+
)
306+
)
307+
reports = c.fetchall()
308+
reports_list = []
309+
for r in reports:
310+
reports_list.append(Report(r))
311+
return reports_list
312+
313+
def get_reports_sent(self):
314+
logging.debug("Getting all reports sent for user {}".format(self.id))
315+
with self.db.cursor() as c:
316+
c.execute(
317+
"""
318+
SELECT reports.id as id, reports.reported_id as reported_id,
319+
reports.reporter_id as reporter_id, reports.dt_reported as dt_reported,
320+
reports.details as details, reports.reason as reason, reports.status as status
321+
FROM users
322+
INNER JOIN reports on users.id = reports.reporter_id
323+
WHERE users.id = CAST({} AS UNSIGNED)
324+
""".format(
325+
self.id
326+
)
327+
)
328+
reports = c.fetchall()
329+
reports_list = []
330+
for r in reports:
331+
reports_list.append(Report(r))
332+
return reports_list
333+
284334

285335
def get_user(uid: Any[int, str]) -> Optional[User]:
286336
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: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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_views_table
25+
from PyMatcha.utils.orm import Field
26+
from PyMatcha.utils.orm import Model
27+
28+
29+
class View(Model):
30+
table_name = "views"
31+
32+
id = Field(int, modifiable=False)
33+
profile_id = Field(int)
34+
viewer_id = Field(int)
35+
dt_seen = Field(datetime.datetime)
36+
37+
def before_init(self, data):
38+
pass
39+
40+
@staticmethod
41+
def create(profile_id: int, viewer_id: int, dt_seen: datetime.datetime = datetime.datetime.utcnow()) -> View:
42+
new_view = View(profile_id=profile_id, viewer_id=viewer_id, dt_seen=dt_seen)
43+
new_view.save()
44+
logging.debug("Creating new view")
45+
return new_view
46+
47+
@classmethod
48+
def create_table(cls):
49+
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: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import datetime
22

3+
import flask_jwt_extended as fjwt
34
import PyMatcha.models.user as user
45
from flask import Blueprint
56
from flask import current_app
67
from flask import jsonify
8+
from flask import request
79
from PyMatcha import redis
810
from PyMatcha.errors import NotFoundError
11+
from PyMatcha.models.report import Report
12+
from PyMatcha.models.view import View
913
from PyMatcha.success import Success
1014
from PyMatcha.success import SuccessDeleted
1115
from PyMatcha.utils.decorators import debug_token_required
16+
from PyMatcha.utils.decorators import validate_params
1217

1318
debug_bp = Blueprint("debug", __name__)
1419

@@ -52,8 +57,26 @@ def delete_user(uid):
5257
return SuccessDeleted("User {} Deleted".format(uid))
5358

5459

60+
@debug_bp.route("/debug/views/<int:amount>", methods=["POST"])
61+
@debug_token_required
62+
@fjwt.jwt_required
63+
def create_views(amount):
64+
current_user = fjwt.current_user
65+
for i in range(amount):
66+
View.create(profile_id=current_user.id, viewer_id=i)
67+
return Success(f"Added {amount} views to user {current_user.id}")
68+
69+
70+
@debug_bp.route("/debug/views", methods=["DELETE"])
71+
@debug_token_required
72+
def delete_views():
73+
View.drop_table()
74+
View.create_table()
75+
return "", 204
76+
77+
5578
@debug_bp.route("/debug/redis")
56-
# @debug_token_required
79+
@debug_token_required
5780
def debug_show_redis():
5881
ret = {"users": {}, "jtis": {}}
5982
for key in redis.scan_iter("user:*"):
@@ -63,3 +86,45 @@ def debug_show_redis():
6386
value = redis.get(str(key))
6487
ret["jtis"][key] = value
6588
return jsonify(ret), 200
89+
90+
91+
@debug_bp.route("/debug/reports", methods=["DELETE"])
92+
@debug_token_required
93+
def delete_reports():
94+
Report.drop_table()
95+
Report.create_table()
96+
return "", 204
97+
98+
99+
@debug_bp.route("/debug/reports", methods=["GET"])
100+
@debug_token_required
101+
def debug_get_all_reports():
102+
report_list = []
103+
for r in Report.select_all():
104+
report_list.append(r.to_dict())
105+
return jsonify(report_list)
106+
107+
108+
@debug_bp.route("/debug/reports/<uid>", methods=["GET"])
109+
@debug_token_required
110+
def debug_get_user_reports(uid):
111+
u = get_user(uid)
112+
reports_received = [r.to_dict() for r in u.get_reports_received()]
113+
reports_sent = [r.to_dict() for r in u.get_reports_sent()]
114+
return jsonify({"reports_received": reports_received, "reports_sent": reports_sent}), 200
115+
116+
117+
DEBUG_CREATE_FAKE_REPORT = {"reporter_id": int, "reported_id": int, "reason": str, "details": str}
118+
119+
120+
@debug_bp.route("/debug/reports", methods=["POST"])
121+
@debug_token_required
122+
@validate_params(DEBUG_CREATE_FAKE_REPORT)
123+
def debug_create_report():
124+
data = request.get_json()
125+
reporter_id = data["reporter_id"]
126+
reported_id = data["reported_id"]
127+
reason = data["reason"]
128+
details = data["details"]
129+
Report.create(reported_id=reported_id, reporter_id=reporter_id, reason=reason, details=details)
130+
return "", 204

0 commit comments

Comments
 (0)