mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-04 23:36:32 +00:00
Merge branch 'main' into production
This commit is contained in:
commit
0f419d2b06
22 changed files with 109 additions and 96 deletions
28
.github/workflows/curlylint.yaml
vendored
Normal file
28
.github/workflows/curlylint.yaml
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
name: Templates validator
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install curlylint
|
||||||
|
run: pip install curlylint
|
||||||
|
|
||||||
|
- name: Run linter
|
||||||
|
run: >
|
||||||
|
curlylint --rule 'aria_role: true' \
|
||||||
|
--rule 'django_forms_rendering: true' \
|
||||||
|
--rule 'html_has_lang: true' \
|
||||||
|
--rule 'image_alt: true' \
|
||||||
|
--rule 'meta_viewport: true' \
|
||||||
|
--rule 'no_autofocus: true' \
|
||||||
|
--rule 'tabindex_no_positive: true' \
|
||||||
|
--exclude '_modal.html|create_status/layout.html' \
|
||||||
|
bookwyrm/templates
|
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
{% if author.wikipedia_link %}
|
{% if author.wikipedia_link %}
|
||||||
<p class="my-1">
|
<p class="my-1">
|
||||||
<a itemprop="sameAs" href="{{ author.wikipedia_link }}" rel=”noopener” target="_blank">
|
<a itemprop="sameAs" href="{{ author.wikipedia_link }}" rel="noopener" target="_blank">
|
||||||
{% trans "Wikipedia" %}
|
{% trans "Wikipedia" %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
<form name="add-description" method="POST" action="/add-description/{{ book.id }}">
|
<form name="add-description" method="POST" action="/add-description/{{ book.id }}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<p class="fields is-grouped">
|
<p class="fields is-grouped">
|
||||||
<label class="label"for="id_description_{{ book.id }}">{% trans "Description:" %}</label>
|
<label class="label" for="id_description_{{ book.id }}">{% trans "Description:" %}</label>
|
||||||
<textarea name="description" cols="None" rows="None" class="textarea" id="id_description_{{ book.id }}"></textarea>
|
<textarea name="description" cols="None" rows="None" class="textarea" id="id_description_{{ book.id }}"></textarea>
|
||||||
</p>
|
</p>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
|
|
@ -42,11 +42,18 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if book %}
|
<form
|
||||||
<form class="block" name="edit-book" action="{{ book.local_path }}/{% if confirm_mode %}confirm{% else %}edit{% endif %}" method="post" enctype="multipart/form-data">
|
class="block"
|
||||||
{% else %}
|
{% if book %}
|
||||||
<form class="block" name="create-book" action="/create-book{% if confirm_mode %}/confirm{% endif %}" method="post" enctype="multipart/form-data">
|
name="edit-book"
|
||||||
{% endif %}
|
action="{{ book.local_path }}/{% if confirm_mode %}confirm{% else %}edit{% endif %}"
|
||||||
|
{% else %}
|
||||||
|
name="create-book"
|
||||||
|
action="/create-book{% if confirm_mode %}/confirm{% endif %}"
|
||||||
|
{% endif %}
|
||||||
|
method="post"
|
||||||
|
enctype="multipart/form-data"
|
||||||
|
>
|
||||||
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% if confirm_mode %}
|
{% if confirm_mode %}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
{% trans "Progress Updates:" %}
|
{% trans "Progress Updates:" %}
|
||||||
</dl>
|
|
||||||
<ul>
|
<ul>
|
||||||
{% if readthrough.finish_date or readthrough.progress %}
|
{% if readthrough.finish_date or readthrough.progress %}
|
||||||
<li>
|
<li>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<html>
|
<html lang="{% get_lang %}">
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<strong>Subject:</strong> {% include subject_path %}
|
<strong>Subject:</strong> {% include subject_path %}
|
||||||
|
|
|
@ -40,11 +40,10 @@
|
||||||
{% if suggested_users %}
|
{% if suggested_users %}
|
||||||
{# suggested users for when things are very lonely #}
|
{# suggested users for when things are very lonely #}
|
||||||
{% include 'feed/suggested_users.html' with suggested_users=suggested_users %}
|
{% include 'feed/suggested_users.html' with suggested_users=suggested_users %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% for activity in activities %}
|
{% for activity in activities %}
|
||||||
|
|
||||||
{% if not activities.number > 1 and forloop.counter0 == 2 and suggested_users %}
|
{% if not activities.number > 1 and forloop.counter0 == 2 and suggested_users %}
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
<section class="block">
|
<section class="block">
|
||||||
<h2 class="title is-5">{% trans "Who to follow" %}</h2>
|
<h2 class="title is-5">{% trans "Who to follow" %}</h2>
|
||||||
{% include 'snippets/suggested_users.html' with suggested_users=suggested_users %}
|
{% include 'snippets/suggested_users.html' with suggested_users=suggested_users %}
|
||||||
<a class="help" href="{% url 'directory' %}">View directory <span class="icon icon-arrow-right"></a>
|
<a class="help" href="{% url 'directory' %}">{% trans "View directory" %} <span class="icon icon-arrow-right"></span></a>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
<dt class="has-text-weight-medium">{% trans "Import completed:" %}</dt>
|
<dt class="has-text-weight-medium">{% trans "Import completed:" %}</dt>
|
||||||
<dd class="ml-2">{{ task.date_done | naturaltime }}</dd>
|
<dd class="ml-2">{{ task.date_done | naturaltime }}</dd>
|
||||||
</div>
|
</div>
|
||||||
|
{% elif task.failed %}
|
||||||
|
<div class="notification is-danger">{% trans "TASK FAILED" %}</div>
|
||||||
|
{% endif %}
|
||||||
</dl>
|
</dl>
|
||||||
{% elif task.failed %}
|
|
||||||
<div class="notification is-danger">{% trans "TASK FAILED" %}</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="block">
|
<div class="block">
|
||||||
|
@ -84,26 +84,26 @@
|
||||||
|
|
||||||
<button class="button is-block mt-3" type="submit">{% trans "Retry items" %}</button>
|
<button class="button is-block mt-3" type="submit">{% trans "Retry items" %}</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
<ul>
|
|
||||||
{% for item in failed_items %}
|
|
||||||
<li class="pb-1">
|
|
||||||
<p>
|
|
||||||
Line {{ item.index }}:
|
|
||||||
<strong>{{ item.data.Title }}</strong> by
|
|
||||||
{{ item.data.Author }}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{ item.fail_reason }}.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<ul>
|
||||||
|
{% for item in failed_items %}
|
||||||
|
<li class="pb-1">
|
||||||
|
<p>
|
||||||
|
Line {{ item.index }}:
|
||||||
|
<strong>{{ item.data.Title }}</strong> by
|
||||||
|
{{ item.data.Author }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{ item.fail_reason }}.
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -153,7 +153,6 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endspaceless %}{% endblock %}
|
{% endspaceless %}{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
{% extends 'layout.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block title %}{% trans "Search Results" %}{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
{% with book_results|first as local_results %}
|
|
||||||
<div class="block">
|
|
||||||
<h1 class="title">{% blocktrans %}Search Results for "{{ query }}"{% endblocktrans %}</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="block columns">
|
|
||||||
<div class="column">
|
|
||||||
<h2 class="title">{% trans "Matching Books" %}</h2>
|
|
||||||
<section class="block">
|
|
||||||
{% if not results %}
|
|
||||||
<p>{% blocktrans %}No books found for "{{ query }}"{% endblocktrans %}</p>
|
|
||||||
{% else %}
|
|
||||||
<ul>
|
|
||||||
{% for result in results %}
|
|
||||||
<li class="pd-4">
|
|
||||||
<a href="{{ result.key }}">{% include 'snippets/search_result_text.html' with result=result link=True %}</a>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div class="column">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endwith %}
|
|
||||||
{% endblock %}
|
|
|
@ -7,7 +7,6 @@
|
||||||
{% block edit-button %}
|
{% block edit-button %}
|
||||||
{% trans "Create Announcement" as button_text %}
|
{% trans "Create Announcement" as button_text %}
|
||||||
{% include 'snippets/toggle/open_button.html' with controls_text="create_announcement" icon_with_text="plus" text=button_text focus="create_announcement_header" %}
|
{% include 'snippets/toggle/open_button.html' with controls_text="create_announcement" icon_with_text="plus" text=button_text focus="create_announcement_header" %}
|
||||||
</a>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block panel %}
|
{% block panel %}
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for invite in invites %}
|
{% for invite in invites %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ invite.link }}">{{ invite.link }}</td>
|
<td><a href="{{ invite.link }}">{{ invite.link }}</a></td>
|
||||||
<td>{{ invite.expiry|naturaltime }}</td>
|
<td>{{ invite.expiry|naturaltime }}</td>
|
||||||
<td>{{ invite.use_limit }}</td>
|
<td>{{ invite.use_limit }}</td>
|
||||||
<td>{{ invite.times_used }}</td>
|
<td>{{ invite.times_used }}</td>
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="id_file">JSON data:</label>
|
<label class="label" for="id_file">JSON data:</label>
|
||||||
<aside class="help">
|
<aside class="help">
|
||||||
Expects a json file in the format provided by <a href="https://fediblock.org/" target="_blank" rel=”noopener”>FediBlock</a>, with a list of entries that have <code>instance</code> and <code>url</code> fields. For example:
|
Expects a json file in the format provided by <a href="https://fediblock.org/" target="_blank" rel="noopener">FediBlock</a>, with a list of entries that have <code>instance</code> and <code>url</code> fields. For example:
|
||||||
<pre>
|
<pre>
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<a
|
<a
|
||||||
href="{{ result.view_link|default:result.key }}"
|
href="{{ result.view_link|default:result.key }}"
|
||||||
{% if remote_result %}
|
{% if remote_result %}
|
||||||
rel=”noopener”
|
rel="noopener"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
>{{ result.title }}</a>
|
>{{ result.title }}</a>
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
{% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="start_reading" controls_uid=button_uuid focus="modal_title_start_reading" disabled=is_current fallback_url=fallback_url %}
|
{% include 'snippets/toggle/toggle_button.html' with class=class text=button_text controls_text="start_reading" controls_uid=button_uuid focus="modal_title_start_reading" disabled=is_current fallback_url=fallback_url %}
|
||||||
|
|
||||||
{% endif %}{% elif shelf.identifier == 'read' and active_shelf.shelf.identifier == 'read' %}{% if not dropdown or active_shelf.shelf.identifier|next_shelf != shelf.identifier %}
|
{% endif %}{% elif shelf.identifier == 'read' and active_shelf.shelf.identifier == 'read' %}{% if not dropdown or active_shelf.shelf.identifier|next_shelf != shelf.identifier %}
|
||||||
<button type="button" class="button {{ class }}" disabled><span>{% trans "Read" %}</span>
|
<button type="button" class="button {{ class }}" disabled>
|
||||||
|
<span>{% trans "Read" %}</span>
|
||||||
|
</button>
|
||||||
{% endif %}{% elif shelf.identifier == 'read' %}{% if not dropdown or active_shelf.shelf.identifier|next_shelf != shelf.identifier %}
|
{% endif %}{% elif shelf.identifier == 'read' %}{% if not dropdown or active_shelf.shelf.identifier|next_shelf != shelf.identifier %}
|
||||||
|
|
||||||
{% trans "Finish reading" as button_text %}
|
{% trans "Finish reading" as button_text %}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div
|
<div
|
||||||
dir="auto"
|
dir="auto"
|
||||||
{% if itemprop %}itemprop="{{ itemprop }}{% endif %}"
|
{% if itemprop %}itemprop="{{ itemprop }}"{% endif %}
|
||||||
>
|
>
|
||||||
{{ full }}
|
{{ full }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div
|
<div
|
||||||
dir="auto"
|
dir="auto"
|
||||||
{% if itemprop %}itemprop="{{ itemprop }}{% endif %}"
|
{% if itemprop %}itemprop="{{ itemprop }}"{% endif %}
|
||||||
>
|
>
|
||||||
{{ full }}
|
{{ full }}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div class="column box has-background-white-bis content preserve-whitespace">
|
<div class="column box has-background-white-bis content preserve-whitespace">
|
||||||
{{ user.summary|to_markdown|safe }}
|
{{ user.summary|to_markdown|safe }}
|
||||||
{% endspaceless %}
|
|
||||||
</div>
|
</div>
|
||||||
|
{% endspaceless %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if not is_self and request.user.is_authenticated %}
|
{% if not is_self and request.user.is_authenticated %}
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if not activities %}
|
{% if not activities %}
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<p>{% trans "No activities yet!" %}</a>
|
<p>{% trans "No activities yet!" %}</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -2,23 +2,30 @@
|
||||||
{% load utilities %}
|
{% load utilities %}
|
||||||
|
|
||||||
{% if widget.is_initial %}
|
{% if widget.is_initial %}
|
||||||
<p class="mb-1">
|
<p class="mb-1">
|
||||||
{{ widget.initial_text }}:
|
{{ widget.initial_text }}:
|
||||||
<a href="{{ widget.value.url }}">{{ widget.value|truncatepath:10 }}</a>
|
<a href="{{ widget.value.url }}">{{ widget.value|truncatepath:10 }}</a>
|
||||||
</p>
|
</p>
|
||||||
{% if not widget.required %}
|
|
||||||
<p class="mb-1">
|
{% if not widget.required %}
|
||||||
<label class="has-text-weight-normal">
|
<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 %}>
|
<input type="checkbox" name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}"{% if widget.attrs.disabled %} disabled{% endif %}>
|
||||||
{{ widget.clear_checkbox_label }}
|
{{ widget.clear_checkbox_label }}
|
||||||
</label>{% endif %}
|
</label>
|
||||||
</p>
|
</p>
|
||||||
<p class="mb-1">
|
{% endif %}
|
||||||
{{ widget.input_text }}:
|
|
||||||
{% else %}
|
|
||||||
<p class="mb-1">
|
|
||||||
{% endif %}
|
{% 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 class="mb-1">
|
||||||
|
{% if widget.is_initial %}
|
||||||
|
{{ widget.input_text }}:
|
||||||
|
{% 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>
|
</p>
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ def get_header_template(status):
|
||||||
if isinstance(status, models.Boost):
|
if isinstance(status, models.Boost):
|
||||||
status = status.boosted_status
|
status = status.boosted_status
|
||||||
try:
|
try:
|
||||||
header_type = status.reading_status
|
header_type = status.reading_status.replace("-", "_")
|
||||||
if not header_type:
|
if not header_type:
|
||||||
raise AttributeError()
|
raise AttributeError()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|
|
@ -62,7 +62,7 @@ class Book(View):
|
||||||
queryset = queryset.filter(user=request.user, deleted=False)
|
queryset = queryset.filter(user=request.user, deleted=False)
|
||||||
else:
|
else:
|
||||||
queryset = reviews.exclude(Q(content__isnull=True) | Q(content=""))
|
queryset = reviews.exclude(Q(content__isnull=True) | Q(content=""))
|
||||||
queryset = queryset.select_related("user")
|
queryset = queryset.select_related("user").order_by("-published_date")
|
||||||
paginated = Paginator(queryset, PAGE_LENGTH)
|
paginated = Paginator(queryset, PAGE_LENGTH)
|
||||||
|
|
||||||
lists = privacy_filter(
|
lists = privacy_filter(
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
""" isbn search view """
|
""" isbn search view """
|
||||||
|
from django.core.paginator import Paginator
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from django.template.response import TemplateResponse
|
from django.template.response import TemplateResponse
|
||||||
from django.views import View
|
from django.views import View
|
||||||
|
|
||||||
from bookwyrm.connectors import connector_manager
|
from bookwyrm.connectors import connector_manager
|
||||||
|
from bookwyrm.settings import PAGE_LENGTH
|
||||||
from .helpers import is_api_request
|
from .helpers import is_api_request
|
||||||
|
|
||||||
# pylint: disable= no-self-use
|
# pylint: disable= no-self-use
|
||||||
|
@ -17,8 +19,12 @@ class Isbn(View):
|
||||||
if is_api_request(request):
|
if is_api_request(request):
|
||||||
return JsonResponse([r.json() for r in book_results], safe=False)
|
return JsonResponse([r.json() for r in book_results], safe=False)
|
||||||
|
|
||||||
|
paginated = Paginator(book_results, PAGE_LENGTH).get_page(
|
||||||
|
request.GET.get("page")
|
||||||
|
)
|
||||||
data = {
|
data = {
|
||||||
"results": book_results,
|
"results": [{"results": paginated}],
|
||||||
"query": isbn,
|
"query": isbn,
|
||||||
|
"type": "book",
|
||||||
}
|
}
|
||||||
return TemplateResponse(request, "isbn_search_results.html", data)
|
return TemplateResponse(request, "search/book.html", data)
|
||||||
|
|
Loading…
Reference in a new issue