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

Enhance Thumbnail Functionality #304

Conversation

studybuffalo
Copy link

This is a pull request to address the dependency issues caused by conflicting versions of django-newsletter, sorl-thumbnail, and Django. It removes the hard dependency on sorl-thumbnail and provides alternative fallbacks if sorl-thumbnail is not used. With this work it was easy enough to extend functionality to include other thumbnail applications. Thus, I have also included easy-thumbnails support to give users another option and serve as a template for any future support for other thumbnail applications.

Major Changes

  • Removed sorl-thumbnail as a dependency.
  • Added a new setting (NEWSLETTER_THUMBNAIL) that allows user to specify a third party thumbnail application for use with django-newsletter.
  • Added support for two thumbnail applications to start: sorl-thumbnail and easy-thumbnails
  • Created a template tag that performs rudimentary thumbnailing with Pillow. This acts as a fallback if the user hasn't specified a third party thumbnail application. This has been tested to support common image file formats: JPG, PNG, GIF, BMP, TIFF.
  • Reworked the image field in the Article model to support swapping between thumbnail applications by creating a model field that will inherit from the appropriate application. This avoids issues where Django will try to make a new migration anytime the user swaps the app. By default, this field will fallback to the Django ImageField if there is no thumbnail app specified.
  • Added logic to the SubmissionArchiveDetailView to select an appropriate template to thumbnail any Article images. Users can override the newsletter/message/thumbnail/django_newletter.html or newsletter/message/message.html template if they need to implement a different template.
  • Added logic to the admin ArticleInline class to make use of the appropriate thumbnail application widget as specified by the user (or the normal Django widet if not specified).
  • Added unit tests for all new functionality
  • Updated relevant documentation sections to outline the new functionality and modifications to the install steps.
  • Removed testing steps from travis.yml that stops installing directly from requirements.txt. This forces the tests to install as though it were a proper PyPI package and catch any odd requirement issues.

Other Comments

  • the upgrading.rst file has not been updated yet, as I am not sure which version this would fall under and if there are major changes to still take place.

Questions before review

  • I am not sure if we want to go ahead with the basic thumbnail functionality via Pillow as a fallback or not. I added it since the work was already done and it was minimal effort at this point. That said, I understand if we don't want this application to dive into something that could become quite complex. I think this works for the common uses, but we can't guarantee that for anything unusual. If we opt not to use it, I think the fallback becomes to just display the image as is and resize it via HTML attributes (i.e. no actual performance benefits, just making sure it visually looks the same as the other thumbnail applications).
  • I opted to create a more rigid implementation of specifying the thumbnail application. We could go with a situation where the user can specify things down to the specific model field they want to use, the admin mixin, the templates, etc. I felt that it wasn't functionality most users were going to use and we should encourage developers to add their thumbnail application of choice as an option within django-newsletter.

Relevant Issues: #302, #303

@coveralls
Copy link

coveralls commented Jan 17, 2020

Coverage Status

Coverage increased (+0.4%) to 88.81% when pulling 620ac61 on studybuffalo:enhance-thumbnail-functionality into 2147d3d on dokterbob:master.

Copy link
Collaborator

@dokterbob dokterbob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super thanks for a great contribg!

My suggestion would be to default to sorl for a while, as it is not 'broken' anymore, and this is what all users are using right now. However, we should yield a deprecation error when no thumbnailing is explicitly configured - and we might add a no-op thumbnailer for users which don't want to use any kind of thumbnailer.

Once more, GREAT WORK! It's a pleasure to review such a great piece of code. Sorry it took a while to get to it!

.travis.yml Outdated
@@ -39,8 +39,6 @@ install:
# Latest PIP uses wheel by default
- pip install --upgrade pip
- pip install $DJANGO
- pip install -r requirements.txt
- pip install -r requirements_test.txt
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this was because I was noticing some odd behaviour in testing. I unfortunately cannot recall exactly what was happening, but I believe I was getting tests that passed locally with the setup.py test command, but then failing in Travis-CI. Removing these lines resolved the issue and all other tests continue to pass. My Travis-CI history unfortunately has since removed the offending tests from the history.

If I were to make an educated guess, I think we were getting weird version conflicts because we install these packages into the environment and then install things again with the setup.py test command.

If we need a definitive answer I can add the lines back and see what happens in testing!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer you take this file straight from master, where CI seems working just fine. :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated with requested changes.

models.TextField: {'widget': newsletter_settings.RICHTEXT_WIDGET},
}

