Skip to content

Commit 791fd06

Browse files
committed
fix merge conflicts
2 parents b1de37a + 6f13160 commit 791fd06

File tree

10 files changed

+82
-62
lines changed

10 files changed

+82
-62
lines changed

lms/lmsdb/bootstrap.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,8 @@ def _add_exercise_course_id_and_number_columns_constraint() -> bool:
284284
migrate(
285285
migrator.add_index('exercise', ('course_id', 'number'), True),
286286
)
287-
except OperationalError as e:
288-
if 'already exists' in str(e):
289-
log.info(f'index exercise already exists: {e}')
290-
else:
291-
raise
287+
except (OperationalError, ProgrammingError) as e:
288+
log.info(f'Index exercise course and number already exists: {e}')
292289
db_config.database.commit()
293290

294291

@@ -301,11 +298,8 @@ def _add_user_course_constaint() -> bool:
301298
'usercourse', ('user_id', 'course_id'), True,
302299
),
303300
)
304-
except OperationalError as e:
305-
if 'already exists' in str(e):
306-
log.info(f'index usercourse already exists: {e}')
307-
else:
308-
raise
301+
except (OperationalError, ProgrammingError) as e:
302+
log.info(f'Index usercourse user and course already exists: {e}')
309303
db_config.database.commit()
310304

311305

lms/lmsdb/models.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -620,16 +620,11 @@ def view_solution(self) -> None:
620620
def start_checking(self) -> bool:
621621
return self.set_state(Solution.STATES.IN_CHECKING)
622622

623-
def set_state(
624-
self, new_state: SolutionState,
625-
assessment: Optional[SolutionAssessment] = None, **kwargs,
626-
) -> bool:
623+
def set_state(self, new_state: SolutionState, **kwargs) -> bool:
627624
# Optional: filter the old state of the object
628625
# to make sure that no two processes set the state together
629626
requested_solution = (Solution.id == self.id)
630627
updates_dict = {Solution.state.name: new_state.name}
631-
if assessment is not None:
632-
updates_dict[Solution.assessment.name] = assessment
633628
changes = Solution.update(
634629
**updates_dict, **kwargs,
635630
).where(requested_solution)
@@ -772,19 +767,20 @@ def _base_next_unchecked(cls):
772767
cls.submission_timestamp.asc(),
773768
)
774769

770+
def change_assessment(self, assessment_id: Optional[int] = None) -> bool:
771+
assessment = SolutionAssessment.get_or_none(
772+
SolutionAssessment.id == assessment_id,
773+
)
774+
requested_solution = (Solution.id == self.id)
775+
updates_dict = {Solution.assessment.name: assessment}
776+
changes = Solution.update(**updates_dict).where(requested_solution)
777+
return changes.execute() == 1
778+
775779
def mark_as_checked(
776780
self,
777-
assessment_id: Optional[int] = None,
778781
by: Optional[Union[User, int]] = None,
779782
) -> bool:
780-
assessment = SolutionAssessment.get_or_none(
781-
SolutionAssessment.id == assessment_id,
782-
)
783-
return self.set_state(
784-
Solution.STATES.DONE,
785-
assessment=assessment,
786-
checker=by,
787-
)
783+
return self.set_state(Solution.STATES.DONE, checker=by)
788784

789785
@classmethod
790786
def next_unchecked(cls) -> Optional['Solution']:

lms/lmsweb/translations/he/LC_MESSAGES/messages.po

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ msgid ""
77
msgstr ""
88
"Project-Id-Version: 1.0\n"
99
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10-
"POT-Creation-Date: 2021-10-15 12:16+0300\n"
10+
"POT-Creation-Date: 2021-10-15 14:37+0300\n"
1111
"PO-Revision-Date: 2021-09-29 11:30+0300\n"
1212
"Last-Translator: Or Ronai\n"
1313
"Language: he\n"
@@ -120,7 +120,7 @@ msgstr "%(solver)s הגיב לך על בדיקת תרגיל \"%(subject)s\"."
120120
msgid "%(checker)s replied for \"%(subject)s\"."
121121
msgstr "%(checker)s הגיב לך על תרגיל \"%(subject)s\"."
122122

123-
#: models/solutions.py:75
123+
#: models/solutions.py:78
124124
#, python-format
125125
msgid "Your solution for the \"%(subject)s\" exercise has been checked."
126126
msgstr "הפתרון שלך לתרגיל \"%(subject)s\" נבדק."
@@ -266,7 +266,6 @@ msgid "Logout"
266266
msgstr "התנתקות"
267267

268268
#: templates/public-courses.html:6
269-
#, fuzzy
270269
msgid "Public Courses List"
271270
msgstr "רשימת קורסים פתוחים"
272271

lms/lmsweb/views.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -717,17 +717,20 @@ def shared_solution(shared_url: str, file_id: Optional[int] = None):
717717
)
718718

719719

