Merge branch 'main' into production

This commit is contained in:
Mouse Reeve 2021-06-05 12:53:03 -07:00
commit c3f938d500
30 changed files with 765 additions and 820 deletions

View file

@ -34,10 +34,8 @@ REDIS_ACTIVITY_PORT=6379
#REDIS_ACTIVITY_PASSWORD=redispassword345 #REDIS_ACTIVITY_PASSWORD=redispassword345
# Redis as celery broker # Redis as celery broker
#REDIS_BROKER_PORT=6379 REDIS_BROKER_PORT=6379
#REDIS_BROKER_PASSWORD=redispassword123 #REDIS_BROKER_PASSWORD=redispassword123
CELERY_BROKER=redis://redis_broker:6379/0
CELERY_RESULT_BACKEND=redis://redis_broker:6379/0
FLOWER_PORT=8888 FLOWER_PORT=8888
#FLOWER_USER=mouse #FLOWER_USER=mouse

View file

@ -36,8 +36,6 @@ REDIS_ACTIVITY_PASSWORD=redispassword345
# Redis as celery broker # Redis as celery broker
REDIS_BROKER_PORT=6379 REDIS_BROKER_PORT=6379
REDIS_BROKER_PASSWORD=redispassword123 REDIS_BROKER_PASSWORD=redispassword123
CELERY_BROKER=redis://:${REDIS_BROKER_PASSWORD}@redis_broker:${REDIS_BROKER_PORT}/0
CELERY_RESULT_BACKEND=redis://:${REDIS_BROKER_PASSWORD}@redis_broker:${REDIS_BROKER_PORT}/0
FLOWER_PORT=8888 FLOWER_PORT=8888
FLOWER_USER=mouse FLOWER_USER=mouse

View file

@ -58,7 +58,8 @@ jobs:
POSTGRES_DB: github_actions POSTGRES_DB: github_actions
POSTGRES_HOST: 127.0.0.1 POSTGRES_HOST: 127.0.0.1
CELERY_BROKER: "" CELERY_BROKER: ""
CELERY_RESULT_BACKEND: "" REDIS_BROKER_PORT: 6379
FLOWER_PORT: 8888
EMAIL_HOST: "smtp.mailgun.org" EMAIL_HOST: "smtp.mailgun.org"
EMAIL_PORT: 587 EMAIL_PORT: 587
EMAIL_HOST_USER: "" EMAIL_HOST_USER: ""

View file

@ -8,5 +8,3 @@ WORKDIR /app
COPY requirements.txt /app/ COPY requirements.txt /app/
RUN pip install -r requirements.txt --no-cache-dir RUN pip install -r requirements.txt --no-cache-dir
COPY ./bookwyrm ./celerywyrm /app/

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

@ -14,13 +14,18 @@ PAGE_LENGTH = env("PAGE_LENGTH", 15)
DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English") DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English")
# celery # celery
CELERY_BROKER = env("CELERY_BROKER") CELERY_BROKER = "redis://:{}@redis_broker:{}/0".format(
CELERY_RESULT_BACKEND = env("CELERY_RESULT_BACKEND") requests.utils.quote(env("REDIS_BROKER_PASSWORD", "")), env("REDIS_BROKER_PORT")
)
CELERY_RESULT_BACKEND = "redis://:{}@redis_broker:{}/0".format(
requests.utils.quote(env("REDIS_BROKER_PASSWORD", "")), env("REDIS_BROKER_PORT")
)
CELERY_ACCEPT_CONTENT = ["application/json"] CELERY_ACCEPT_CONTENT = ["application/json"]
CELERY_TASK_SERIALIZER = "json" 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.died %} {% if author.died %}
<div class="is-flex"> <div class="is-flex my-1">
<dt class="mr-1">{% trans "Died:" %}</dt> <dt class="has-text-weight-bold mr-1">{% trans "Died:" %}</dt>
<dd itemprop="aliases">{{ author.died|naturalday }}</dd> <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

@ -29,67 +29,85 @@
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<h2 class="title is-4">{% trans "Metadata" %}</h2> <h2 class="title is-4">{% trans "Metadata" %}</h2>
<p class="mb-2"><label class="label" for="id_name">{% trans "Name:" %}</label> {{ form.name }}</p> <div class="field">
{% for error in form.name.errors %} <label class="label" for="id_name">{% trans "Name:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.name }}
{% endfor %} {% for error in form.name.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"> <div class="field">
<label class="label" for="id_aliases">{% trans "Aliases:" %}</label> <label class="label" for="id_aliases">{% trans "Aliases:" %}</label>
{{ form.aliases }} {{ form.aliases }}
<span class="help">{% trans "Separate multiple values with commas." %}</span> <span class="help">{% trans "Separate multiple values with commas." %}</span>
</p> {% for error in form.aliases.errors %}
{% for error in form.aliases.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"><label class="label" for="id_bio">{% trans "Bio:" %}</label> {{ form.bio }}</p> <div class="field">
{% for error in form.bio.errors %} <label class="label" for="id_bio">{% trans "Bio:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.bio }}
{% endfor %} {% for error in form.bio.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"><label class="label" for="id_wikipedia_link">{% trans "Wikipedia link:" %}</label> {{ form.wikipedia_link }}</p> <p class="field"><label class="label" for="id_wikipedia_link">{% trans "Wikipedia link:" %}</label> {{ form.wikipedia_link }}</p>
{% for error in form.wikipedia_link.errors %} {% for error in form.wikipedia_link.errors %}
<p class="help is-danger">{{ error | escape }}</p> <p class="help is-danger">{{ error | escape }}</p>
{% endfor %} {% endfor %}
<p class="mb-2"> <div class="field">
<label class="label" for="id_born">{% trans "Birth date:" %}</label> <label class="label" for="id_born">{% trans "Birth date:" %}</label>
<input type="date" name="born" value="{{ form.born.value|date:'Y-m-d' }}" class="input" id="id_born"> <input type="date" name="born" value="{{ form.born.value|date:'Y-m-d' }}" class="input" id="id_born">
</p> {% for error in form.born.errors %}
{% for error in form.born.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"> <div class="field">
<label class="label" for="id_died">{% trans "Death date:" %}</label> <label class="label" for="id_died">{% trans "Death date:" %}</label>
<input type="date" name="died" value="{{ form.died.value|date:'Y-m-d' }}" class="input" id="id_died"> <input type="date" name="died" value="{{ form.died.value|date:'Y-m-d' }}" class="input" id="id_died">
</p> {% for error in form.died.errors %}
{% for error in form.died.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
</div> </div>
<div class="column"> <div class="column">
<h2 class="title is-4">{% trans "Author Identifiers" %}</h2> <h2 class="title is-4">{% trans "Author Identifiers" %}</h2>
<p class="mb-2"><label class="label" for="id_openlibrary_key">{% trans "Openlibrary key:" %}</label> {{ form.openlibrary_key }}</p> <div class="field">
{% for error in form.openlibrary_key.errors %} <label class="label" for="id_openlibrary_key">{% trans "Openlibrary key:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.openlibrary_key }}
{% endfor %} {% for error in form.openlibrary_key.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"><label class="label" for="id_inventaire_id">{% trans "Inventaire ID:" %}</label> {{ form.inventaire_id }}</p> <div class="field">
{% for error in form.inventaire_id.errors %} <label class="label" for="id_inventaire_id">{% trans "Inventaire ID:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.inventaire_id }}
{% endfor %} {% for error in form.inventaire_id.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"><label class="label" for="id_librarything_key">{% trans "Librarything key:" %}</label> {{ form.librarything_key }}</p> <div class="field">
{% for error in form.librarything_key.errors %} <label class="label" for="id_librarything_key">{% trans "Librarything key:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.librarything_key }}
{% endfor %} {% for error in form.librarything_key.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"><label class="label" for="id_goodreads_key">{% trans "Goodreads key:" %}</label> {{ form.goodreads_key }}</p> <div class="field">
{% for error in form.goodreads_key.errors %} <label class="label" for="id_goodreads_key">{% trans "Goodreads key:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.goodreads_key }}
{% endfor %} {% for error in form.goodreads_key.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
</div> </div>
</div> </div>

View file

@ -14,11 +14,25 @@
{% endif %} {% endif %}
</h1> </h1>
{% if book %} {% if book %}
<div> <dl>
<p>{% trans "Added:" %} {{ book.created_date | naturaltime }}</p> <div class="is-flex">
<p>{% trans "Updated:" %} {{ book.updated_date | naturaltime }}</p> <dt class="has-text-weight-semibold">{% trans "Added:" %}</dt>
<p>{% trans "Last edited by:" %} <a href="{{ book.last_edited_by.remote_id }}">{{ book.last_edited_by.display_name }}</a></p> <dd class="ml-2">{{ book.created_date | naturaltime }}</dd>
</div> </div>
<div class="is-flex">
<dt class="has-text-weight-semibold">{% trans "Updated:" %}</dt>
<dd class="ml-2">{{ book.updated_date | naturaltime }}</dd>
</div>
{% if book.last_edited_by %}
<div class="is-flex">
<dt class="has-text-weight-semibold">{% trans "Last edited by:" %}</dt>
<dd class="ml-2"><a href="{{ book.last_edited_by.remote_id }}">{{ book.last_edited_by.display_name }}</a></dd>
</div>
{% endif %}
</dl>
{% endif %} {% endif %}
</header> </header>
@ -38,21 +52,28 @@
{% if confirm_mode %} {% if confirm_mode %}
<div class="box"> <div class="box">
<h2 class="title is-4">{% trans "Confirm Book Info" %}</h2> <h2 class="title is-4">{% trans "Confirm Book Info" %}</h2>
<div class="columns"> <div class="columns mb-4">
{% if author_matches %} {% if author_matches %}
<input type="hidden" name="author-match-count" value="{{ author_matches|length }}"> <input type="hidden" name="author-match-count" value="{{ author_matches|length }}">
<div class="column is-half"> <div class="column is-half">
{% for author in author_matches %} {% for author in author_matches %}
<fieldset class="mb-4"> <fieldset>
<legend class="title is-5 mb-1">{% blocktrans with name=author.name %}Is "{{ name }}" an existing author?{% endblocktrans %}</legend> <legend class="title is-5 mb-1">
{% blocktrans with name=author.name %}Is "{{ name }}" an existing author?{% endblocktrans %}
</legend>
{% with forloop.counter0 as counter %} {% with forloop.counter0 as counter %}
{% for match in author.matches %} {% for match in author.matches %}
<label><input type="radio" name="author_match-{{ counter }}" value="{{ match.id }}" required> {{ match.name }}</label> <label class="label mb-2">
<input type="radio" name="author_match-{{ counter }}" value="{{ match.id }}" required>
{{ match.name }}
</label>
<p class="help"> <p class="help">
<a href="{{ match.local_path }}" target="_blank">{% blocktrans with book_title=match.book_set.first.title %}Author of <em>{{ book_title }}</em>{% endblocktrans %}</a> <a href="{{ match.local_path }}" target="_blank">{% blocktrans with book_title=match.book_set.first.title %}Author of <em>{{ book_title }}</em>{% endblocktrans %}</a>
</p> </p>
{% endfor %} {% endfor %}
<label><input type="radio" name="author_match-{{ counter }}" value="{{ author.name }}" required> {% trans "This is a new author" %}</label> <label class="label">
<input type="radio" name="author_match-{{ counter }}" value="{{ author.name }}" required> {% trans "This is a new author" %}
</label>
{% endwith %} {% endwith %}
</fieldset> </fieldset>
{% endfor %} {% endfor %}
@ -64,11 +85,17 @@
{% if not book %} {% if not book %}
<div class="column is-half"> <div class="column is-half">
<fieldset> <fieldset>
<legend class="title is-5 mb-1">{% trans "Is this an edition of an existing work?" %}</legend> <legend class="title is-5 mb-1">
{% trans "Is this an edition of an existing work?" %}
</legend>
{% for match in book_matches %} {% for match in book_matches %}
<label class="label"><input type="radio" name="parent_work" value="{{ match.parent_work.id }}"> {{ match.parent_work.title }}</label> <label class="label">
<input type="radio" name="parent_work" value="{{ match.parent_work.id }}"> {{ match.parent_work.title }}
</label>
{% endfor %} {% endfor %}
<label><input type="radio" name="parent_work" value="0" required> {% trans "This is a new work" %}</label> <label>
<input type="radio" name="parent_work" value="0" required> {% trans "This is a new work" %}
</label>
</fieldset> </fieldset>
</div> </div>
{% endif %} {% endif %}
@ -89,76 +116,79 @@
<section class="block"> <section class="block">
<h2 class="title is-4">{% trans "Metadata" %}</h2> <h2 class="title is-4">{% trans "Metadata" %}</h2>
<p class="mb-2"> <div class="field">
<label class="label" for="id_title">{% trans "Title:" %}</label> <label class="label" for="id_title">{% trans "Title:" %}</label>
<input type="text" name="title" value="{{ form.title.value|default:'' }}" maxlength="255" class="input" required="" id="id_title"> <input type="text" name="title" value="{{ form.title.value|default:'' }}" maxlength="255" class="input" required="" id="id_title">
</p> {% for error in form.title.errors %}
{% for error in form.title.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"> <div class="field">
<label class="label" for="id_subtitle">{% trans "Subtitle:" %}</label> <label class="label" for="id_subtitle">{% trans "Subtitle:" %}</label>
<input type="text" name="subtitle" value="{{ form.subtitle.value|default:'' }}" maxlength="255" class="input" id="id_subtitle"> <input type="text" name="subtitle" value="{{ form.subtitle.value|default:'' }}" maxlength="255" class="input" id="id_subtitle">
</p> {% for error in form.subtitle.errors %}
{% for error in form.subtitle.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"><label class="label" for="id_description">{% trans "Description:" %}</label> {{ form.description }} </p> <div class="field">
{% for error in form.description.errors %} <label class="label" for="id_description">{% trans "Description:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.description }}
{% endfor %} {% for error in form.description.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"> <div class="field">
<label class="label" for="id_series">{% trans "Series:" %}</label> <label class="label" for="id_series">{% trans "Series:" %}</label>
<input type="text" class="input" name="series" id="id_series" value="{{ form.series.value|default:'' }}"> <input type="text" class="input" name="series" id="id_series" value="{{ form.series.value|default:'' }}">
</p> {% for error in form.series.errors %}
{% for error in form.series.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"> <div class="field">
<label class="label" for="id_series_number">{% trans "Series number:" %}</label> <label class="label" for="id_series_number">{% trans "Series number:" %}</label>
{{ form.series_number }} {{ form.series_number }}
</p> {% for error in form.series_number.errors %}
{% for error in form.series_number.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"> <div class="field">
<label class="label" for="id_languages">{% trans "Languages:" %}</label> <label class="label" for="id_languages">{% trans "Languages:" %}</label>
{{ form.languages }} {{ form.languages }}
<span class="help">{% trans "Separate multiple values with commas." %}</span> <span class="help">{% trans "Separate multiple values with commas." %}</span>
</p> {% for error in form.languages.errors %}
{% for error in form.languages.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"> <div class="field">
<label class="label" for="id_publishers">{% trans "Publisher:" %}</label> <label class="label" for="id_publishers">{% trans "Publisher:" %}</label>
{{ form.publishers }} {{ form.publishers }}
<span class="help">{% trans "Separate multiple values with commas." %}</span> <span class="help">{% trans "Separate multiple values with commas." %}</span>
</p> {% for error in form.publishers.errors %}
{% for error in form.publishers.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"> <div class="field">
<label class="label" for="id_first_published_date">{% trans "First published date:" %}</label> <label class="label" for="id_first_published_date">{% trans "First published date:" %}</label>
<input type="date" name="first_published_date" class="input" id="id_first_published_date"{% if form.first_published_date.value %} value="{{ form.first_published_date.value|date:'Y-m-d' }}"{% endif %}> <input type="date" name="first_published_date" class="input" id="id_first_published_date"{% if form.first_published_date.value %} value="{{ form.first_published_date.value|date:'Y-m-d' }}"{% endif %}>
</p> {% for error in form.first_published_date.errors %}
{% for error in form.first_published_date.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"> <div class="field">
<label class="label" for="id_published_date">{% trans "Published date:" %}</label> <label class="label" for="id_published_date">{% trans "Published date:" %}</label>
<input type="date" name="published_date" class="input" id="id_published_date"{% if form.published_date.value %} value="{{ form.published_date.value|date:'Y-m-d'}}"{% endif %}> <input type="date" name="published_date" class="input" id="id_published_date"{% if form.published_date.value %} value="{{ form.published_date.value|date:'Y-m-d'}}"{% endif %}>
</p> {% for error in form.published_date.errors %}
{% for error in form.published_date.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
</section> </section>
<section class="block"> <section class="block">
@ -166,16 +196,23 @@
{% if book.authors.exists %} {% if book.authors.exists %}
<fieldset> <fieldset>
{% for author in book.authors.all %} {% for author in book.authors.all %}
<label class="label mb-2"> <div class="is-flex is-justify-content-space-between">
<input type="checkbox" name="remove_authors" value="{{ author.id }}" {% if author.id|stringformat:"i" in remove_authors %}checked{% endif %}> <label class="label mb-2">
{% blocktrans with name=author.name path=author.local_path %}Remove <a href="{{ path }}">{{ name }}</a>{% endblocktrans %} <input type="checkbox" name="remove_authors" value="{{ author.id }}" {% if author.id|stringformat:"i" in remove_authors %}checked{% endif %}>
</label> {% blocktrans with name=author.name %}Remove {{ name }}{% endblocktrans %}
</label>
<p class="help">
<a href="{{ author.local_path }}">{% blocktrans with name=author.name %}Author page for {{ name }}{% endblocktrans %}</a>
</p>
</div>
{% endfor %} {% endfor %}
</fieldset> </fieldset>
{% endif %} {% endif %}
<label class="label" for="id_add_author">{% trans "Add Authors:" %}</label> <div class="field">
<input class="input" type="text" name="add_author" id="id_add_author" placeholder="{% trans 'John Doe, Jane Smith' %}" value="{{ add_author }}" {% if confirm_mode %}readonly{% endif %}> <label class="label" for="id_add_author">{% trans "Add Authors:" %}</label>
<span class="help">{% trans "Separate multiple values with commas." %}</span> <input class="input" type="text" name="add_author" id="id_add_author" placeholder="{% trans 'John Doe, Jane Smith' %}" value="{{ add_author }}" {% if confirm_mode %}readonly{% endif %}>
<span class="help">{% trans "Separate multiple values with commas." %}</span>
</div>
</section> </section>
</div> </div>
@ -188,17 +225,17 @@
<div class="column"> <div class="column">
<div class="block"> <div class="block">
<p> <div class="field">
<label class="label" for="id_cover">{% trans "Upload cover:" %}</label> <label class="label" for="id_cover">{% trans "Upload cover:" %}</label>
{{ form.cover }} {{ form.cover }}
</p> </div>
{% if book %} {% if book %}
<p> <div class="field">
<label class="label" for="id_cover_url"> <label class="label" for="id_cover_url">
{% trans "Load cover from url:" %} {% trans "Load cover from url:" %}
</label> </label>
<input class="input" name="cover-url" id="id_cover_url"> <input class="input" name="cover-url" id="id_cover_url">
</p> </div>
{% endif %} {% endif %}
{% for error in form.cover.errors %} {% for error in form.cover.errors %}
<p class="help is-danger">{{ error | escape }}</p> <p class="help is-danger">{{ error | escape }}</p>
@ -209,51 +246,72 @@
<div class="block"> <div class="block">
<h2 class="title is-4">{% trans "Physical Properties" %}</h2> <h2 class="title is-4">{% trans "Physical Properties" %}</h2>
<p class="mb-2"><label class="label" for="id_physical_format">{% trans "Format:" %}</label> {{ form.physical_format }} </p> <div class="field">
{% for error in form.physical_format.errors %} <label class="label" for="id_physical_format">{% trans "Format:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.physical_format }}
{% endfor %} {% for error in form.physical_format.errors %}
{% for error in form.physical_format.errors %} <p class="help is-danger">{{ error | escape }}</p>
<p class="help is-danger">{{ error | escape }}</p> {% endfor %}
{% endfor %} </div>
<p class="mb-2"><label class="label" for="id_pages">{% trans "Pages:" %}</label> {{ form.pages }} </p> <div class="field">
{% for error in form.pages.errors %} <label class="label" for="id_pages">{% trans "Pages:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.pages }}
{% endfor %} {% for error in form.pages.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
</div> </div>
<div class="block"> <div class="block">
<h2 class="title is-4">{% trans "Book Identifiers" %}</h2> <h2 class="title is-4">{% trans "Book Identifiers" %}</h2>
<p class="mb-2"><label class="label" for="id_isbn_13">{% trans "ISBN 13:" %}</label> {{ form.isbn_13 }} </p> <div class="field">
{% for error in form.isbn_13.errors %} <label class="label" for="id_isbn_13">{% trans "ISBN 13:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.isbn_13 }}
{% endfor %} {% for error in form.isbn_13.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"><label class="label" for="id_isbn_10">{% trans "ISBN 10:" %}</label> {{ form.isbn_10 }} </p> <div class="field">
{% for error in form.isbn_10.errors %} <label class="label" for="id_isbn_10">{% trans "ISBN 10:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.isbn_10 }}
{% endfor %} {% for error in form.isbn_10.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"><label class="label" for="id_openlibrary_key">{% trans "Openlibrary ID:" %}</label> {{ form.openlibrary_key }} </p> <div class="field">
{% for error in form.openlibrary_key.errors %} <label class="label" for="id_openlibrary_key">{% trans "Openlibrary ID:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.openlibrary_key }}
{% endfor %} {% for error in form.openlibrary_key.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"><label class="label" for="id_inventaire_id">{% trans "Inventaire ID:" %}</label> {{ form.inventaire_id }} </p> <div class="field">
{% for error in form.inventaire_id.errors %} <label class="label" for="id_inventaire_id">{% trans "Inventaire ID:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.inventaire_id }}
{% endfor %} {% for error in form.inventaire_id.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"><label class="label" for="id_oclc_number">{% trans "OCLC Number:" %}</label> {{ form.oclc_number }} </p> <div class="field">
{% for error in form.oclc_number.errors %} <label class="label" for="id_oclc_number">{% trans "OCLC Number:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.oclc_number }}
{% endfor %} {% for error in form.oclc_number.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
<p class="mb-2"><label class="label" for="id_asin">{% trans "ASIN:" %}</label> {{ form.asin }} </p> <div class="field">
{% for error in form.ASIN.errors %} <label class="label" for="id_asin">{% trans "ASIN:" %}</label>
<p class="help is-danger">{{ error | escape }}</p> {{ form.asin }}
{% endfor %} {% for error in form.ASIN.errors %}
<p class="help is-danger">{{ error | escape }}</p>
{% endfor %}
</div>
</div> </div>
</div> </div>
</div> </div>
@ -261,7 +319,7 @@
{% if not confirm_mode %} {% if not confirm_mode %}
<div class="block"> <div class="block">
<button class="button is-primary" type="submit">{% trans "Save" %}</button> <button class="button is-primary" type="submit">{% trans "Save" %}</button>
<a class="button" href="{{ book.local_path}}">{% trans "Cancel" %}</a> <a class="button" href="{{ book.local_path }}">{% trans "Cancel" %}</a>
</div> </div>
{% endif %} {% endif %}
</form> </form>

View file

@ -11,7 +11,7 @@
{% trans "Close" as label %} {% trans "Close" as label %}
<div class="modal-card"> <div class="modal-card">
<header class="modal-card-head" tabindex="0" id="modal-title-{{ controls_text }}-{{ controls_uid }}"> <header class="modal-card-head" tabindex="0" id="modal-title-{{ controls_text }}-{{ controls_uid }}">
<h2 class="modal-card-title" id="modal-card-title-{{ controls_text }}-{{ controls_uid }}"> <h2 class="modal-card-title is-flex-shrink-1" id="modal-card-title-{{ controls_text }}-{{ controls_uid }}">
{% block modal-title %}{% endblock %} {% block modal-title %}{% endblock %}
</h2> </h2>
{% include 'snippets/toggle/toggle_button.html' with label=label class="delete" nonbutton=True %} {% include 'snippets/toggle/toggle_button.html' with label=label class="delete" nonbutton=True %}

View file

@ -41,8 +41,8 @@
</label> </label>
</div> </div>
<div class="field"> <div class="field">
<label class="label"> <label>
<p>{% trans "Privacy setting for imported reviews:" %}</p> <span class="label">{% trans "Privacy setting for imported reviews:" %}</span>
{% include 'snippets/privacy_select.html' with no_label=True %} {% include 'snippets/privacy_select.html' with no_label=True %}
</label> </label>
</div> </div>

View file

@ -8,13 +8,17 @@
<div class="block"> <div class="block">
<h1 class="title">{% trans "Import Status" %}</h1> <h1 class="title">{% trans "Import Status" %}</h1>
<p> <dl>
{% trans "Import started:" %} {{ job.created_date | naturaltime }} <div class="is-flex">
</p> <dt class="has-text-weight-medium">{% trans "Import started:" %}</dt>
{% if job.complete %} <dd class="ml-2">{{ job.created_date | naturaltime }}</dd>
<p> </div>
{% trans "Import completed:" %} {{ task.date_done | naturaltime }} {% if job.complete %}
</p> <div class="is-flex">
<dt class="has-text-weight-medium">{% trans "Import completed:" %}</dt>
<dd class="ml-2">{{ task.date_done | naturaltime }}</dd>
</div>
</dl>
{% elif task.failed %} {% elif task.failed %}
<div class="notification is-danger">{% trans "TASK FAILED" %}</div> <div class="notification is-danger">{% trans "TASK FAILED" %}</div>
{% endif %} {% endif %}
@ -22,8 +26,9 @@
<div class="block"> <div class="block">
{% if not job.complete %} {% if not job.complete %}
{% trans "Import still in progress." %}
<p> <p>
{% trans "Import still in progress." %}
<br/>
{% trans "(Hit reload to update!)" %} {% trans "(Hit reload to update!)" %}
</p> </p>
{% endif %} {% endif %}
@ -49,16 +54,13 @@
<fieldset id="failed-imports"> <fieldset id="failed-imports">
<ul> <ul>
{% for item in failed_items %} {% for item in failed_items %}
<li class="pb-1"> <li class="mb-2 is-flex is-align-items-start">
<input class="checkbox" type="checkbox" name="import_item" value="{{ item.id }}" id="import-item-{{ item.id }}"> <input class="checkbox mt-1" type="checkbox" name="import_item" value="{{ item.id }}" id="import-item-{{ item.id }}">
<label for="import-item-{{ item.id }}"> <label class="ml-1" for="import-item-{{ item.id }}">
Line {{ item.index }}: {% blocktrans with index=item.index title=item.data.Title author=item.data.Author %}Line {{ index }}: <strong>{{ title }}</strong> by {{ author }}{% endblocktrans %}
<strong>{{ item.data.Title }}</strong> by <br/>
{{ item.data.Author }}
</label>
<p>
{{ item.fail_reason }}. {{ item.fail_reason }}.
</p> </label>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>

View file

@ -26,14 +26,14 @@
{% csrf_token %} {% csrf_token %}
<div class="columns"> <div class="columns">
<div class="column is-half"> <div class="column is-half">
<div> <div class="field">
<label class="label" for="id_server_name">{% trans "Instance:" %}</label> <label class="label" for="id_server_name">{% trans "Instance:" %}</label>
<input type="text" name="server_name" maxlength="255" class="input" required id="id_server_name" value="{{ form.server_name.value|default:'' }}" placeholder="domain.com"> <input type="text" name="server_name" maxlength="255" class="input" required id="id_server_name" value="{{ form.server_name.value|default:'' }}" placeholder="domain.com">
{% for error in form.server_name.errors %} {% for error in form.server_name.errors %}
<p class="help is-danger">{{ error | escape }}</p> <p class="help is-danger">{{ error | escape }}</p>
{% endfor %} {% endfor %}
</div> </div>
<div> <div class="field">
<label class="label" for="id_status">{% trans "Status:" %}</label> <label class="label" for="id_status">{% trans "Status:" %}</label>
<div class="select"> <div class="select">
<select name="status" class="" id="id_status"> <select name="status" class="" id="id_status">
@ -44,14 +44,14 @@
</div> </div>
</div> </div>
<div class="column is-half"> <div class="column is-half">
<div> <div class="field">
<label class="label" for="id_application_type">{% trans "Software:" %}</label> <label class="label" for="id_application_type">{% trans "Software:" %}</label>
<input type="text" name="application_type" maxlength="255" class="input" id="id_application_type" value="{{ form.application_type.value|default:'' }}"> <input type="text" name="application_type" maxlength="255" class="input" id="id_application_type" value="{{ form.application_type.value|default:'' }}">
{% for error in form.application_type.errors %} {% for error in form.application_type.errors %}
<p class="help is-danger">{{ error | escape }}</p> <p class="help is-danger">{{ error | escape }}</p>
{% endfor %} {% endfor %}
</div> </div>
<div> <div class="field">
<label class="label" for="id_application_version">{% trans "Version:" %}</label> <label class="label" for="id_application_version">{% trans "Version:" %}</label>
<input type="text" name="application_version" maxlength="255" class="input" id="id_application_version" value="{{ form.application_version.value|default:'' }}"> <input type="text" name="application_version" maxlength="255" class="input" id="id_application_version" value="{{ form.application_version.value|default:'' }}">
{% for error in form.application_version.errors %} {% for error in form.application_version.errors %}
@ -60,10 +60,10 @@
</div> </div>
</div> </div>
</div> </div>
<p> <div class="field">
<label class="label" for="id_notes">{% trans "Notes:" %}</label> <label class="label" for="id_notes">{% trans "Notes:" %}</label>
<textarea name="notes" cols="None" rows="None" class="textarea" id="id_notes">{{ form.notes.value|default:'' }}</textarea> <textarea name="notes" cols="None" rows="None" class="textarea" id="id_notes">{{ form.notes.value|default:'' }}</textarea>
</p> </div>
<button type="submit" class="button is-primary">{% trans "Save" %}</button> <button type="submit" class="button is-primary">{% trans "Save" %}</button>
</form> </form>

View file

@ -11,23 +11,23 @@
{% csrf_token %} {% csrf_token %}
<section class="block" id="instance-info"> <section class="block" id="instance-info">
<h2 class="title is-4">{% trans "Instance Info" %}</h2> <h2 class="title is-4">{% trans "Instance Info" %}</h2>
<div class="control"> <div class="field">
<label class="label" for="id_name">{% trans "Instance Name:" %}</label> <label class="label" for="id_name">{% trans "Instance Name:" %}</label>
{{ site_form.name }} {{ site_form.name }}
</div> </div>
<div class="control"> <div class="field">
<label class="label" for="id_instance_tagline">{% trans "Tagline:" %}</label> <label class="label" for="id_instance_tagline">{% trans "Tagline:" %}</label>
{{ site_form.instance_tagline }} {{ site_form.instance_tagline }}
</div> </div>
<div class="control"> <div class="field">
<label class="label" for="id_instance_description">{% trans "Instance description:" %}</label> <label class="label" for="id_instance_description">{% trans "Instance description:" %}</label>
{{ site_form.instance_description }} {{ site_form.instance_description }}
</div> </div>
<div class="control"> <div class="field">
<label class="label" for="id_code_of_conduct">{% trans "Code of conduct:" %}</label> <label class="label" for="id_code_of_conduct">{% trans "Code of conduct:" %}</label>
{{ site_form.code_of_conduct }} {{ site_form.code_of_conduct }}
</div> </div>
<div class="control"> <div class="field">
<label class="label" for="id_privacy_policy">{% trans "Privacy Policy:" %}</label> <label class="label" for="id_privacy_policy">{% trans "Privacy Policy:" %}</label>
{{ site_form.privacy_policy }} {{ site_form.privacy_policy }}
</div> </div>
@ -57,19 +57,19 @@
<section class="block" id="footer"> <section class="block" id="footer">
<h2 class="title is-4">{% trans "Footer Content" %}</h2> <h2 class="title is-4">{% trans "Footer Content" %}</h2>
<div class="control"> <div class="field">
<label class="label" for="id_support_link">{% trans "Support link:" %}</label> <label class="label" for="id_support_link">{% trans "Support link:" %}</label>
<input type="text" name="support_link" maxlength="255" class="input" id="id_support_link" placeholder="https://www.patreon.com/bookwyrm"{% if site.support_link %} value="{{ site.support_link }}"{% endif %}> <input type="text" name="support_link" maxlength="255" class="input" id="id_support_link" placeholder="https://www.patreon.com/bookwyrm"{% if site.support_link %} value="{{ site.support_link }}"{% endif %}>
</div> </div>
<div class="control"> <div class="field">
<label class="label" for="id_support_title">{% trans "Support title:" %}</label> <label class="label" for="id_support_title">{% trans "Support title:" %}</label>
<input type="text" name="support_title" maxlength="100" class="input" id="id_support_title" placeholder="Patreon"{% if site.support_title %} value="{{ site.support_title }}"{% endif %}> <input type="text" name="support_title" maxlength="100" class="input" id="id_support_title" placeholder="Patreon"{% if site.support_title %} value="{{ site.support_title }}"{% endif %}>
</div> </div>
<div class="control"> <div class="field">
<label class="label" for="id_admin_email">{% trans "Admin email:" %}</label> <label class="label" for="id_admin_email">{% trans "Admin email:" %}</label>
{{ site_form.admin_email }} {{ site_form.admin_email }}
</div> </div>
<div class="control"> <div class="field">
<label class="label" for="id_footer_item">{% trans "Additional info:" %}</label> <label class="label" for="id_footer_item">{% trans "Additional info:" %}</label>
{{ site_form.footer_item }} {{ site_form.footer_item }}
</div> </div>
@ -79,15 +79,19 @@
<section class="block" id="registration"> <section class="block" id="registration">
<h2 class="title is-4">{% trans "Registration" %}</h2> <h2 class="title is-4">{% trans "Registration" %}</h2>
<div class="control"> <div class="field">
<label class="label" for="id_allow_registration">{% trans "Allow registration:" %} <label class="label" for="id_allow_registration">
{{ site_form.allow_registration }} {{ site_form.allow_registration }}
{% trans "Allow registration" %}
</label>
</div> </div>
<div class="control"> <div class="field">
<label class="label" for="id_allow_invite_requests">{% trans "Allow invite requests:" %} <label class="label" for="id_allow_invite_requests">
{{ site_form.allow_invite_requests }} {{ site_form.allow_invite_requests }}
{% trans "Allow invite requests" %}
</label>
</div> </div>
<div class="control"> <div class="field">
<label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label> <label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label>
{{ site_form.registration_closed_text }} {{ site_form.registration_closed_text }}
</div> </div>

View file

@ -3,10 +3,10 @@
<input type="hidden" name="id" value="{{ readthrough.id }}"> <input type="hidden" name="id" value="{{ readthrough.id }}">
<input type="hidden" name="book" value="{{ book.id }}"> <input type="hidden" name="book" value="{{ book.id }}">
<div class="field"> <div class="field">
<label class="label" tabindex="0" id="add-readthrough-focus"> <label class="label" tabindex="0" id="add-readthrough-focus" for="id_start_date-{{ readthrough.id }}">
{% trans "Started reading" %} {% trans "Started reading" %}
<input type="date" name="start_date" class="input" id="id_start_date-{{ readthrough.id }}" value="{{ readthrough.start_date | date:"Y-m-d" }}">
</label> </label>
<input type="date" name="start_date" class="input" id="id_start_date-{{ readthrough.id }}" value="{{ readthrough.start_date | date:"Y-m-d" }}">
</div> </div>
{# Only show progress for editing existing readthroughs #} {# Only show progress for editing existing readthroughs #}
{% if readthrough.id and not readthrough.finish_date %} {% if readthrough.id and not readthrough.finish_date %}
@ -26,8 +26,8 @@
</div> </div>
{% endif %} {% endif %}
<div class="field"> <div class="field">
<label class="label"> <label class="label" for="id_finish_date-{{ readthrough.id }}">
{% trans "Finished reading" %} {% trans "Finished reading" %}
<input type="date" name="finish_date" class="input" id="id_finish_date-{{ readthrough.id }}" value="{{ readthrough.finish_date | date:"Y-m-d" }}">
</label> </label>
<input type="date" name="finish_date" class="input" id="id_finish_date-{{ readthrough.id }}" value="{{ readthrough.finish_date | date:"Y-m-d" }}">
</div> </div>

View file

@ -15,16 +15,16 @@
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="id" value="{{ readthrough.id }}"> <input type="hidden" name="id" value="{{ readthrough.id }}">
<div class="field"> <div class="field">
<label class="label"> <label class="label" for="finish_id_start_date-{{ uuid }}">
{% trans "Started reading" %} {% trans "Started reading" %}
<input type="date" name="start_date" class="input" id="finish_id_start_date-{{ uuid }}" value="{{ readthrough.start_date | date:"Y-m-d" }}">
</label> </label>
<input type="date" name="start_date" class="input" id="finish_id_start_date-{{ uuid }}" value="{{ readthrough.start_date | date:"Y-m-d" }}">
</div> </div>
<div class="field"> <div class="field">
<label class="label"> <label class="label" for="id_finish_date-{{ uuid }}">
{% trans "Finished reading" %} {% trans "Finished reading" %}
<input type="date" name="finish_date" class="input" id="id_finish_date-{{ uuid }}" value="{% now "Y-m-d" %}">
</label> </label>
<input type="date" name="finish_date" class="input" id="id_finish_date-{{ uuid }}" value="{% now "Y-m-d" %}">
</div> </div>
</section> </section>
{% endblock %} {% endblock %}
@ -38,7 +38,7 @@
</label> </label>
{% include 'snippets/privacy_select.html' %} {% include 'snippets/privacy_select.html' %}
</div> </div>
<div class="column"> <div class="column has-text-right">
<button type="submit" class="button is-success">{% trans "Save" %}</button> <button type="submit" class="button is-success">{% trans "Save" %}</button>
{% trans "Cancel" as button_text %} {% trans "Cancel" as button_text %}
{% include 'snippets/toggle/close_button.html' with text=button_text controls_text="finish-reading" controls_uid=uuid %} {% include 'snippets/toggle/close_button.html' with text=button_text controls_text="finish-reading" controls_uid=uuid %}

View file

@ -13,10 +13,10 @@
<section class="modal-card-body"> <section class="modal-card-body">
{% csrf_token %} {% csrf_token %}
<div class="field"> <div class="field">
<label class="label"> <label class="label" for="start_id_start_date-{{ uuid }}">
{% trans "Started reading" %} {% trans "Started reading" %}
<input type="date" name="start_date" class="input" id="start_id_start_date-{{ uuid }}" value="{% now "Y-m-d" %}">
</label> </label>
<input type="date" name="start_date" class="input" id="start_id_start_date-{{ uuid }}" value="{% now "Y-m-d" %}">
</div> </div>
</section> </section>
{% endblock %} {% endblock %}
@ -30,7 +30,7 @@
</label> </label>
{% include 'snippets/privacy_select.html' %} {% include 'snippets/privacy_select.html' %}
</div> </div>
<div class="column"> <div class="column has-text-right">
<button class="button is-success" type="submit">{% trans "Save" %}</button> <button class="button is-success" type="submit">{% trans "Save" %}</button>
{% trans "Cancel" as button_text %} {% trans "Cancel" as button_text %}
{% include 'snippets/toggle/toggle_button.html' with text=button_text controls_text="start-reading" controls_uid=uuid %} {% include 'snippets/toggle/toggle_button.html' with text=button_text controls_text="start-reading" controls_uid=uuid %}

View file

@ -0,0 +1,24 @@
{% load i18n %}
{% load utilities %}
{% if widget.is_initial %}
<p class="mb-1">
{{ widget.initial_text }}:
<a href="{{ widget.value.url }}">{{ widget.value|truncatepath:10 }}</a>
</p>
{% if not widget.required %}
<p class="mb-1">
<label class="has-text-weight-normal">
<input type="checkbox" name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}"{% if widget.attrs.disabled %} disabled{% endif %}>
{{ widget.clear_checkbox_label }}
</label>{% endif %}
</p>
<p class="mb-1">
{{ widget.input_text }}:
{% else %}
<p class="mb-1">
{% endif %}
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>
<span class="help file-cta is-hidden file-too-big">{% trans "File exceeds maximum size: 10MB" %}</span>
</p>

View file

@ -1,4 +1,5 @@
""" template filters for really common utilities """ """ template filters for really common utilities """
import os
from uuid import uuid4 from uuid import uuid4
from django import template from django import template
@ -33,3 +34,15 @@ def get_title(book):
def comparison_bool(str1, str2): def comparison_bool(str1, str2):
"""idk why I need to write a tag for this, it reutrns a bool""" """idk why I need to write a tag for this, it reutrns a bool"""
return str1 == str2 return str1 == str2
@register.filter(is_safe=True)
def truncatepath(value, arg):
"""Truncate a path by removing all directories except the first and truncating ."""
path = os.path.normpath(value.name)
path_list = path.split(os.sep)
try:
length = int(arg)
except ValueError: # invalid literal for int()
return path_list[-1] # Fail silently.
return "%s/…%s" % (path_list[0], path_list[-1][-length:])

View file

@ -1,10 +1,10 @@
""" bookwyrm settings and configuration """ """ bookwyrm settings and configuration """
from bookwyrm.settings import * from bookwyrm.settings import *
CELERY_BROKER_URL = env("CELERY_BROKER") CELERY_BROKER_URL = CELERY_BROKER
CELERY_ACCEPT_CONTENT = ["json"] CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json" CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_BACKEND = "redis" FLOWER_PORT = env("FLOWER_PORT")
INSTALLED_APPS = INSTALLED_APPS + [ INSTALLED_APPS = INSTALLED_APPS + [
"celerywyrm", "celerywyrm",

View file

@ -90,10 +90,10 @@ services:
restart: on-failure restart: on-failure
flower: flower:
build: . build: .
command: flower --port=${FLOWER_PORT} --basic_auth=${FLOWER_USER}:${FLOWER_PASSWORD} command: flower -A celerywyrm
env_file: .env env_file: .env
environment: volumes:
- CELERY_BROKER_URL=${CELERY_BROKER} - .:/app
networks: networks:
- main - main
depends_on: depends_on:

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-model-utils==4.0.0 django-model-utils==4.0.0
environs==7.2.0 environs==7.2.0
flower==0.9.4 flower==0.9.4