Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Markup(...).unescape() #3

Open
profgrumpy opened this issue Feb 25, 2022 · 2 comments
Open

Refactor Markup(...).unescape() #3

profgrumpy opened this issue Feb 25, 2022 · 2 comments
Assignees
Labels
Refactor Code Improvement
Milestone

Comments

@profgrumpy
Copy link
Collaborator

profgrumpy commented Feb 25, 2022

Right now, we use these Markup(...).unescape throughout the server-side code in order to prepare the content to be rendered in the jinja2 templates, using the | safe filter.
We should really instead apply these transformations to the contents as it is sent to the server (routes_pages.py or routes_mcq.py mostly I'd guess) and before it is inserted in the DB. Potential target for this would be the models maybe. This way, we would not have to constantly apply them when we're about to serve the content and just send directly what's in the DB to the jinja2 templates.

# NOTE this particular one works without doing the following pass on the data, probably bc it's using only the titles in the list
for q in all_questions:
q.title = Markup(q.title).unescape()
q.stem = Markup(q.stem).unescape()
q.answer = Markup(q.answer).unescape()

# working on getting rid of the dump_as_dict and instead using Markup(...).unescape when appropriate
# all_quizzes = [q.dump_as_dict() for q in models.Quiz.query.all()]
all_quizzes = models.Quiz.query.all()

# we replace dump_as_dict with proper Markup(...).unescape of the objects'fields themselves
#ds = [d.dump_as_dict() for d in q.distractors]
#q = q.dump_as_dict()
q.title = Markup(q.title).unescape()
q.stem = Markup(q.stem).unescape()
q.answer = Markup(q.answer).unescape()
for d in q.distractors:
d.answer = Markup(d.answer).unescape()

for d in qq.distractors:
d.answer = Markup(d.answer).unescape()
# now edit the QuizQuestion

for q in questions:
q.stem = Markup(q.stem).unescape()
q.answer = Markup(q.answer).unescape()

question.stem = Markup(question.stem).unescape()
question.answer = Markup(question.answer).unescape()
for d in question.distractors:
d.answer = Markup(d.answer).unescape()
return render_template('quiz-question-selector-2.html', quiz_id=quiz_id, question=question)

# we replace dump_as_dict with proper Markup(...).unescape of the objects'fields themselves
#q = q.dump_as_dict()
for qq in q.quiz_questions:
qq.question.title = Markup(qq.question.title).unescape()
qq.question.stem = Markup(qq.question.stem).unescape()
qq.question.answer = Markup(qq.question.answer).unescape()
# NOTE we do not have to worry about unescaping the distractors because the quiz-editor
# does not render them. However, if we had to do so, remember that we need to add to
# each QuizQuestion a field named alternatives that has the answer + distractors unescaped.

qq.question.title = Markup(qq.question.title).unescape()
qq.question.stem = Markup(qq.question.stem).unescape()
qq.question.answer = Markup(qq.question.answer).unescape()
for d in qq.distractors:
d.answer = Markup(d.answer).unescape()
# Preparing the list of alternatives for this question (these are the distractors + answer being displayed in the template)
# This comes straight from models.py dump_as_dict for QuizQuestion
tmp1 = [] # list of distractors IDs, -1 for right answer
tmp2 = [] # list of alternatives, including the right answer
tmp1.append(-1)
tmp2.append(Markup(qq.question.answer).unescape())
for d in qq.distractors:
tmp1.append(Markup(d.id).unescape()) # FIXME not necessary
tmp2.append(Markup(d.answer).unescape())
qq.alternatives = [list(tup) for tup in zip(tmp1,tmp2)]
shuffle(qq.alternatives)
# now, each QuizQuestion has an additional field "alternatives"

@profgrumpy
Copy link
Collaborator Author

profgrumpy commented Feb 25, 2022

In routes_pages.py we have several spots where we seem to actually properly Markup(...).unescape() the data from the front end before to commit it to the DB. If that's the case then why do we have to do it all over again in routes_pages.py when sending the data to the jinja2 templates??!!

# escaped_answer = json.dumps(answer) # escapes "" used in code
escaped_answer = Markup.escape(answer) # escapes HTML characters
escaped_answer = sanitize(escaped_answer)
# escaped_stem = json.dumps(stem)
escaped_stem = Markup.escape(stem)
escaped_stem = sanitize(escaped_stem)
# escaped_title = json.dumps(title)
escaped_title = Markup.escape(title)
escaped_title = sanitize(escaped_title)
q = models.Question(title=escaped_title, stem=escaped_stem, answer=escaped_answer)
models.DB.session.add(q)
models.DB.session.commit()

EvoPIE/evopie/routes_mcq.py

Lines 263 to 264 in 7bb7941

escaped_answer = Markup.escape(answer) # escapes HTML characters
escaped_answer = sanitize(escaped_answer)

@profgrumpy
Copy link
Collaborator Author

profgrumpy commented Feb 25, 2022

In models, we apparently started doing the right thing in dump_as_dict.
Problem is that we are now trying to get away from using dump_as_dict and pass instead the python objects to the jinja2 templates. So we need to get rid of dump_as_dict and, with them, these proper Markup(...).unescape() but, on the other hand, ensure that we apply these transformations before to commit the data received from the frontend to the DB.

EvoPIE/evopie/models.py

Lines 42 to 57 in 7bb7941

def dump_as_dict(self):
q = {
"id" : self.id,
"title" : Markup(self.title).unescape(),
"stem" : Markup(self.stem).unescape(),
"answer" : Markup(self.answer).unescape(),
"alternatives" : []
}
# NOTE we have to do the above unescapes so that the html code sent by summernote to the server
# is then rendered as HTML instead of being displayed as an escape string, or rendered
# with the unescaped symbols but not interpreted as HTML
q['alternatives'] = [Markup(d.answer).unescape() for d in self.distractors]
q['alternatives'].append(Markup(self.answer).unescape())
shuffle(q['alternatives'])
return q

EvoPIE/evopie/models.py

Lines 97 to 99 in 7bb7941

def dump_as_dict(self):
return {"id" : self.id, "answer": Markup(self.answer).unescape()}

EvoPIE/evopie/models.py

Lines 124 to 139 in 7bb7941

def dump_as_dict(self):
result = { "id" : self.id,
"title": self.question.title,
"stem": Markup(self.question.stem).unescape(),
"answer": Markup(self.question.answer).unescape(),
"alternatives": [] }
tmp1 = [] # list of distractors IDs, -1 for right answer
tmp2 = [] # list of alternatives, including the right answer
tmp1.append(-1)
tmp2.append(Markup(self.question.answer).unescape())
for d in self.distractors:
tmp1.append(Markup(d.id).unescape())
tmp2.append(Markup(d.answer).unescape())

@profgrumpy profgrumpy self-assigned this Feb 25, 2022
@profgrumpy profgrumpy added this to the EvoPIE mark 1 milestone Feb 25, 2022
@profgrumpy profgrumpy added the enhancement New feature or request label Feb 25, 2022
@profgrumpy profgrumpy added Refactor Code Improvement and removed enhancement New feature or request labels Mar 5, 2022
@profgrumpy profgrumpy modified the milestones: EvoPIE mark 1.1, NSDF May 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Refactor Code Improvement
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

1 participant