720+
@webapp.route('/assessment/<int:solution_id>', methods=['POST'])
721+
@login_required
722+
@managers_only
723+
def assessment(solution_id: int):
724+
assessment_id = request.json.get('assessment')
725+
updated = solutions.change_assessment(solution_id, assessment_id)
726+
return jsonify({'success': updated})
727+
728+
720729
@webapp.route('/checked/<int:exercise_id>/<int:solution_id>', methods=['POST'])
721730
@login_required
722731
@managers_only
723-
def done_checking(exercise_id, solution_id):
724-
if request.method == 'POST':
725-
assessment_id = request.json.get('assessment')
726-
else: # it's a GET
727-
assessment_id = request.args.get('assessment')
728-
is_updated = solutions.mark_as_checked(
729-
solution_id, current_user.id, assessment_id,
730-
)
732+
def done_checking(exercise_id: int, solution_id: int):
733+
is_updated = solutions.mark_as_checked(solution_id, current_user.id)
731734
next_solution = solutions.get_next_unchecked(exercise_id)
732735
next_solution_id = getattr(next_solution, 'id', None)
733736
return jsonify({'success': is_updated, 'next': next_solution_id})

lms/models/solutions.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,16 @@ def get_message_and_addressee(
6565
return msg, addressee
6666

6767

68-
def mark_as_checked(
69-
solution_id: int, checker_id: int, assessment_id: Optional[int] = None,
68+
def change_assessment(
69+
solution_id: int, assessment_id: Optional[int] = None,
7070
) -> bool:
7171
checked_solution: Solution = Solution.get_by_id(solution_id)
72-
is_updated = checked_solution.mark_as_checked(
73-
assessment_id=assessment_id, by=checker_id,
74-
)
72+
return checked_solution.change_assessment(assessment_id=assessment_id)
73+
74+
75+
def mark_as_checked(solution_id: int, checker_id: int) -> bool:
76+
checked_solution: Solution = Solution.get_by_id(solution_id)
77+
is_updated = checked_solution.mark_as_checked(by=checker_id)
7578
msg = _(
7679
'Your solution for the "%(subject)s" exercise has been checked.',
7780
subject=checked_solution.exercise.subject,

lms/static/checker.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
function trackFinished(exerciseId, solutionId, element) {
22
element.addEventListener('click', () => {
3-
const assessment = document.querySelector('input[name="assessment"]:checked');
4-
const assessmentValue = (assessment !== null) ? assessment.value : null;
53
const xhr = new XMLHttpRequest();
64
xhr.open('POST', `/checked/${exerciseId}/${solutionId}`, true);
75
xhr.setRequestHeader('Content-Type', 'application/json');
@@ -20,20 +18,33 @@ function trackFinished(exerciseId, solutionId, element) {
2018
}
2119
};
2220

23-
xhr.send(JSON.stringify({
24-
assessment: assessmentValue,
25-
}));
21+
xhr.send(JSON.stringify({}));
2622
});
2723
}
2824

2925
function changeAssessmentsAttributes(assessmentGroup, item) {
3026
if (item.value == assessmentGroup.dataset.checkedid) {
3127
item.removeAttribute('checked');
3228
item.checked = false;
33-
assessmentGroup.dataset.checkedid = 'None';
29+
assessmentGroup.dataset.checkedid = null;
3430
} else {
3531
assessmentGroup.dataset.checkedid = item.value;
3632
}
33+
document.activeElement.blur();
34+
35+
const xhr = new XMLHttpRequest();
36+
xhr.open('POST', `/assessment/${solutionId}`, true);
37+
xhr.setRequestHeader('Content-Type', 'application/json');
38+
xhr.responseType = 'json';
39+
xhr.onreadystatechange = () => {
40+
if (xhr.readyState === 4) {
41+
if (xhr.status !== 200) {
42+
console.log(xhr.status);
43+
}
44+
}
45+
};
46+
47+
xhr.send(JSON.stringify({assessment: assessmentGroup.dataset.checkedid}));
3748
}
3849

3950
function trackAssessmentButtons() {

lms/static/my.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ code .grader-add .fa {
801801
}
802802

803803
#courses-list {
804-
overflow-y: scroll;
804+
overflow-y: auto;
805805
max-height: 10em;
806806
}
807807

lms/templates/view.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{% block page_content %}
44
<div id="page-view">
55
<div id="view-head">
6-
<h1>{{ _('Exercise view') }} {{ solution['exercise']['id'] }}: {{ solution['exercise']['subject'] }}</h1>
6+
<h1>{{ _('Exercise view') }} {{ solution['exercise']['number'] }}: {{ solution['exercise']['subject'] }}</h1>
77
{% if not is_manager and not shared_url %}
88
{% if solution['state'] == 'DONE' %}
99
<p class="checked-msg {{ direction }}"><strong>{{ _('Your solution had checked!') }}</strong> {{ _('Click on the red lines in order to see the comments.') }}</p>

tests/test_notifications.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def test_user_commented_after_check(
175175
client = conftest.get_logged_user(student_user.username)
176176

177177
# Marking the solution as checked
178-
solutions.mark_as_checked(solution.id, staff_user.id, 1)
178+
solutions.mark_as_checked(solution.id, staff_user.id)
179179
solution = Solution.get_by_id(solution.id)
180180

181181
# Sending comments after solution checked

tests/test_solutions.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def test_mark_as_checked(
132132
):
133133
# Basic functionality
134134
assert solution.state == Solution.STATES.CREATED.name
135-
marked = solutions.mark_as_checked(solution.id, staff_user.id, 2)
135+
marked = solutions.mark_as_checked(solution.id, staff_user.id)
136136
# HELL WITH PEEWEE!!!
137137
solution = Solution.get_by_id(solution.id)
138138
assert marked
@@ -142,7 +142,7 @@ def test_mark_as_checked(
142142
# Not duplicating things
143143
staff_user2 = conftest.create_staff_user(index=1)
144144
solution2 = conftest.create_solution(exercise, student_user)
145-
marked = solutions.mark_as_checked(solution2.id, staff_user2.id, 3)
145+
marked = solutions.mark_as_checked(solution2.id, staff_user2.id)
146146
solution2 = Solution.get_by_id(solution2.id)
147147
assert solution2.state == Solution.STATES.DONE.name
148148
assert solution2.checker == staff_user2
@@ -171,21 +171,21 @@ def test_get_next_unchecked(
171171
assert unchecked.exercise.id == solution1.exercise.id
172172
assert unchecked == solution1
173173

174-
solutions.mark_as_checked(solution1.id, staff_user, 4)
174+
solutions.mark_as_checked(solution1.id, staff_user)
175175
unchecked = solutions.get_next_unchecked(exercise.id)
176176
assert unchecked is not None
177177
assert unchecked.exercise.id == solution3.exercise.id
178178
assert unchecked == solution3
179179

180-
solutions.mark_as_checked(solution3.id, staff_user, 1)
180+
solutions.mark_as_checked(solution3.id, staff_user)
181181
unchecked = solutions.get_next_unchecked(exercise.id)
182182
assert unchecked is None
183183

184184
unchecked = solutions.get_next_unchecked()
185185
assert unchecked is not None
186186
assert unchecked == solution2
187187

188-
solutions.mark_as_checked(solution2.id, staff_user, 2)
188+
solutions.mark_as_checked(solution2.id, staff_user)
189189
unchecked = solutions.get_next_unchecked()
190190
assert unchecked is None
191191

@@ -563,7 +563,7 @@ def test_last_view_status(
563563
solution = Solution.get_by_id(solution.id)
564564
assert solution.last_status_view == SolutionStatusView.NOT_CHECKED.name
565565

566-
solutions.mark_as_checked(solution.id, staff_user.id, 3)
566+
solutions.mark_as_checked(solution.id, staff_user.id)
567567
solution = Solution.get_by_id(solution.id)
568568
assert solution.last_status_view == SolutionStatusView.NOT_CHECKED.name
569569
client.get(f'/view/{solution.id}')
@@ -590,8 +590,6 @@ def test_done_checking(
590590
client = conftest.get_logged_user(staff_user.username)
591591
response = client.post(
592592
f'/checked/{solution.exercise.id}/{solution.id}',
593-
data=json.dumps({'assessment': 1}),
594-
content_type='application/json',
595593
)
596594
assert response.status_code == 200
597595

@@ -636,14 +634,30 @@ def test_solutions_of_user(
636634
solution: Solution, _assessments,
637635
):
638636
conftest.create_usercourse(student_user, course)
639-
solutions.mark_as_checked(solution.id, staff_user.id, 2)
637+
client = conftest.get_logged_user(staff_user.username)
638+
client.post(
639+
f'/assessment/{solution.id}',
640+
data=json.dumps({'assessment': 2}),
641+
content_type='application/json',
642+
)
640643
solution = Solution.get_by_id(solution.id)
644+
assert solution.assessment.name == 'Nice'
645+
646+
client.post(
647+
f'/assessment/{solution.id}',
648+
data=json.dumps({'assessment': None}),
649+
content_type='application/json',
650+
)
641651

642652
exercise2 = conftest.create_exercise(course, 2)
643653
solution2 = conftest.create_solution(exercise2, student_user)
644-
solutions.mark_as_checked(solution2.id, staff_user.id)
654+
client.post(
655+
f'/assessment/{solution2.id}',
656+
data=json.dumps({'assessment': 3}),
657+
content_type='application/json',
658+
)
645659
solution2 = Solution.get_by_id(solution2.id)
646660

647661
exercises = solution.of_user(student_user.id, from_all_courses=True)
648-
assert exercises[0].get('assessment') == 'Nice'
649-
assert exercises[1].get('assessment') is None
662+
assert exercises[0].get('assessment') is None
663+
assert exercises[1].get('assessment') == 'Try again'

0 commit comments

Comments
 (0)