Merge branch 'main' into images-django-imagekit

This commit is contained in:
Mouse Reeve 2021-06-05 11:46:57 -07:00 committed by GitHub
commit bbbae9fc9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 439 additions and 609 deletions

View file

@ -9,6 +9,7 @@ from django.contrib.postgres.fields import ArrayField as DjangoArrayField
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.db import models from django.db import models
from django.forms import ClearableFileInput, ImageField
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from bookwyrm import activitypub from bookwyrm import activitypub
@ -332,6 +333,14 @@ class TagField(ManyToManyField):
return items return items
class ClearableFileInputWithWarning(ClearableFileInput):
template_name = "widgets/clearable_file_input_with_warning.html"
class CustomImageField(ImageField):
widget = ClearableFileInputWithWarning
def image_serializer(value, alt): def image_serializer(value, alt):
"""helper for serializing images""" """helper for serializing images"""
if value and hasattr(value, "url"): if value and hasattr(value, "url"):
@ -395,6 +404,14 @@ class ImageField(ActivitypubFieldMixin, models.ImageField):
image_content = ContentFile(response.content) image_content = ContentFile(response.content)
return [image_name, image_content] return [image_name, image_content]
def formfield(self, **kwargs):
return super().formfield(
**{
"form_class": CustomImageField,
**kwargs,
}
)
class DateTimeField(ActivitypubFieldMixin, models.DateTimeField): class DateTimeField(ActivitypubFieldMixin, models.DateTimeField):
"""activitypub-aware datetime field""" """activitypub-aware datetime field"""

View file

@ -21,6 +21,7 @@ CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json" CELERY_RESULT_SERIALIZER = "json"
# email # email
EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend")
EMAIL_HOST = env("EMAIL_HOST") EMAIL_HOST = env("EMAIL_HOST")
EMAIL_PORT = env("EMAIL_PORT", 587) EMAIL_PORT = env("EMAIL_PORT", 587)
EMAIL_HOST_USER = env("EMAIL_HOST_USER") EMAIL_HOST_USER = env("EMAIL_HOST_USER")

View file

@ -3,6 +3,7 @@
let BookWyrm = new class { let BookWyrm = new class {
constructor() { constructor() {
this.MAX_FILE_SIZE_BYTES = 10 * 1000000
this.initOnDOMLoaded(); this.initOnDOMLoaded();
this.initReccuringTasks(); this.initReccuringTasks();
this.initEventListeners(); this.initEventListeners();
@ -32,15 +33,26 @@ let BookWyrm = new class {
'click', 'click',
this.back) this.back)
); );
document.querySelectorAll('input[type="file"]')
.forEach(node => node.addEventListener(
'change',
this.disableIfTooLarge.bind(this)
));
} }
/** /**
* Execute code once the DOM is loaded. * Execute code once the DOM is loaded.
*/ */
initOnDOMLoaded() { initOnDOMLoaded() {
const bookwyrm = this
window.addEventListener('DOMContentLoaded', function() { window.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.tab-group') document.querySelectorAll('.tab-group')
.forEach(tabs => new TabGroup(tabs)); .forEach(tabs => new TabGroup(tabs));
document.querySelectorAll('input[type="file"]').forEach(
bookwyrm.disableIfTooLarge.bind(bookwyrm)
)
}); });
} }
@ -284,4 +296,27 @@ let BookWyrm = new class {
node.classList.remove(classname); node.classList.remove(classname);
} }
} }
disableIfTooLarge(eventOrElement) {
const { addRemoveClass, MAX_FILE_SIZE_BYTES } = this
const element = eventOrElement.currentTarget || eventOrElement
const submits = element.form.querySelectorAll('[type="submit"]')
const warns = element.parentElement.querySelectorAll('.file-too-big')
const isTooBig = element.files &&
element.files[0] &&
element.files[0].size > MAX_FILE_SIZE_BYTES
if (isTooBig) {
submits.forEach(submitter => submitter.disabled = true)
warns.forEach(
sib => addRemoveClass(sib, 'is-hidden', false)
)
} else {
submits.forEach(submitter => submitter.disabled = false)
warns.forEach(
sib => addRemoveClass(sib, 'is-hidden', true)
)
}
}
} }

View file