# https://easy-thumbnails.readthedocs.io/en/latest/usage/#forms
if newsletter_settings.THUMBNAIL == 'easy-thumbnails':
_formfield_overrides = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to override the _formfield_overrides when a RichtextWidget is set.

It's also not clear to me why a separate _formield_overrides is used instead of directly setting/updating formfield_overrides.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct. Ultimately this is largely a personal stylistic choice so that we only have one spot where we set the attribute value, but we could achieve the same effect with if/elif/else statements and set the value directly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer setting them directly as I feel non-functional code does not contribute to clarity.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated with requested changes.

source_image = parser.compile_filter(tag_args[1])

# Return the thumbnail
return ThumbnailNode(source_image, tag_args[-1])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think providing (and thus maintaining!) thumbnail code is really out of scope from django-newsletter!

My suggestion would be:

  1. For now, to default to sorl-thumbnail for backwards-compatibility but to yield a DeprecationError if no thumbnail facility is explicitly configured.
  2. In the next major version, failing hard if none is defined. We might make sure there's a no-op thumbnail facility by default.

I am open to your suggestions on this one though!

Super happy with this great contrib!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that plan and I think it makes perfect sense. I have no doubts there are countless pitfalls with proper thumbnail generation we aren't accounting for here and it could create some concerning feature creep.

I'll look at making the suggested updates and remove this block (and updating the other impacted code sections).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set this up to raise a DeprecationWarning if no NEWSLETTER_THUMBNAIL is declared and then default to sorl-thumbnail. I have set the warning to say this will become a mandatory declaration for version 0.11.0 (I assume the warning itself will kick in for version 0.10.0). I updated some details in the installation and setting docs to cover this change as well.

@studybuffalo
Copy link
Author

Thanks for taking the time to review and provide the feedback @dokterbob - really appreciate it!

I will try and find some time to make the changes around the thumbnailer functionality in the near future and get another version out.

@studybuffalo
Copy link
Author

Okay, had some time and pulled out the thumbnail functionality. I left comments to some of your other questions and can make any additional changes as needed quite quickly. Thanks!

@dokterbob dokterbob self-requested a review June 8, 2020 10:45
.travis.yml Outdated
@@ -39,8 +39,6 @@ install:
# Latest PIP uses wheel by default
- pip install --upgrade pip
- pip install $DJANGO
- pip install -r requirements.txt
- pip install -r requirements_test.txt
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer you take this file straight from master, where CI seems working just fine. :)

models.TextField: {'widget': newsletter_settings.RICHTEXT_WIDGET},
}

# https://easy-thumbnails.readthedocs.io/en/latest/usage/#forms
if newsletter_settings.THUMBNAIL == 'easy-thumbnails':
_formfield_overrides = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer setting them directly as I feel non-functional code does not contribute to clarity.

dokterbob pushed a commit that referenced this pull request Oct 24, 2020
…ependency. (#304)

* Removed sorl-thumbnail as a dependency.
* Added a new setting (NEWSLETTER_THUMBNAIL) which allows users to specify a third party thumbnail application.
* Integrated support for two thumbnail applications: sorl-thumbnail and easy-thumbnails
* Removing some Python 2.7 conditional imports
dokterbob pushed a commit that referenced this pull request Oct 24, 2020
…ependency. (#304)

* Removed sorl-thumbnail as a dependency.
* Added a new setting (NEWSLETTER_THUMBNAIL) which allows users to specify a third party thumbnail application.
* Integrated support for two thumbnail applications: sorl-thumbnail and easy-thumbnails
* Removing conditional Python 2.7 and pytz (already required by Django) imports in tetst
@dokterbob
Copy link
Collaborator

Merged, at last! :D

Thanks, @studybuffalo!

Ref: 2ce29ba

@dokterbob dokterbob closed this Oct 24, 2020
@frennkie
Copy link
Collaborator

@dokterbob the migration that was merged with 2ce29ba is called 0006_switch_from_sorl_imagefield.py. The "attachment" migration already has the prefix 0006. I'm sure that is is no technical problem at all. But it might be a bit confusing to developers/users.

What do you think? Is it necessary to rename this one to 0007_switch_from_sorl_imagefield.py or should we just leave it?

@dokterbob
Copy link
Collaborator

Oh, that's a silly human bug right there. We might quickly renumber them, before anyone uses it (or else they'll have to manually rewind and re-apply). What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants