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
Enhancements on the freeform-answers report #17
Conversation
5d42fd8
to
fd4bd27
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @AhmedAljazzar! I tested this and it works well. I asked for a few changes - most importantly the title of the PDF should be a separate field, we should leave display_name
unchanged. The other part is supporting /static/* Studio URLs for font files.
eoc_journal/eoc_journal.py
Outdated
@@ -61,8 +63,8 @@ class EOCJournalXBlock(StudioEditableXBlockMixin, XBlock): | |||
|
|||
display_name = String( | |||
display_name=_("Title (display name)"), | |||
help=_("Title to display"), | |||
default=_("Course Journal"), | |||
help=_("Title to display. Leave blank to use the course title."), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AhmedAljazzar After looking at related client tickets again, I think that they only want the title of the PDF to default to the course name, but not the block's display_name
. I should have realized that and made it clear, sorry about that.
We will have to revert this change to the display_name
field and add a separate setting pdf_title
, which defaults to current course name but can be set to an arbitrary value by the author.
eoc_journal/eoc_journal.py
Outdated
custom_font = String( | ||
display_name=_("Default Font"), | ||
help=_("A URL links to the custom font users are going to " | ||
"generate PDFs in. (You can upload the font on Studio)"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we use Studio uploaded files in xblocks, we usually only support the "/static/" style URLs, because it's the only thing that works reliably across export/imports.
Please change the help text to:
Studio static URL to a custom font file to be used for PDF report. Example: "/static/myfont.ttf". Leave empty to use default fonts. You can upload custom TTF font files from the Content - Files & Uploads page.
You can use this method to convert "/static/..." URLs to absolute urls. It's ugly, but as far as I know there is no cleaner way and we are using this method in several of our xblocks.
eoc_journal/eoc_journal.py
Outdated
course_name = self._get_course_name() | ||
|
||
report_header_name = self.display_name or course_name | ||
title = _('{course_name} Report'.format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: can we just use report_header_name
for the title as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
eoc_journal/pdf_generator.py
Outdated
font_name_italic = tt2ps(font_name, 0, 1) | ||
font_name_bold_italic = tt2ps(font_name, 1, 1) | ||
|
||
stylesheet.add(ParagraphStyle(name='Normal', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change line breaks to comply with edx python styleguide: http://edx.readthedocs.io/projects/edx-developer-guide/en/latest/style_guides/python-guidelines.html#breaking-long-lines
reportlab.rl_config.warnOnMissingFontGlyphs = 0 | ||
pdfmetrics.registerFont(font) | ||
|
||
font_name_bold = tt2ps(font_name, 1, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I didn't know about the tt2ps
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me neither! It's saved us a lot of bad code.
eoc_journal/pdf_generator.py
Outdated
from reportlab.pdfbase.ttfonts import TTFont | ||
|
||
|
||
def _add_url_scheme(url): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'll be able to remove this method since we only want to support Studio /static/* urls (and can therefore use _expand_static_url
helper instead).
22ac6de
to
b3d712d
Compare
@mtyaka, this is ready for another pass. |
040febe
to
7245697
Compare
7245697
to
9d006b0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates @AhmedAljazzar!
The PDF report currently errors for me in the LMS if I try to use default fonts (see inline comments). I think the reason that the tests don't catch this is due to a difference in runtimes - the test runtime does not provide the replace_urls
function.
eoc_journal/eoc_journal.py
Outdated
@@ -85,6 +90,13 @@ class EOCJournalXBlock(StudioEditableXBlockMixin, XBlock): | |||
list_values_provider=provide_pb_answer_list, | |||
) | |||
|
|||
pdf_title = String( | |||
display_name=_("PDF Title"), | |||
help=_("Title to of the PDF report. Leave blank to use the course title."), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo/leftover: "Title to of..." -> "Title of..."
eoc_journal/eoc_journal.py
Outdated
pdf_buffer = BytesIO() | ||
document = SimpleDocTemplate(pdf_buffer, pagesize=pagesizes.letter, title=_("Report")) | ||
course_name = self._get_course_name() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: can we remove this line and change the line below to report_header_name = self.pdf_title or self._get_course_name()
to avoid fetching the course when pdf_title
is set.
default_title = 'Testing Ways' | ||
custom_title = 'My Custom Report Title' | ||
|
||
# The default title is 'Course Journal'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is outdated, right? The default title is the course name now.
|
||
# Patch _get_course_name method. | ||
mock_course = Mock() | ||
mock_course.return_value = 'Testing Ways' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of hardcoding the value here, can you move it up into a module variable (similar to how default_answers_data
and other mocked values are defined at the module top level).
eoc_journal/eoc_journal.py
Outdated
@@ -85,6 +90,13 @@ class EOCJournalXBlock(StudioEditableXBlockMixin, XBlock): | |||
list_values_provider=provide_pb_answer_list, | |||
) | |||
|
|||
pdf_title = String( | |||
display_name=_("PDF Title"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rename this to "PDF Report Title" for consistency with the other options related to the PDF report.
eoc_journal/eoc_journal.py
Outdated
@@ -175,11 +199,15 @@ def serve_pdf(self, request, _suffix): | |||
""" | |||
Builds and serves a PDF document containing user's freeform answers. | |||
""" | |||
styles = getSampleStyleSheet() | |||
font_path = self._expand_static_url(self.custom_font) if self.custom_font else None | |||
styles = get_style_sheet(font_url=self._make_url_absolute(font_path)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line currently fails if custom_font
is not set, since _make_ur_absolute(font_path)
returns a truthy value even if font_path
is None
.
If I try to generate a PDF report using default fonts, I get a TTFError: Not a TrueType font: version=0x0A0A0A0A
exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also have to catch this to avoid a 500 errors just in case the user entered an invalid path.
76c4267
to
7ccd6ff
Compare
7ccd6ff
to
b8762f8
Compare
Thanks you @AhmedAljazzar, this is working perfectly now 👍
|
Thanks @mtyaka for revewing! :D |
Description
This PR contains 3 different enhancements:
Horizantal line between questions:
Appears on all generated reports and there's no custom setting or flow controls it.
Default PDF header to Course Title:
Changes made on the
display_name
field where it's now left blank to determine whether to use the Course Title or another custom value.Use custom fonts in generated PDF reports:
Users now can specify a url to the desired font and we will generate the report using it. The font can be hosted anywhere on the web, or can be uploaded on Studio. If the url is uploaded on Studio, the user should fill the
custom_font
field with the Web url not theStudioone.Tests
Screenshot