@ -22,42 +22,76 @@
</div> </div>
</div> </div>
<div class="block content columns"> <div class="block columns" itemscope itemtype="https://schema.org/Person">
{% if author.aliases or author.born or author.died or author.wikipedia_link %} <meta itemprop="name" content="{{ author.name }}">
<div class="column is-narrow">
<div class="box"> {% if author.aliases or author.born or author.died or author.wikipedia_link or author.openlibrary_key or author.inventaire_id %}
<div class="column is-two-fifths">
<div class="box py-2">
<dl> <dl>
{% if author.aliases %} {% if author.aliases %}
<div class="is-flex"> <div class="is-flex is-flex-wrap-wrap my-1">
<dt class="mr-1">{% trans "Aliases:" %}</dt> <dt class="has-text-weight-bold mr-1">{% trans "Aliases:" %}</dt>
<dd itemprop="aliases">{{ author.aliases|join:', ' }}</dd> {% for alias in author.aliases %}
<dd itemprop="alternateName" content="{{alias}}">
{{alias}}{% if not forloop.last %},&nbsp;{% endif %}
</dd>
{% endfor %}
</div> </div>
{% endif %} {% endif %}
{% if author.born %} {% if author.born %}
<div class="is-flex"> <div class="is-flex my-1">
<dt class="mr-1">{% trans "Born:" %}</dt> <dt class="has-text-weight-bold mr-1">{% trans "Born:" %}</dt>
<dd itemprop="aliases">{{ author.born|naturalday }}</dd> <dd itemprop="birthDate">{{ author.born|naturalday }}</dd>
</div> </div>
{% endif %} {% endif %}
{% if author.aliases %}
<div class="is-flex"> {% if author.died %}
<dt class="mr-1">{% trans "Died:" %}</dt> <div class="is-flex my-1">
<dd itemprop="aliases">{{ author.died|naturalday }}</dd> <dt class="has-text-weight-bold mr-1">{% trans "Died:" %}</dt>
<dd itemprop="deathDate">{{ author.died|naturalday }}</dd>
</div> </div>
{% endif %} {% endif %}
</dl> </dl>
{% if author.wikipedia_link %} {% if author.wikipedia_link %}
<p><a href="{{ author.wikipedia_link }}" rel=”noopener” target="_blank">{% trans "Wikipedia" %}</a></p> <p class="my-1">
{% endif %} <a itemprop="sameAs" href="{{ author.wikipedia_link }}" rel=”noopener” target="_blank">
{% if author.openlibrary_key %} {% trans "Wikipedia" %}
<p class="mb-0"> </a>
<a href="https://openlibrary.org/authors/{{ author.openlibrary_key }}" target="_blank" rel="noopener">{% trans "View on OpenLibrary" %}</a>
</p> </p>
{% endif %} {% endif %}
{% if author.openlibrary_key %}
<p class="my-1">
<a itemprop="sameAs" href="https://openlibrary.org/authors/{{ author.openlibrary_key }}" target="_blank" rel="noopener">
{% trans "View on OpenLibrary" %}
</a>
</p>
{% endif %}
{% if author.inventaire_id %} {% if author.inventaire_id %}
<p class="mb-0"> <p class="my-1">
<a href="https://inventaire.io/entity/{{ author.inventaire_id }}" target="_blank" rel="noopener">{% trans "View on Inventaire" %}</a> <a itemprop="sameAs" href="https://inventaire.io/entity/{{ author.inventaire_id }}" target="_blank" rel="noopener">
{% trans "View on Inventaire" %}
</a>
</p>
{% endif %}
{% if author.librarything_key %}
<p class="my-1">
<a itemprop="sameAs" href="https://www.librarything.com/author/{{ author.librarything_key }}" target="_blank" rel="noopener">
{% trans "View on LibraryThing" %}
</a>
</p>
{% endif %}
{% if author.goodreads_key %}
<p class="my-1">
<a itemprop="sameAs" href="https://www.goodreads.com/author/show/{{ author.goodreads_key }}" target="_blank" rel="noopener">
{% trans "View on Goodreads" %}
</a>
</p> </p>
{% endif %} {% endif %}
</div> </div>

View file

@ -1,7 +1,7 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% load i18n %}{% load bookwyrm_tags %}{% load humanize %}{% load utilities %} {% load i18n %}{% load bookwyrm_tags %}{% load humanize %}{% load utilities %}
{% block title %}{{ book|title }}{% endblock %} {% block title %}{{ book|book_title }}{% endblock %}
{% block content %} {% block content %}
{% with user_authenticated=request.user.is_authenticated can_edit_book=perms.bookwyrm.edit_book %} {% with user_authenticated=request.user.is_authenticated can_edit_book=perms.bookwyrm.edit_book %}

View file

@ -0,0 +1,3 @@
{% load i18n %}
{% include "django/forms/widgets/clearable_file_input.html" %}
<span class="help file-cta is-hidden file-too-big">{% trans "File exceeds maximum size: 10MB" %}</span>

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,5 @@
include /etc/nginx/conf.d/server_config;
upstream web { upstream web {
server web:8000; server web:8000;
} }

View file

@ -1,3 +1,5 @@
include /etc/nginx/conf.d/server_config;
upstream web { upstream web {
server web:8000; server web:8000;
} }

1
nginx/server_config Normal file
View file

@ -0,0 +1 @@
client_max_body_size 10m;

View file

@ -1,5 +1,5 @@
celery==4.4.2 celery==4.4.2
Django==3.2.0 Django==3.2.1
django-imagekit==4.0.2 django-imagekit==4.0.2
django-model-utils==4.0.0 django-model-utils==4.0.0
environs==7.2.0 environs==7.2.0