Skip to content

Commit a7fab8e

Browse files
committed
Merge branch 'fix/missing-signal' into 'master'
Ensure the event listeners are registered See merge request pyshare/backend!120
2 parents 6c9b7ff + 0c982dd commit a7fab8e

File tree

12 files changed

+108
-321
lines changed

12 files changed

+108
-321
lines changed

mongo/comment.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
from .course import Course
77
from .user import User
88
from .notif import Notif
9-
from .utils import doc_required, get_redis_client
9+
from .utils import (
10+
doc_required,
11+
get_redis_client,
12+
logger,
13+
)
1014
from .submission import *
1115
from .event import (
1216
submission_completed,
@@ -52,11 +56,6 @@ def __new__(cls, pk, *args, **kwargs):
5256
cls.__initialized = True
5357
return super().__new__(cls, pk, *args, **kwargs)
5458

55-
def __init__(self, _id):
56-
if isinstance(_id, self.engine):
57-
_id = _id.id
58-
self.id = _id
59-
6059
@classmethod
6160
def on_submission_completed(cls, submission):
6261
if submission.comment is None:
@@ -131,7 +130,7 @@ def delete(self):
131130
return self
132131

133132
@doc_required('user', 'user', User)
134-
def like(self, user):
133+
def like(self, user: User):
135134
'''
136135
Like/Unlike a comment
137136
'''
@@ -155,6 +154,8 @@ def like(self, user):
155154
self.reload()
156155
user.reload()
157156
event.send(self, user=user)
157+
logger().info(
158+
f'User like/unlike comment [user={user.id}, comment={self.id}]')
158159

159160
def submit(self, code=None):
160161
'''
@@ -187,6 +188,7 @@ def on_submission_completed_ins(self):
187188
self.update(inc__success=1)
188189
# Process OJ problem
189190
if self.problem.is_OJ:
191+
# FIXME: There might exists unfinished submissions, their `result` will be `None`
190192
is_ac = lambda s: s.result.judge_result == Submission.engine.JudgeResult.AC
191193
self.update(acceptance=self.Acceptance.ACCEPTED if any(
192194
map(is_ac, self.submissions)) else self.Acceptance.REJECTED)
@@ -240,6 +242,7 @@ def add_to_problem(
240242
notif = Notif.new(info)
241243
target.author.update(push__notifs=notif.pk)
242244
comment_created.send(comment.reload())
245+
logger().info(f'Comment created [comment={comment.id}]')
243246
return comment
244247

245248
def new_submission(self, code: str):
@@ -271,27 +274,28 @@ def add_to_comment(
271274
if not target:
272275
raise engine.DoesNotExist
273276
# create new comment
274-
comment = cls.add(
277+
reply = cls.add(
275278
floor=target.floor,
276279
depth=1,
277280
problem=target.problem,
278281
**ks,
279282
)
280-
target.update(push__replies=comment.obj)
283+
target.update(push__replies=reply.obj)
281284
# notify relevant users
282285
info = Notif.types.NewReply(
283286
comment=target.pk,
284287
problem=target.problem,
285288
)
286289
authors = {target.author, target.problem.author} - {
287-
comment.author,
290+
reply.author,
288291
}
289292
if authors:
290293
notif = Notif.new(info)
291294
for author in authors:
292295
author.update(push__notifs=notif.pk)
293-
reply_created.send(comment.reload())
294-
return comment
296+
reply_created.send(reply.reload())
297+
logger().info(f'Reply created [comment={target.id}, reply={reply.id}]')
298+
return reply
295299

296300
@classmethod
297301
@doc_required('author', User)

mongo/requirement/leave_comment.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,26 @@
1818
get_redis_client,
1919
doc_required,
2020
drop_none,
21+
logger,
2122
)
2223
from .base import default_on_task_time_changed
2324

2425

2526
class LeaveComment(MongoBase, engine=engine.LeaveComment):
2627
__initialized = False
2728

28-
def __new__(cls, pk, *args, **kwargs):
29-
if not cls.__initialized:
30-
comment_created.connect(cls.on_comment_created)
31-
task_time_changed.connect(cls.on_task_time_changed)
32-
cls.__initialized = True
33-
return super().__new__(cls, pk, *args, **kwargs)
29+
def __new__(cls, *args, **kwargs):
30+
cls.register_event_listener()
31+
return super().__new__(cls, *args, **kwargs)
32+
33+
@classmethod
34+
def register_event_listener(cls):
35+
if cls.__initialized:
36+
return
37+
cls.__initialized = True
38+
comment_created.connect(cls.on_comment_created)
39+
task_time_changed.connect(cls.on_task_time_changed)
40+
logger().info(f'Event listener registered [class={cls.__name__}]')
3441

3542
# Declare again because blinker cannot accept `partial` as a reciever
3643
@classmethod
@@ -92,6 +99,7 @@ def add(
9299
params = {k: v for k, v in params.items() if v is not None}
93100
req = cls.engine(**params).save()
94101
requirement_added.send(req)
102+
logger().info(f'Requirement created [requirement={req.id}]')
95103
return cls(req)
96104

97105
def sync(
@@ -112,3 +120,6 @@ def sync(
112120
}))
113121
for comment in comments:
114122
self.add_comment(comment)
123+
124+
125+
LeaveComment.register_event_listener()

mongo/requirement/like_others_comment.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,26 @@
1616
from mongo.utils import (
1717
get_redis_client,
1818
doc_required,
19+
logger,
1920
)
2021
from .base import default_on_task_time_changed
2122

2223

2324
class LikeOthersComment(MongoBase, engine=engine.LikeOthersComment):
2425
__initialized = False
2526

26-
def __new__(cls, pk, *args, **kwargs):
27-
if not cls.__initialized:
28-
comment_liked.connect(cls.on_liked)
29-
task_time_changed.connect(cls.on_task_time_changed)
30-
cls.__initialized = True
31-
return super().__new__(cls, pk, *args, **kwargs)
27+
def __new__(cls, *args, **kwargs):
28+
cls.register_event_listener()
29+
return super().__new__(cls, *args, **kwargs)
30+
31+
@classmethod
32+
def register_event_listener(cls):
33+
if cls.__initialized:
34+
return
35+
cls.__initialized = True
36+
comment_liked.connect(cls.on_liked)
37+
task_time_changed.connect(cls.on_task_time_changed)
38+
logger().info(f'Event listener registered [class={cls.__name__}]')
3239

3340
# Declare again because blinker cannot accept `partial` as a reciever
3441
@classmethod
@@ -75,6 +82,7 @@ def add(
7582
required_number=required_number,
7683
).save()
7784
requirement_added.send(req)
85+
logger().info(f'Requirement created [requirement={req.id}]')
7886
return cls(req)
7987

8088
def sync(
@@ -93,3 +101,6 @@ def sync(
93101
# instead of when the comment was created
94102
if starts_at < comment.created < ends_at:
95103
self.add_like(comment, user)
104+
105+
106+
LikeOthersComment.register_event_listener()

mongo/requirement/reply_to_comment.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,26 @@
1717
get_redis_client,
1818
doc_required,
1919
drop_none,
20+
logger,
2021
)
2122
from .base import default_on_task_time_changed
2223

2324

2425
class ReplyToComment(MongoBase, engine=engine.ReplyToComment):
2526
__initialized = False
2627

27-
def __new__(cls, pk, *args, **kwargs):
28-
if not cls.__initialized:
29-
reply_created.connect(cls.on_reply_created)
30-
task_time_changed.connect(cls.on_task_time_changed)
31-
cls.__initialized = True
32-
return super().__new__(cls, pk, *args, **kwargs)
28+
def __new__(cls, *args, **kwargs):
29+
cls.register_event_listener()
30+
return super().__new__(cls, *args, **kwargs)
31+
32+
@classmethod
33+
def register_event_listener(cls):
34+
if cls.__initialized:
35+
return
36+
cls.__initialized = True
37+
reply_created.connect(cls.on_reply_created)
38+
task_time_changed.connect(cls.on_task_time_changed)
39+
logger().info(f'Event listener registered [class={cls.__name__}]')
3340

3441
# Declare again because blinker cannot accept `partial` as a reciever
3542
@classmethod
@@ -77,6 +84,7 @@ def add(
7784
params = {k: v for k, v in params.items() if v is not None}
7885
req = cls.engine(**params).save()
7986
requirement_added.send(req)
87+
logger().info(f'Requirement created [requirement={req.id}]')
8088
return cls(req)
8189

8290
def sync(
@@ -97,3 +105,6 @@ def sync(
97105
}))
98106
for reply in replies:
99107
self.add_reply(reply)
108+
109+
110+
ReplyToComment.register_event_listener()

mongo/requirement/solve_oj_problem.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,27 @@
1919
get_redis_client,
2020
doc_required,
2121
drop_none,
22+
logger,
2223
)
2324
from .base import default_on_task_time_changed
2425

2526

2627
class SolveOJProblem(MongoBase, engine=engine.SolveOJProblem):
2728
__initialized = False
2829

29-
def __new__(cls, pk, *args, **kwargs):
30+
def __new__(cls, *args, **kwargs):
31+
cls.register_event_listener()
32+
return super().__new__(cls, *args, **kwargs)
33+
34+
@classmethod
35+
def register_event_listener(cls):
36+
if cls.__initialized:
37+
return
38+
cls.__initialized = True
3039
# TODO: handle rejudge, which might convert a AC submission into WA
31-
if not cls.__initialized:
32-
submission_completed.connect(cls.on_submission_completed)
33-
task_time_changed.connect(cls.on_task_time_changed)
34-
cls.__initialized = True
35-
return super().__new__(cls, pk, *args, **kwargs)
40+
submission_completed.connect(cls.on_submission_completed)
41+
task_time_changed.connect(cls.on_task_time_changed)
42+
logger().info(f'Event listener registered [class={cls.__name__}]')
3643

3744
# Declare again because blinker cannot accept `partial` as a reciever
3845
@classmethod
@@ -60,6 +67,9 @@ def on_submission_completed(cls, submission):
6067
cls(req).add_submission(submission)
6168

6269
def add_submission(self, submission):
70+
logger().debug(
71+
f'New submission added to requirement [type=SolveOJProblem, id={self.id}]'
72+
)
6373
if not self.is_valid_submission(submission):
6474
return
6575
if submission.problem not in self.problems:
@@ -75,8 +85,15 @@ def add_submission(self, submission):
7585
if problem in completes:
7686
return
7787
completes.append(problem.id)
88+
logger().info(
89+
'User solved a new OJ problem '
90+
f'[user={user.id}, problem={problem.id}, requirement={self.id}]'
91+
)
7892
if len(completes) >= len(self.problems):
7993
record.completed_at = datetime.now()
94+
logger().info(
95+
f'User complete requirement [user={user.id}, requirement={self.id}]'
96+
)
8097
self.set_record(user, record)
8198

8299
@classmethod
@@ -97,6 +114,7 @@ def add(
97114
problems=[p.id for p in problems],
98115
).save()
99116
requirement_added.send(req)
117+
logger().info(f'Requirement created [requirement={req.id}]')
100118
return cls(req)
101119

102120
def sync(
@@ -118,3 +136,6 @@ def sync(
118136
}))
119137
for submission in submissions:
120138
self.add_submission(submission)
139+
140+
141+
SolveOJProblem.register_event_listener()

mongo/submission.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
from typing import List, Optional
22
import base64
3-
from blinker import signal
43
from . import engine
54
from .base import MongoBase
65
from .user import User
76
from .problem import Problem
87
from .comment import Comment
9-
from .utils import doc_required, get_redis_client
8+
from .utils import (
9+
doc_required,
10+
get_redis_client,
11+
logger,
12+
)
1013
from .token import TokenExistError
1114
from .event import submission_completed
1215

@@ -117,6 +120,7 @@ def complete(
117120
self.result.files = files
118121
self.save()
119122
submission_completed.send(self.reload())
123+
logger().info(f'Submission judge complete [submission={self.id}]')
120124
return True
121125

122126
def get_file(self, filename):

mongo/task.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
from .base import MongoBase
99
from .utils import (
1010
doc_required,
11-
get_redis_client,
1211
drop_none,
12+
logger,
1313
)
1414
from .event import (requirement_added, task_time_changed)
1515

@@ -111,3 +111,4 @@ def update(self, **ks):
111111
old_ends_at=old_ends_at,
112112
)
113113
self.reload('requirements')
114+
logger().info(f'Task interval updated [task={self.id}]')

pytest.ini

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,2 @@
11
[pytest]
2-
testpaths =
3-
tests/unittest
4-
tests/api_test/test_attachment.py
5-
tests/api_test/test_problem.py
6-
tests/api_test/test_course.py
7-
tests/api_test/test_auth.py
8-
tests/api_test/test_school.py
9-
tests/api_test/test_submission.py
10-
tests/api_test/test_user.py
11-
tests/api_test/test_tag.py
12-
tests/api_test/test_dummy.py
13-
tests/api_test/test_sandbox.py
14-
tests/api_test/test_task.py
15-
; python_files = test_problem.py
2+
testpaths = tests/

requirements.txt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
# TODO: move test dependencies to tests/requirements.txt
2-
flask==2.0.1
1+
flask~=2.1
32
gunicorn==20.1.0
43
mongoengine==0.23.1
54
PyJWT==2.1.0
65
requests==2.26.0
76
pre-commit==2.8.2
87
yapf==0.31.0
98
redis==3.5.3
9+
# TODO: move test dependencies to tests/requirements.txt
1010
fakeredis==1.6.0
11-
flask-socketio<5
12-
python-socketio<5
13-
python-engineio<4
11+
flask-socketio~=5.1
1412
eventlet==0.29.1
1513
dynaconf==3.1.5
1614
blinker==1.4

0 commit comments

Comments
 (0)