mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-27 12:01:14 +00:00
Merge branch 'main' into progress-modal
This commit is contained in:
commit
4dbb09be87
104 changed files with 1818 additions and 1193 deletions
|
@ -8,4 +8,4 @@ WORKDIR /app
|
|||
|
||||
COPY requirements.txt /app/
|
||||
RUN pip install -r requirements.txt --no-cache-dir
|
||||
RUN apt-get update && apt-get install -y gettext libgettextpo-dev && apt-get clean
|
||||
RUN apt-get update && apt-get install -y gettext libgettextpo-dev tidy && apt-get clean
|
||||
|
|
|
@ -29,8 +29,7 @@ class CustomForm(ModelForm):
|
|||
input_type = visible.field.widget.input_type
|
||||
if isinstance(visible.field.widget, Textarea):
|
||||
input_type = "textarea"
|
||||
visible.field.widget.attrs["cols"] = None
|
||||
visible.field.widget.attrs["rows"] = None
|
||||
visible.field.widget.attrs["rows"] = 5
|
||||
visible.field.widget.attrs["class"] = css_classes[input_type]
|
||||
|
||||
|
||||
|
@ -269,7 +268,7 @@ class CreateInviteForm(CustomForm):
|
|||
class ShelfForm(CustomForm):
|
||||
class Meta:
|
||||
model = models.Shelf
|
||||
fields = ["user", "name", "privacy"]
|
||||
fields = ["user", "name", "privacy", "description"]
|
||||
|
||||
|
||||
class GoalForm(CustomForm):
|
||||
|
|
18
bookwyrm/migrations/0100_shelf_description.py
Normal file
18
bookwyrm/migrations/0100_shelf_description.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.5 on 2021-09-28 23:20
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("bookwyrm", "0099_readthrough_is_active"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="shelf",
|
||||
name="description",
|
||||
field=models.TextField(blank=True, max_length=500, null=True),
|
||||
),
|
||||
]
|
|
@ -21,6 +21,7 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel):
|
|||
|
||||
name = fields.CharField(max_length=100)
|
||||
identifier = models.CharField(max_length=100)
|
||||
description = models.TextField(blank=True, null=True, max_length=500)
|
||||
user = fields.ForeignKey(
|
||||
"User", on_delete=models.PROTECT, activitypub_field="owner"
|
||||
)
|
||||
|
@ -52,6 +53,11 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel):
|
|||
"""list of books for this shelf, overrides OrderedCollectionMixin"""
|
||||
return self.books.order_by("shelfbook")
|
||||
|
||||
@property
|
||||
def deletable(self):
|
||||
"""can the shelf be safely deleted?"""
|
||||
return self.editable and not self.shelfbook_set.exists()
|
||||
|
||||
def get_remote_id(self):
|
||||
"""shelf identifier instead of id"""
|
||||
base_path = self.user.remote_id
|
||||
|
@ -61,7 +67,7 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel):
|
|||
def raise_not_deletable(self, viewer):
|
||||
"""don't let anyone delete a default shelf"""
|
||||
super().raise_not_deletable(viewer)
|
||||
if not self.editable:
|
||||
if not self.deletable:
|
||||
raise PermissionDenied()
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -236,14 +236,12 @@
|
|||
<label class="label" for="id_cover">{% trans "Upload cover:" %}</label>
|
||||
{{ form.cover }}
|
||||
</div>
|
||||
{% if book %}
|
||||
<div class="field">
|
||||
<label class="label" for="id_cover_url">
|
||||
{% trans "Load cover from url:" %}
|
||||
</label>
|
||||
<input class="input" name="cover-url" id="id_cover_url">
|
||||
<input class="input" name="cover-url" id="id_cover_url" type="url" value="{{ cover_url|default:'' }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for error in form.cover.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
{% trans "Local users" %}
|
||||
</label>
|
||||
<label class="is-block">
|
||||
<input type="radio" class="radio" name="scope" value="federated" {% if not request.GET.sort or request.GET.scope == "federated" %}checked{% endif %}>
|
||||
<input type="radio" class="radio" name="scope" value="federated" {% if request.GET.scope == "federated" %}checked{% endif %}>
|
||||
{% trans "Federated community" %}
|
||||
</label>
|
||||
{% endblock %}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<label class="label" for="id_sort">{% trans "Order by" %}</label>
|
||||
<div class="select">
|
||||
<select name="sort" id="id_sort">
|
||||
<option value="suggested" {% if not request.GET.sort or request.GET.sort == "suggested" %}checked{% endif %}>{% trans "Suggested" %}</option>
|
||||
<option value="recent" {% if request.GET.sort == "suggested" %}checked{% endif %}>{% trans "Recently active" %}</option>
|
||||
<option value="recent" {% if request.GET.sort == "recent" %}selected{% endif %}>{% trans "Recently active" %}</option>
|
||||
<option value="suggested" {% if request.GET.sort == "suggested" %}selected{% endif %}>{% trans "Suggested" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
</a>
|
||||
</li>
|
||||
{% if perms.bookwyrm.create_invites or perms.moderate_user %}
|
||||
<li class="navbar-divider" role="presentation"></li>
|
||||
<li class="navbar-divider" role="presentation"> </li>
|
||||
{% endif %}
|
||||
{% if perms.bookwyrm.create_invites and not site.allow_registration %}
|
||||
<li>
|
||||
|
@ -133,7 +133,7 @@
|
|||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="navbar-divider" role="presentation"></li>
|
||||
<li class="navbar-divider" role="presentation"> </li>
|
||||
<li>
|
||||
<a href="{% url 'logout' %}" class="navbar-item">
|
||||
{% trans 'Log out' %}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
{% block panel %}
|
||||
{% if not request.user.blocks.exists %}
|
||||
<p>{% trans "No users currently blocked." %}</p>
|
||||
<p><em>{% trans "No users currently blocked." %}</em></p>
|
||||
{% else %}
|
||||
<ul>
|
||||
{% for user in request.user.blocks.all %}
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
{% block panel %}
|
||||
<form name="edit-profile" action="{% url 'prefs-password' %}" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<div class="block">
|
||||
<div class="field">
|
||||
<label class="label" for="id_password">{% trans "New password:" %}</label>
|
||||
<input type="password" name="password" maxlength="128" class="input" required="" id="id_password">
|
||||
</div>
|
||||
<div class="block">
|
||||
<div class="field">
|
||||
<label class="label" for="id_confirm_password">{% trans "Confirm password:" %}</label>
|
||||
<input type="password" name="confirm-password" maxlength="128" class="input" required="" id="id_confirm_password">
|
||||
</div>
|
||||
|
|
|
@ -7,76 +7,114 @@
|
|||
{% trans "Edit Profile" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block profile-tabs %}
|
||||
<ul class="menu-list">
|
||||
<li><a href="#profile">{% trans "Profile" %}</a></li>
|
||||
<li><a href="#display-preferences">{% trans "Display preferences" %}</a></li>
|
||||
<li><a href="#privacy">{% trans "Privacy" %}</a></li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
{% if form.non_field_errors %}
|
||||
<p class="notification is-danger">{{ form.non_field_errors }}</p>
|
||||
{% endif %}
|
||||
<form name="edit-profile" action="{% url 'prefs-profile' %}" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<div class="block">
|
||||
<label class="label" for="id_avatar">{% trans "Avatar:" %}</label>
|
||||
{{ form.avatar }}
|
||||
{% for error in form.avatar.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="block">
|
||||
<label class="label" for="id_name">{% trans "Display name:" %}</label>
|
||||
{{ form.name }}
|
||||
{% for error in form.name.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="block">
|
||||
<label class="label" for="id_summary">{% trans "Summary:" %}</label>
|
||||
{{ form.summary }}
|
||||
{% for error in form.summary.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="block">
|
||||
<label class="label" for="id_email">{% trans "Email address:" %}</label>
|
||||
{{ form.email }}
|
||||
{% for error in form.email.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="block">
|
||||
<label class="checkbox label" for="id_show_goal">
|
||||
{% trans "Show reading goal prompt in feed:" %}
|
||||
{{ form.show_goal }}
|
||||
</label>
|
||||
<label class="checkbox label" for="id_show_goal">
|
||||
{% trans "Show suggested users:" %}
|
||||
{{ form.show_suggested_users }}
|
||||
</label>
|
||||
<label class="checkbox label" for="id_discoverable">
|
||||
{% trans "Show this account in suggested users:" %}
|
||||
{{ form.discoverable }}
|
||||
</label>
|
||||
{% url 'directory' as path %}
|
||||
<p class="help">{% blocktrans %}Your account will show up in the <a href="{{ path }}">directory</a>, and may be recommended to other BookWyrm users.{% endblocktrans %}</p>
|
||||
</div>
|
||||
<div class="block">
|
||||
<label class="checkbox label" for="id_manually_approves_followers">
|
||||
{% trans "Manually approve followers:" %}
|
||||
{{ form.manually_approves_followers }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="block">
|
||||
<label class="label" for="id_default_post_privacy">
|
||||
{% trans "Default post privacy:" %}
|
||||
</label>
|
||||
<div class="select">
|
||||
{{ form.default_post_privacy }}
|
||||
<section class="block" id="profile">
|
||||
<h2 class="title is-4">{% trans "Profile" %}</h2>
|
||||
<div class="box">
|
||||
<label class="label" for="id_avatar">{% trans "Avatar:" %}</label>
|
||||
<div class="field columns is-mobile">
|
||||
{% if request.user.avatar %}
|
||||
<div class="column is-narrow">
|
||||
{% include 'snippets/avatar.html' with user=request.user large=True %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="column">
|
||||
{{ form.avatar }}
|
||||
{% for error in form.avatar.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_name">{% trans "Display name:" %}</label>
|
||||
{{ form.name }}
|
||||
{% for error in form.name.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_summary">{% trans "Summary:" %}</label>
|
||||
{{ form.summary }}
|
||||
{% for error in form.summary.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_email">{% trans "Email address:" %}</label>
|
||||
{{ form.email }}
|
||||
{% for error in form.email.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block">
|
||||
<label class="label" for="id_preferred_timezone">{% trans "Preferred Timezone: " %}</label>
|
||||
<div class="select">
|
||||
{{ form.preferred_timezone }}
|
||||
</section>
|
||||
|
||||
<hr aria-hidden="true">
|
||||
|
||||
<section class="block" id="display-preferences">
|
||||
<h2 class="title is-4">{% trans "Display preferences" %}</h2>
|
||||
<div class="box">
|
||||
<div class="field">
|
||||
<label class="checkbox label" for="id_show_goal">
|
||||
{% trans "Show reading goal prompt in feed:" %}
|
||||
{{ form.show_goal }}
|
||||
</label>
|
||||
<label class="checkbox label" for="id_show_suggested_users">
|
||||
{% trans "Show suggested users:" %}
|
||||
{{ form.show_suggested_users }}
|
||||
</label>
|
||||
<label class="checkbox label" for="id_discoverable">
|
||||
{% trans "Show this account in suggested users:" %}
|
||||
{{ form.discoverable }}
|
||||
</label>
|
||||
{% url 'directory' as path %}
|
||||
<p class="help">
|
||||
{% blocktrans %}Your account will show up in the <a href="{{ path }}">directory</a>, and may be recommended to other BookWyrm users.{% endblocktrans %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_preferred_timezone">{% trans "Preferred Timezone: " %}</label>
|
||||
<div class="select">
|
||||
{{ form.preferred_timezone }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block"><button class="button is-primary" type="submit">{% trans "Save" %}</button></div>
|
||||
</section>
|
||||
|
||||
<hr aria-hidden="true">
|
||||
|
||||
<section class="block" id="privacy">
|
||||
<h2 class="title is-4">{% trans "Privacy" %}</h2>
|
||||
<div class="box">
|
||||
<div class="field">
|
||||
<label class="checkbox label" for="id_manually_approves_followers">
|
||||
{% trans "Manually approve followers:" %}
|
||||
{{ form.manually_approves_followers }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_default_post_privacy">
|
||||
{% trans "Default post privacy:" %}
|
||||
</label>
|
||||
<div class="select">
|
||||
{{ form.default_post_privacy }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="field"><button class="button is-primary" type="submit">{% trans "Save" %}</button></div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
<ul class="menu-list">
|
||||
<li>
|
||||
{% url 'prefs-profile' as url %}
|
||||
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Profile" %}</a>
|
||||
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Edit Profile" %}</a>
|
||||
{% block profile-tabs %}{% endblock %}
|
||||
</li>
|
||||
<li>
|
||||
{% url 'prefs-password' as url %}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
{% block panel %}
|
||||
|
||||
<form name="edit-announcement" method="post" action="{% url 'settings-announcements' announcement.id %}" class="block">
|
||||
{% include 'settings/announcement_form.html' with controls_text="edit_announcement" %}
|
||||
{% include 'settings/announcements/announcement_form.html' with controls_text="edit_announcement" %}
|
||||
</form>
|
||||
|
||||
<div class="block content">
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
{% block panel %}
|
||||
<form name="create-announcement" method="post" action="{% url 'settings-announcements' %}" class="block">
|
||||
{% include 'settings/announcement_form.html' with controls_text="create_announcement" %}
|
||||
{% include 'settings/announcements/announcement_form.html' with controls_text="create_announcement" %}
|
||||
</form>
|
||||
|
||||
<div class="block">
|
||||
|
@ -48,11 +48,10 @@
|
|||
<td>{% if announcement.active %}{% trans "active" %}{% else %}{% trans "inactive" %}{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if not announcements %}
|
||||
<tr><td colspan="5"><em>{% trans "No announcements found" %}</em></td></tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
{% if not announcements %}
|
||||
<p><em>{% trans "No announcements found." %}</em></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% include 'snippets/pagination.html' with page=announcements path=request.path %}
|
|
@ -67,27 +67,27 @@
|
|||
<form method="get" action="{% url 'settings-dashboard' %}" class="notification has-background-white-bis">
|
||||
<div class="is-flex is-align-items-flex-end">
|
||||
<div class="ml-1 mr-1">
|
||||
<label class="label">
|
||||
<label class="label" for="id_start">
|
||||
{% trans "Start date:" %}
|
||||
<input class="input" type="date" name="start" value="{{ start }}">
|
||||
</label>
|
||||
<input class="input" type="date" name="start" value="{{ start }}" id="id_start">
|
||||
</div>
|
||||
<div class="ml-1 mr-1">
|
||||
<label class="label">
|
||||
<label class="label" for="id_end">
|
||||
{% trans "End date:" %}
|
||||
<input class="input" type="date" name="end" value="{{ end }}">
|
||||
</label>
|
||||
<input class="input" type="date" name="end" value="{{ end }}" id="id_end">
|
||||
</div>
|
||||
<div class="ml-1 mr-1">
|
||||
<label class="label">
|
||||
<label class="label" for="id_interval">
|
||||
{% trans "Interval:" %}
|
||||
<div class="select">
|
||||
<select name="days">
|
||||
<option value="1" {% if interval == 1 %}selected{% endif %}>{% trans "Days" %}</option>
|
||||
<option value="7" {% if interval == 7 %}selected{% endif %}>{% trans "Weeks" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<div class="select">
|
||||
<select name="days" id="id_interval">
|
||||
<option value="1" {% if interval == 1 %}selected{% endif %}>{% trans "Days" %}</option>
|
||||
<option value="7" {% if interval == 7 %}selected{% endif %}>{% trans "Weeks" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-1 mr-1">
|
||||
<button class="button is-link" type="submit">{% trans "Submit" %}</button>
|
||||
|
@ -115,6 +115,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.1/dist/chart.min.js"></script>
|
||||
{% include 'settings/dashboard_user_chart.html' %}
|
||||
{% include 'settings/dashboard_status_chart.html' %}
|
||||
{% include 'settings/dashboard/dashboard_user_chart.html' %}
|
||||
{% include 'settings/dashboard/dashboard_status_chart.html' %}
|
||||
{% endblock %}
|
|
@ -12,7 +12,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
{% include 'settings/domain_form.html' with controls_text="add_domain" class="block" %}
|
||||
{% include 'settings/email_blocklist/domain_form.html' with controls_text="add_domain" class="block" %}
|
||||
|
||||
<p class="notification block">
|
||||
{% trans "When someone tries to register with an email from this domain, no account will be created. The registration process will appear to have worked." %}
|
||||
|
@ -55,7 +55,11 @@
|
|||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if not domains.exists %}
|
||||
<tr><td colspan="5"><em>{% trans "No email domains currently blocked" %}</em></td></tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -33,6 +33,8 @@
|
|||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-half">
|
||||
<div class="field">
|
||||
<label class="label" for="id_status">{% trans "Status:" %}</label>
|
||||
<div class="select">
|
||||
|
@ -43,6 +45,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column is-half">
|
||||
<div class="field">
|
||||
<label class="label" for="id_application_type">{% trans "Software:" %}</label>
|
||||
|
@ -51,6 +55,8 @@
|
|||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-half">
|
||||
<div class="field">
|
||||
<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:'' }}">
|
||||
|
@ -62,7 +68,7 @@
|
|||
</div>
|
||||
<div class="field">
|
||||
<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="40" rows="5" class="textarea" id="id_notes">{{ form.notes.value|default:'' }}</textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="button is-primary">{% trans "Save" %}</button>
|
|
@ -19,18 +19,14 @@
|
|||
<h2 class="title is-4">{% trans "Details" %}</h2>
|
||||
<div class="box is-flex-grow-1 content">
|
||||
<dl>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Software:" %}</dt>
|
||||
<dd>{{ server.application_type }}</dd>
|
||||
</div>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Version:" %}</dt>
|
||||
<dd>{{ server.application_version }}</dd>
|
||||
</div>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Status:" %}</dt>
|
||||
<dd>{{ server.get_status_display }}</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Software:" %}</dt>
|
||||
<dd>{{ server.application_type }}</dd>
|
||||
|
||||
<dt class="is-pulled-left mr-5">{% trans "Version:" %}</dt>
|
||||
<dd>{{ server.application_version }}</dd>
|
||||
|
||||
<dt class="is-pulled-left mr-5">{% trans "Status:" %}</dt>
|
||||
<dd>{{ server.get_status_display }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -39,38 +35,32 @@
|
|||
<h2 class="title is-4">{% trans "Activity" %}</h2>
|
||||
<div class="box is-flex-grow-1 content">
|
||||
<dl>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Users:" %}</dt>
|
||||
<dd>
|
||||
{{ users.count }}
|
||||
{% if server.user_set.count %}(<a href="{% url 'settings-users' %}?server={{ server.server_name }}">{% trans "View all" %}</a>){% endif %}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Reports:" %}</dt>
|
||||
<dd>
|
||||
{{ reports.count }}
|
||||
{% if reports.count %}(<a href="{% url 'settings-reports' %}?server={{ server.server_name }}">{% trans "View all" %}</a>){% endif %}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Followed by us:" %}</dt>
|
||||
<dd>
|
||||
{{ followed_by_us.count }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Followed by them:" %}</dt>
|
||||
<dd>
|
||||
{{ followed_by_them.count }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Blocked by us:" %}</dt>
|
||||
<dd>
|
||||
{{ blocked_by_us.count }}
|
||||
</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Users:" %}</dt>
|
||||
<dd>
|
||||
{{ users.count }}
|
||||
{% if server.user_set.count %}(<a href="{% url 'settings-users' %}?server={{ server.server_name }}">{% trans "View all" %}</a>){% endif %}
|
||||
</dd>
|
||||
|
||||
<dt class="is-pulled-left mr-5">{% trans "Reports:" %}</dt>
|
||||
<dd>
|
||||
{{ reports.count }}
|
||||
{% if reports.count %}(<a href="{% url 'settings-reports' %}?server={{ server.server_name }}">{% trans "View all" %}</a>){% endif %}
|
||||
</dd>
|
||||
|
||||
<dt class="is-pulled-left mr-5">{% trans "Followed by us:" %}</dt>
|
||||
<dd>
|
||||
{{ followed_by_us.count }}
|
||||
</dd>
|
||||
|
||||
<dt class="is-pulled-left mr-5">{% trans "Followed by them:" %}</dt>
|
||||
<dd>
|
||||
{{ followed_by_them.count }}
|
||||
</dd>
|
||||
|
||||
<dt class="is-pulled-left mr-5">{% trans "Blocked by us:" %}</dt>
|
||||
<dd>
|
||||
{{ blocked_by_us.count }}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -86,14 +76,13 @@
|
|||
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit_notes" %}
|
||||
</div>
|
||||
</header>
|
||||
{% if server.notes %}
|
||||
<div class="box" id="hide_edit_notes">{{ server.notes|to_markdown|safe }}</div>
|
||||
{% endif %}
|
||||
{% trans "<em>No notes</em>" as null_text %}
|
||||
<div class="box" id="hide_edit_notes">{{ server.notes|to_markdown|default:null_text|safe }}</div>
|
||||
<form class="box is-hidden" method="POST" action="{% url 'settings-federated-server' server.id %}" id="edit_notes">
|
||||
{% csrf_token %}
|
||||
<p>
|
||||
<label class="is-sr-only" for="id_notes">Notes:</label>
|
||||
<textarea name="notes" cols="None" rows="None" class="textarea" id="id_notes">{{ server.notes|default:"" }}</textarea>
|
||||
<textarea name="notes" cols="40" rows="5" class="textarea" id="id_notes">{{ server.notes|default:"" }}</textarea>
|
||||
</p>
|
||||
<button type="submit" class="button is-primary">{% trans "Save" %}</button>
|
||||
{% trans "Cancel" as button_text %}
|
|
@ -59,7 +59,11 @@
|
|||
<td>{{ server.get_status_display }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if not servers %}
|
||||
<tr><td colspan="5"><em>{% trans "No instances found" %}</em></td></tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
|
||||
{% include 'snippets/pagination.html' with page=servers path=request.path %}
|
||||
{% endblock %}
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'snippets/filters_panel/filters_panel.html' %}
|
||||
|
||||
{% block filter_fields %}
|
||||
{% include 'settings/status_filter.html' %}
|
||||
{% include 'settings/invites/status_filter.html' %}
|
||||
{% endblock %}
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
{% endif %} ({{ count }})
|
||||
</h2>
|
||||
|
||||
{% include 'settings/invite_request_filters.html' %}
|
||||
{% include 'settings/invites/invite_request_filters.html' %}
|
||||
|
||||
<table class="table is-striped is-fullwidth">
|
||||
{% url 'settings-invite-requests' as url %}
|
||||
|
@ -47,7 +47,7 @@
|
|||
<th>{% trans "Action" %}</th>
|
||||
</tr>
|
||||
{% if not requests %}
|
||||
<tr><td colspan="4">{% trans "No requests" %}</td></tr>
|
||||
<tr><td colspan="5"><em>{% trans "No requests" %}</em></td></tr>
|
||||
{% endif %}
|
||||
{% for req in requests %}
|
||||
<tr>
|
|
@ -12,7 +12,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
{% include 'settings/ip_address_form.html' with controls_text="add_address" class="block" %}
|
||||
{% include 'settings/ip_blocklist/ip_address_form.html' with controls_text="add_address" class="block" %}
|
||||
|
||||
<p class="notification block">
|
||||
{% trans "Any traffic from this IP address will get a 404 response when trying to access any part of the application." %}
|
||||
|
@ -42,6 +42,9 @@
|
|||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if not addresses.exists %}
|
||||
<tr><td colspan="2"><em>{% trans "No IP addresses currently blocked" %}</em></td></tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
|
@ -74,14 +74,7 @@
|
|||
<li>
|
||||
{% url 'settings-site' as url %}
|
||||
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Site Settings" %}</a>
|
||||
{% if url in request.path %}
|
||||
<ul class="emnu-list">
|
||||
<li><a href="{{ url }}#instance-info">{% trans "Instance Info" %}</a></li>
|
||||
<li><a href="{{ url }}#images">{% trans "Images" %}</a></li>
|
||||
<li><a href="{{ url }}#footer">{% trans "Footer Content" %}</a></li>
|
||||
<li><a href="{{ url }}#registration">{% trans "Registration" %}</a></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% block site-subtabs %}{% endblock %}
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
|
|
@ -3,20 +3,21 @@
|
|||
{% load humanize %}
|
||||
|
||||
{% block title %}{% blocktrans with report_id=report.id username=report.user.username %}Report #{{ report_id }}: {{ username }}{% endblocktrans %}{% endblock %}
|
||||
{% block header %}{% blocktrans with report_id=report.id username=report.user.username %}Report #{{ report_id }}: {{ username }}{% endblocktrans %}{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
{% blocktrans with report_id=report.id username=report.user.username %}Report #{{ report_id }}: {{ username }}{% endblocktrans %}
|
||||
<a href="{% url 'settings-reports' %}" class="has-text-weight-normal help">{% trans "Back to reports" %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
<div class="block">
|
||||
<a href="{% url 'settings-reports' %}">{% trans "Back to reports" %}</a>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
{% include 'moderation/report_preview.html' with report=report %}
|
||||
{% include 'settings/reports/report_preview.html' with report=report %}
|
||||
</div>
|
||||
|
||||
{% include 'user_admin/user_info.html' with user=report.user %}
|
||||
{% include 'settings/users/user_info.html' with user=report.user %}
|
||||
|
||||
{% include 'user_admin/user_moderation_actions.html' with user=report.user %}
|
||||
{% include 'settings/users/user_moderation_actions.html' with user=report.user %}
|
||||
|
||||
<div class="block">
|
||||
<h3 class="title is-4">{% trans "Moderator Comments" %}</h3>
|
|
@ -30,7 +30,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
{% include 'user_admin/user_admin_filters.html' %}
|
||||
{% include 'settings/users/user_admin_filters.html' %}
|
||||
|
||||
<div class="block">
|
||||
{% if not reports %}
|
||||
|
@ -39,7 +39,7 @@
|
|||
|
||||
{% for report in reports %}
|
||||
<div class="block">
|
||||
{% include 'moderation/report_preview.html' with report=report %}
|
||||
{% include 'settings/reports/report_preview.html' with report=report %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
|
@ -5,36 +5,46 @@
|
|||
|
||||
{% block header %}{% trans "Site Settings" %}{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
{% block site-subtabs %}
|
||||
<ul class="menu-list">
|
||||
<li><a href="#instance-info">{% trans "Instance Info" %}</a></li>
|
||||
<li><a href="#images">{% trans "Images" %}</a></li>
|
||||
<li><a href="#footer">{% trans "Footer Content" %}</a></li>
|
||||
<li><a href="#registration">{% trans "Registration" %}</a></li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
<form action="{% url 'settings-site' %}" method="POST" class="content" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<section class="block" id="instance_info">
|
||||
<h2 class="title is-4">{% trans "Instance Info" %}</h2>
|
||||
<div class="field">
|
||||
<label class="label" for="id_name">{% trans "Instance Name:" %}</label>
|
||||
{{ site_form.name }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_instance_tagline">{% trans "Tagline:" %}</label>
|
||||
{{ site_form.instance_tagline }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_instance_description">{% trans "Instance description:" %}</label>
|
||||
{{ site_form.instance_description }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label mb-0" for="id_short_description">{% trans "Short description:" %}</label>
|
||||
<p class="help">{% trans "Used when the instance is previewed on joinbookwyrm.com. Does not support html or markdown." %}</p>
|
||||
{{ site_form.instance_short_description }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_code_of_conduct">{% trans "Code of conduct:" %}</label>
|
||||
{{ site_form.code_of_conduct }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_privacy_policy">{% trans "Privacy Policy:" %}</label>
|
||||
{{ site_form.privacy_policy }}
|
||||
<div class="box">
|
||||
<div class="field">
|
||||
<label class="label" for="id_name">{% trans "Instance Name:" %}</label>
|
||||
{{ site_form.name }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_instance_tagline">{% trans "Tagline:" %}</label>
|
||||
{{ site_form.instance_tagline }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_instance_description">{% trans "Instance description:" %}</label>
|
||||
{{ site_form.instance_description }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label mb-0" for="id_short_description">{% trans "Short description:" %}</label>
|
||||
<p class="help">{% trans "Used when the instance is previewed on joinbookwyrm.com. Does not support html or markdown." %}</p>
|
||||
{{ site_form.instance_short_description }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_code_of_conduct">{% trans "Code of conduct:" %}</label>
|
||||
{{ site_form.code_of_conduct }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_privacy_policy">{% trans "Privacy Policy:" %}</label>
|
||||
{{ site_form.privacy_policy }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -42,16 +52,16 @@
|
|||
|
||||
<section class="block" id="images">
|
||||
<h2 class="title is-4">{% trans "Images" %}</h2>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="box is-flex">
|
||||
<div>
|
||||
<label class="label" for="id_logo">{% trans "Logo:" %}</label>
|
||||
{{ site_form.logo }}
|
||||
</div>
|
||||
<div class="column">
|
||||
<div>
|
||||
<label class="label" for="id_logo_small">{% trans "Logo small:" %}</label>
|
||||
{{ site_form.logo_small }}
|
||||
</div>
|
||||
<div class="column">
|
||||
<div>
|
||||
<label class="label" for="id_favicon">{% trans "Favicon:" %}</label>
|
||||
{{ site_form.favicon }}
|
||||
</div>
|
||||
|
@ -62,21 +72,23 @@
|
|||
|
||||
<section class="block" id="footer">
|
||||
<h2 class="title is-4">{% trans "Footer Content" %}</h2>
|
||||
<div class="field">
|
||||
<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 %}>
|
||||
</div>
|
||||
<div class="field">
|
||||
<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 %}>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_admin_email">{% trans "Admin email:" %}</label>
|
||||
{{ site_form.admin_email }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_footer_item">{% trans "Additional info:" %}</label>
|
||||
{{ site_form.footer_item }}
|
||||
<div class="box">
|
||||
<div class="field">
|
||||
<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 %}>
|
||||
</div>
|
||||
<div class="field">
|
||||
<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 %}>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_admin_email">{% trans "Admin email:" %}</label>
|
||||
{{ site_form.admin_email }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_footer_item">{% trans "Additional info:" %}</label>
|
||||
{{ site_form.footer_item }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -84,35 +96,37 @@
|
|||
|
||||
<section class="block" id="registration">
|
||||
<h2 class="title is-4">{% trans "Registration" %}</h2>
|
||||
<div class="field">
|
||||
<label class="label" for="id_allow_registration">
|
||||
{{ site_form.allow_registration }}
|
||||
{% trans "Allow registration" %}
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_allow_invite_requests">
|
||||
{{ site_form.allow_invite_requests }}
|
||||
{% trans "Allow invite requests" %}
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label mb-0" for="id_allow_invite_requests">
|
||||
{{ site_form.require_confirm_email }}
|
||||
{% trans "Require users to confirm email address" %}
|
||||
</label>
|
||||
<p class="help">{% trans "(Recommended if registration is open)" %}</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label>
|
||||
{{ site_form.registration_closed_text }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_invite_request_text">{% trans "Invite request text:" %}</label>
|
||||
{{ site_form.invite_request_text }}
|
||||
{% for error in site_form.invite_request_text.errors %}
|
||||
<p class="help is-danger">{{ error|escape }}</p>
|
||||
{% endfor %}
|
||||
<div class="box">
|
||||
<div class="field">
|
||||
<label class="label" for="id_allow_registration">
|
||||
{{ site_form.allow_registration }}
|
||||
{% trans "Allow registration" %}
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_allow_invite_requests">
|
||||
{{ site_form.allow_invite_requests }}
|
||||
{% trans "Allow invite requests" %}
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label mb-0" for="id_require_confirm_email">
|
||||
{{ site_form.require_confirm_email }}
|
||||
{% trans "Require users to confirm email address" %}
|
||||
</label>
|
||||
<p class="help">{% trans "(Recommended if registration is open)" %}</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label>
|
||||
{{ site_form.registration_closed_text }}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_invite_request_text">{% trans "Invite request text:" %}</label>
|
||||
{{ site_form.invite_request_text }}
|
||||
{% for error in site_form.invite_request_text.errors %}
|
||||
<p class="help is-danger">{{ error|escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
16
bookwyrm/templates/settings/users/user.html
Normal file
16
bookwyrm/templates/settings/users/user.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
{% extends 'settings/layout.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ user.username }}{% endblock %}
|
||||
{% block header %}
|
||||
{{ user.username }}
|
||||
<a class="help has-text-weight-normal" href="{% url 'settings-users' %}">{% trans "Back to users" %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
{% include 'settings/users/user_info.html' with user=user %}
|
||||
|
||||
{% include 'settings/users/user_moderation_actions.html' with user=user %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
{% block panel %}
|
||||
|
||||
{% include 'user_admin/user_admin_filters.html' %}
|
||||
{% include 'settings/users/user_admin_filters.html' %}
|
||||
|
||||
<table class="table is-striped">
|
||||
<tr>
|
|
@ -1,7 +1,7 @@
|
|||
{% extends 'snippets/filters_panel/filters_panel.html' %}
|
||||
|
||||
{% block filter_fields %}
|
||||
{% include 'user_admin/username_filter.html' %}
|
||||
{% include 'settings/users/username_filter.html' %}
|
||||
{% include 'directory/community_filter.html' %}
|
||||
{% include 'user_admin/server_filter.html' %}
|
||||
{% include 'settings/users/server_filter.html' %}
|
||||
{% endblock %}
|
|
@ -48,58 +48,42 @@
|
|||
<div class="box content is-flex-grow-1">
|
||||
<dl>
|
||||
{% if user.local %}
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Email:" %}</dt>
|
||||
<dd>{{ user.email }}</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Email:" %}</dt>
|
||||
<dd>{{ user.email }}</dd>
|
||||
{% endif %}
|
||||
|
||||
{% with report_count=user.report_set.count %}
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Reports:" %}</dt>
|
||||
<dd>
|
||||
{{ report_count|intcomma }}
|
||||
{% if report_count > 0 %}
|
||||
<a href="{% url 'settings-reports' %}?username={{ user.username }}">
|
||||
{% trans "(View reports)" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Reports:" %}</dt>
|
||||
<dd>
|
||||
{{ report_count|intcomma }}
|
||||
{% if report_count > 0 %}
|
||||
<a href="{% url 'settings-reports' %}?username={{ user.username }}">
|
||||
{% trans "(View reports)" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</dd>
|
||||
{% endwith %}
|
||||
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Blocked by count:" %}</dt>
|
||||
<dd>{{ user.blocked_by.count }}</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Blocked by count:" %}</dt>
|
||||
<dd>{{ user.blocked_by.count }}</dd>
|
||||
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Last active date:" %}</dt>
|
||||
<dd>{{ user.last_active_date }}</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Last active date:" %}</dt>
|
||||
<dd>{{ user.last_active_date }}</dd>
|
||||
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Manually approved followers:" %}</dt>
|
||||
<dd>{{ user.manually_approves_followers }}</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Manually approved followers:" %}</dt>
|
||||
<dd>{{ user.manually_approves_followers }}</dd>
|
||||
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Discoverable:" %}</dt>
|
||||
<dd>{{ user.discoverable }}</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Discoverable:" %}</dt>
|
||||
<dd>{{ user.discoverable }}</dd>
|
||||
|
||||
{% if not user.is_active %}
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Deactivation reason:" %}</dt>
|
||||
<dd>{{ user.deactivation_reason }}</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Deactivation reason:" %}</dt>
|
||||
<dd>{{ user.deactivation_reason }}</dd>
|
||||
{% endif %}
|
||||
|
||||
{% if not user.is_active and user.deactivation_reason == "pending" %}
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Confirmation code:" %}</dt>
|
||||
<dd>{{ user.confirmation_code }}</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Confirmation code:" %}</dt>
|
||||
<dd>{{ user.confirmation_code }}</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
</div>
|
||||
|
@ -113,18 +97,14 @@
|
|||
{% if server %}
|
||||
<h5>{{ server.server_name }}</h5>
|
||||
<dl>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Software:" %}</dt>
|
||||
<dd>{{ server.application_type }}</dd>
|
||||
</div>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Version:" %}</dt>
|
||||
<dd>{{ server.application_version }}</dd>
|
||||
</div>
|
||||
<div class="is-flex">
|
||||
<dt>{% trans "Status:" %}</dt>
|
||||
<dd>{{ server.status }}</dd>
|
||||
</div>
|
||||
<dt class="is-pulled-left mr-5">{% trans "Software:" %}</dt>
|
||||
<dd>{{ server.application_type }}</dd>
|
||||
|
||||
<dt class="is-pulled-left mr-5">{% trans "Version:" %}</dt>
|
||||
<dd>{{ server.application_version }}</dd>
|
||||
|
||||
<dt class="is-pulled-left mr-5">{% trans "Status:" %}</dt>
|
||||
<dd>{{ server.status }}</dd>
|
||||
</dl>
|
||||
{% if server.notes %}
|
||||
<h5>{% trans "Notes" %}</h5>
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
{% if user.local %}
|
||||
<div>
|
||||
{% include "user_admin/delete_user_form.html" with controls_text="delete_user" class="mt-2 mb-2" %}
|
||||
{% include "settings/users/delete_user_form.html" with controls_text="delete_user" class="mt-2 mb-2" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
13
bookwyrm/templates/shelf/create_shelf_form.html
Normal file
13
bookwyrm/templates/shelf/create_shelf_form.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends 'components/inline_form.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block header %}
|
||||
{% trans "Create Shelf" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block form %}
|
||||
<form name="create-shelf" action="{% url 'shelf-create' %}" method="post">
|
||||
{% include "shelf/form.html" with editable=shelf.editable form=create_form %}
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
13
bookwyrm/templates/shelf/edit_shelf_form.html
Normal file
13
bookwyrm/templates/shelf/edit_shelf_form.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends 'components/inline_form.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block header %}
|
||||
{% trans "Edit Shelf" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block form %}
|
||||
<form name="edit-shelf" action="{{ shelf.local_path }}" method="post">
|
||||
{% include "shelf/form.html" with editable=shelf.editable form=edit_form privacy=shelf.privacy %}
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
28
bookwyrm/templates/shelf/form.html
Normal file
28
bookwyrm/templates/shelf/form.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
{% load i18n %}
|
||||
{% load utilities %}
|
||||
{% with 0|uuid as uuid %}
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="user" value="{{ request.user.id }}">
|
||||
|
||||
{% if editable %}
|
||||
<div class="field">
|
||||
<label class="label" for="id_name">{% trans "Name:" %}</label>
|
||||
<input type="text" name="name" value="{{ form.name.value|default:'' }}" maxlength="100" class="input" required="" id="id_name">
|
||||
</div>
|
||||
{% else %}
|
||||
<input type="hidden" name="name" required="true" value="{{ shelf.name }}">
|
||||
{% endif %}
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="id_description_{{ uuid }}">{% trans "Description:" %}</label>
|
||||
<textarea name="description" cols="40" rows="5" maxlength="500" class="textarea" id="id_description_{{ uuid }}">{{ form.description.value|default:'' }}</textarea>
|
||||
</div>
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
{% include 'snippets/privacy_select.html' with current=privacy %}
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-primary" type="submit">{% trans "Save" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
|
@ -5,7 +5,7 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% include 'user/shelf/books_header.html' %}
|
||||
{% include 'user/books_header.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block opengraph_images %}
|
||||
|
@ -15,7 +15,7 @@
|
|||
{% block content %}
|
||||
<header class="block">
|
||||
<h1 class="title">
|
||||
{% include 'user/shelf/books_header.html' %}
|
||||
{% include 'user/books_header.html' %}
|
||||
</h1>
|
||||
</header>
|
||||
|
||||
|
@ -60,45 +60,62 @@
|
|||
</div>
|
||||
|
||||
<div class="block">
|
||||
{% include 'user/shelf/create_shelf_form.html' with controls_text='create_shelf_form' %}
|
||||
{% include 'shelf/create_shelf_form.html' with controls_text='create_shelf_form' %}
|
||||
</div>
|
||||
|
||||
<div class="block columns is-mobile">
|
||||
<div class="column">
|
||||
<h2 class="title is-3">
|
||||
{{ shelf.name }}
|
||||
<span class="subtitle">
|
||||
{% include 'snippets/privacy-icons.html' with item=shelf %}
|
||||
</span>
|
||||
{% with count=books.paginator.count %}
|
||||
{% if count %}
|
||||
<p class="help">
|
||||
{% blocktrans trimmed count counter=count with formatted_count=count|intcomma %}
|
||||
{{ formatted_count }} book
|
||||
{% plural %}
|
||||
{{ formatted_count }} books
|
||||
{% endblocktrans %}
|
||||
|
||||
{% if books.has_other_pages %}
|
||||
{% blocktrans trimmed with start=books.start_index end=books.end_index %}
|
||||
(showing {{ start }}-{{ end }})
|
||||
<div>
|
||||
<div class="block columns is-mobile">
|
||||
<div class="column">
|
||||
<h2 class="title is-3">
|
||||
{{ shelf.name }}
|
||||
<span class="subtitle">
|
||||
{% include 'snippets/privacy-icons.html' with item=shelf %}
|
||||
</span>
|
||||
{% with count=books.paginator.count %}
|
||||
{% if count %}
|
||||
<p class="help">
|
||||
{% blocktrans trimmed count counter=count with formatted_count=count|intcomma %}
|
||||
{{ formatted_count }} book
|
||||
{% plural %}
|
||||
{{ formatted_count }} books
|
||||
{% endblocktrans %}
|
||||
|
||||
{% if books.has_other_pages %}
|
||||
{% blocktrans trimmed with start=books.start_index end=books.end_index %}
|
||||
(showing {{ start }}-{{ end }})
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</h2>
|
||||
</div>
|
||||
{% if is_self and shelf.id %}
|
||||
<div class="column is-narrow">
|
||||
{% trans "Edit shelf" as button_text %}
|
||||
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit_shelf_form" focus="edit_shelf_form_header" %}
|
||||
{% endwith %}
|
||||
</h2>
|
||||
</div>
|
||||
{% if is_self and shelf.id %}
|
||||
<div class="column is-narrow">
|
||||
<div class="is-flex">
|
||||
{% trans "Edit shelf" as button_text %}
|
||||
{% include 'snippets/toggle/open_button.html' with text=button_text icon_with_text="pencil" controls_text="edit_shelf_form" focus="edit_shelf_form_header" %}
|
||||
|
||||
{% if shelf.deletable %}
|
||||
<form class="ml-1" name="delete-shelf" action="/delete-shelf/{{ shelf.id }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="user" value="{{ request.user.id }}">
|
||||
<button class="button is-danger is-light" type="submit">
|
||||
{% trans "Delete shelf" %}
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if shelf.description %}
|
||||
<p>{{ shelf.description }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
{% include 'user/shelf/edit_shelf_form.html' with controls_text="edit_shelf_form" %}
|
||||
{% include 'shelf/edit_shelf_form.html' with controls_text="edit_shelf_form" %}
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
|
@ -167,17 +184,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p>{% trans "This shelf is empty." %}</p>
|
||||
{% if shelf.id and shelf.editable %}
|
||||
<form name="delete-shelf" action="/delete-shelf/{{ shelf.id }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="user" value="{{ request.user.id }}">
|
||||
<button class="button is-danger is-light" type="submit">
|
||||
{% trans "Delete shelf" %}
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<p><em>{% trans "This shelf is empty." %}</em></p>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
|
@ -1,7 +1,7 @@
|
|||
{% load i18n %}
|
||||
{% load utilities %}
|
||||
<div class="select {{ class }}">
|
||||
{% with 0|uuid as uuid %}
|
||||
{% firstof uuid 0|uuid as uuid %}
|
||||
{% if not no_label %}
|
||||
<label class="is-sr-only" for="privacy_{{ uuid }}">{% trans "Post privacy" %}</label>
|
||||
{% endif %}
|
||||
|
@ -20,6 +20,5 @@
|
|||
{% trans "Private" %}
|
||||
</option>
|
||||
</select>
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
{% trans "Report" as button_text %}
|
||||
{% include 'snippets/toggle/toggle_button.html' with class="is-danger is-light is-small is-fullwidth" text=button_text controls_text="report" controls_uid=report_uuid focus="modal_title_report" disabled=is_current %}
|
||||
|
||||
{% include 'moderation/report_modal.html' with user=user reporter=request.user controls_text="report" controls_uid=report_uuid %}
|
||||
{% include 'snippets/report_modal.html' with user=user reporter=request.user controls_text="report" controls_uid=report_uuid %}
|
||||
|
||||
{% endwith %}
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
{% block nullstate %}
|
||||
<div>
|
||||
{% blocktrans with username=user.display_name %}{{ username }} has no followers{% endblocktrans %}
|
||||
<em>{% blocktrans with username=user.display_name %}{{ username }} has no followers{% endblocktrans %}</em>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
{% block nullstate %}
|
||||
<div>
|
||||
{% blocktrans with username=user.display_name %}{{ username }} isn't following any users{% endblocktrans %}
|
||||
<em>{% blocktrans with username=user.display_name %}{{ username }} isn't following any users{% endblocktrans %}</em>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
{% extends 'components/inline_form.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block header %}
|
||||
{% trans "Create Shelf" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block form %}
|
||||
<form name="create-shelf" action="{% url 'shelf-create' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="user" value="{{ request.user.id }}">
|
||||
<div class="field">
|
||||
<label class="label" for="id_name_create">{% trans "Name:" %}</label>
|
||||
<input type="text" name="name" maxlength="100" class="input" required="true" id="id_name_create">
|
||||
</div>
|
||||
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
{% include 'snippets/privacy_select.html' %}
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-primary" type="submit">{% trans "Create Shelf" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
{% extends 'components/inline_form.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block header %}
|
||||
{% trans "Edit Shelf" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block form %}
|
||||
<form name="edit-shelf" action="{{ shelf.local_path }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="user" value="{{ request.user.id }}">
|
||||
{% if shelf.editable %}
|
||||
<div class="field">
|
||||
<label class="label" for="id_name">{% trans "Name:" %}</label>
|
||||
<input type="text" name="name" maxlength="100" class="input" required="true" value="{{ shelf.name }}" id="id_name">
|
||||
</div>
|
||||
{% else %}
|
||||
<input type="hidden" name="name" required="true" value="{{ shelf.name }}">
|
||||
{% endif %}
|
||||
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
{% include 'snippets/privacy_select.html' with current=shelf.privacy %}
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-primary" type="submit">{% trans "Update shelf" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
{% if user.bookwyrm_user %}
|
||||
<div class="block">
|
||||
<h2 class="title">
|
||||
{% include 'user/shelf/books_header.html' %}
|
||||
{% include 'user/books_header.html' %}
|
||||
</h2>
|
||||
<div class="columns is-mobile scroll-x">
|
||||
{% for shelf in shelves %}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{% extends 'settings/layout.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ user.username }}{% endblock %}
|
||||
{% block header %}
|
||||
{{ user.username }}
|
||||
<p class="help has-text-weight-normal">
|
||||
<a href="{% url 'settings-users' %}">{% trans "Back to users" %}</a>
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
{% include 'user_admin/user_info.html' with user=user %}
|
||||
|
||||
{% include 'user_admin/user_moderation_actions.html' with user=user %}
|
||||
|
||||
{% endblock %}
|
||||
|
1
bookwyrm/tests/views/admin/__init__.py
Normal file
1
bookwyrm/tests/views/admin/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from . import *
|
|
@ -1,5 +1,6 @@
|
|||
""" test for app action functionality """
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
@ -34,5 +35,8 @@ class DashboardViews(TestCase):
|
|||
request.user.is_superuser = True
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
|
@ -1,5 +1,7 @@
|
|||
""" test for app action functionality """
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
@ -36,7 +38,10 @@ class EmailBlocklistViews(TestCase):
|
|||
result = view(request)
|
||||
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content, options={"drop-empty-elements": False})
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_blocklist_page_post(self):
|
||||
|
@ -49,7 +54,10 @@ class EmailBlocklistViews(TestCase):
|
|||
result = view(request)
|
||||
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content, options={"drop-empty-elements": False})
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
self.assertTrue(
|
|
@ -1,6 +1,8 @@
|
|||
""" test for app action functionality """
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
|
@ -46,10 +48,19 @@ class FederationViews(TestCase):
|
|||
request.user.is_superuser = True
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(
|
||||
html.content,
|
||||
options={
|
||||
"drop-empty-elements": False,
|
||||
"warn-proprietary-attributes": False,
|
||||
},
|
||||
)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_server_page(self):
|
||||
def test_instance_page(self):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
server = models.FederatedServer.objects.create(server_name="hi.there.com")
|
||||
view = views.FederatedServer.as_view()
|
||||
|
@ -59,7 +70,10 @@ class FederationViews(TestCase):
|
|||
|
||||
result = view(request, server.id)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content, options={"drop-empty-elements": False})
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_server_page_block(self):
|
||||
|
@ -148,7 +162,10 @@ class FederationViews(TestCase):
|
|||
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_add_view_post_create(self):
|
||||
|
@ -169,6 +186,7 @@ class FederationViews(TestCase):
|
|||
self.assertEqual(server.application_type, "coolsoft")
|
||||
self.assertEqual(server.status, "blocked")
|
||||
|
||||
# pylint: disable=consider-using-with
|
||||
def test_import_blocklist(self):
|
||||
"""load a json file with a list of servers to block"""
|
||||
server = models.FederatedServer.objects.create(server_name="hi.there.com")
|
||||
|
@ -180,7 +198,7 @@ class FederationViews(TestCase):
|
|||
{"instance": "hi.there.com", "url": "https://explanation.url"}, # existing
|
||||
{"a": "b"}, # invalid
|
||||
]
|
||||
json.dump(data, open("file.json", "w"))
|
||||
json.dump(data, open("file.json", "w")) # pylint: disable=unspecified-encoding
|
||||
|
||||
view = views.ImportServerBlocklist.as_view()
|
||||
request = self.factory.post(
|
44
bookwyrm/tests/views/admin/test_ip_blocklist.py
Normal file
44
bookwyrm/tests/views/admin/test_ip_blocklist.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
""" test for app action functionality """
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from bookwyrm import models, views
|
||||
|
||||
|
||||
class IPBlocklistViews(TestCase):
|
||||
"""every response to a get request, html or json"""
|
||||
|
||||
def setUp(self):
|
||||
"""we need basic test data and mocks"""
|
||||
self.factory = RequestFactory()
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
):
|
||||
self.local_user = models.User.objects.create_user(
|
||||
"mouse@local.com",
|
||||
"mouse@mouse.mouse",
|
||||
"password",
|
||||
local=True,
|
||||
localname="mouse",
|
||||
)
|
||||
|
||||
models.SiteSettings.objects.create()
|
||||
|
||||
def test_blocklist_page_get(self):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
view = views.IPBlocklist.as_view()
|
||||
request = self.factory.get("")
|
||||
request.user = self.local_user
|
||||
request.user.is_superuser = True
|
||||
|
||||
result = view(request)
|
||||
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content, options={"drop-empty-elements": False})
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
|
@ -1,6 +1,8 @@
|
|||
""" test for app action functionality """
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
@ -42,7 +44,16 @@ class ReportViews(TestCase):
|
|||
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(
|
||||
html.content,
|
||||
options={
|
||||
"drop-empty-elements": False,
|
||||
"warn-proprietary-attributes": False,
|
||||
},
|
||||
)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_reports_page_with_data(self):
|
||||
|
@ -55,7 +66,16 @@ class ReportViews(TestCase):
|
|||
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(
|
||||
html.content,
|
||||
options={
|
||||
"drop-empty-elements": False,
|
||||
"warn-proprietary-attributes": False,
|
||||
},
|
||||
)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_report_page(self):
|
||||
|
@ -69,7 +89,10 @@ class ReportViews(TestCase):
|
|||
result = view(request, report.id)
|
||||
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content, options={"drop-empty-elements": False})
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_report_comment(self):
|
|
@ -1,5 +1,7 @@
|
|||
""" test for app action functionality """
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.contrib.auth.models import Group
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
|
@ -34,7 +36,10 @@ class UserAdminViews(TestCase):
|
|||
request.user.is_superuser = True
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content, options={"drop-empty-elements": False})
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_user_admin_page(self):
|
||||
|
@ -47,7 +52,10 @@ class UserAdminViews(TestCase):
|
|||
result = view(request, self.local_user.id)
|
||||
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content, options={"drop-empty-elements": False})
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||
|
@ -69,7 +77,10 @@ class UserAdminViews(TestCase):
|
|||
result = view(request, self.local_user.id)
|
||||
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content, options={"drop-empty-elements": False})
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
|
||||
self.assertEqual(
|
||||
list(self.local_user.groups.values_list("name", flat=True)), ["editor"]
|
1
bookwyrm/tests/views/preferences/__init__.py
Normal file
1
bookwyrm/tests/views/preferences/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from . import *
|
|
@ -1,5 +1,7 @@
|
|||
""" test for app action functionality """
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
@ -44,7 +46,10 @@ class BlockViews(TestCase):
|
|||
request.user = self.local_user
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_block_post(self, _):
|
||||
|
@ -75,6 +80,6 @@ class BlockViews(TestCase):
|
|||
request.user = self.local_user
|
||||
|
||||
with patch("bookwyrm.activitystreams.add_user_statuses_task.delay"):
|
||||
views.block.unblock(request, self.remote_user.id)
|
||||
views.unblock(request, self.remote_user.id)
|
||||
|
||||
self.assertFalse(models.UserBlocks.objects.exists())
|
61
bookwyrm/tests/views/preferences/test_change_password.py
Normal file
61
bookwyrm/tests/views/preferences/test_change_password.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
""" test for app action functionality """
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from bookwyrm import models, views
|
||||
|
||||
|
||||
class ChangePasswordViews(TestCase):
|
||||
"""view user and edit profile"""
|
||||
|
||||
def setUp(self):
|
||||
"""we need basic test data and mocks"""
|
||||
self.factory = RequestFactory()
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
):
|
||||
self.local_user = models.User.objects.create_user(
|
||||
"mouse@local.com",
|
||||
"mouse@mouse.com",
|
||||
"password",
|
||||
local=True,
|
||||
localname="mouse",
|
||||
)
|
||||
models.SiteSettings.objects.create(id=1)
|
||||
|
||||
def test_password_change_get(self):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
view = views.ChangePassword.as_view()
|
||||
request = self.factory.get("")
|
||||
request.user = self.local_user
|
||||
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_password_change(self):
|
||||
"""change password"""
|
||||
view = views.ChangePassword.as_view()
|
||||
password_hash = self.local_user.password
|
||||
request = self.factory.post("", {"password": "hi", "confirm-password": "hi"})
|
||||
request.user = self.local_user
|
||||
with patch("bookwyrm.views.preferences.change_password.login"):
|
||||
view(request)
|
||||
self.assertNotEqual(self.local_user.password, password_hash)
|
||||
|
||||
def test_password_change_mismatch(self):
|
||||
"""change password"""
|
||||
view = views.ChangePassword.as_view()
|
||||
password_hash = self.local_user.password
|
||||
request = self.factory.post("", {"password": "hi", "confirm-password": "hihi"})
|
||||
request.user = self.local_user
|
||||
view(request)
|
||||
self.assertEqual(self.local_user.password, password_hash)
|
89
bookwyrm/tests/views/preferences/test_delete_user.py
Normal file
89
bookwyrm/tests/views/preferences/test_delete_user.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
""" test for app action functionality """
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.contrib.sessions.middleware import SessionMiddleware
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from bookwyrm import forms, models, views
|
||||
|
||||
|
||||
@patch("bookwyrm.suggested_users.remove_user_task.delay")
|
||||
class DeleteUserViews(TestCase):
|
||||
"""view user and edit profile"""
|
||||
|
||||
def setUp(self):
|
||||
"""we need basic test data and mocks"""
|
||||
self.factory = RequestFactory()
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
):
|
||||
self.local_user = models.User.objects.create_user(
|
||||
"mouse@local.com",
|
||||
"mouse@mouse.mouse",
|
||||
"password",
|
||||
local=True,
|
||||
localname="mouse",
|
||||
)
|
||||
self.rat = models.User.objects.create_user(
|
||||
"rat@local.com", "rat@rat.rat", "password", local=True, localname="rat"
|
||||
)
|
||||
|
||||
self.book = models.Edition.objects.create(
|
||||
title="test", parent_work=models.Work.objects.create(title="test work")
|
||||
)
|
||||
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.add_book_statuses_task.delay"
|
||||
):
|
||||
models.ShelfBook.objects.create(
|
||||
book=self.book,
|
||||
user=self.local_user,
|
||||
shelf=self.local_user.shelf_set.first(),
|
||||
)
|
||||
|
||||
models.SiteSettings.objects.create()
|
||||
|
||||
def test_delete_user_page(self, _):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
view = views.DeleteUser.as_view()
|
||||
request = self.factory.get("")
|
||||
request.user = self.local_user
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task")
|
||||
def test_delete_user(self, *_):
|
||||
"""use a form to update a user"""
|
||||
view = views.DeleteUser.as_view()
|
||||
form = forms.DeleteUserForm()
|
||||
form.data["password"] = "password"
|
||||
request = self.factory.post("", form.data)
|
||||
request.user = self.local_user
|
||||
middleware = SessionMiddleware()
|
||||
middleware.process_request(request)
|
||||
request.session.save()
|
||||
|
||||
self.assertIsNone(self.local_user.name)
|
||||
with patch(
|
||||
"bookwyrm.models.activitypub_mixin.broadcast_task.delay"
|
||||
) as delay_mock:
|
||||
view(request)
|
||||
self.assertEqual(delay_mock.call_count, 1)
|
||||
activity = json.loads(delay_mock.call_args[0][1])
|
||||
self.assertEqual(activity["type"], "Delete")
|
||||
self.assertEqual(activity["actor"], self.local_user.remote_id)
|
||||
self.assertEqual(
|
||||
activity["cc"][0], "https://www.w3.org/ns/activitystreams#Public"
|
||||
)
|
||||
|
||||
self.local_user.refresh_from_db()
|
||||
self.assertFalse(self.local_user.is_active)
|
||||
self.assertEqual(self.local_user.deactivation_reason, "self_deletion")
|
|
@ -1,11 +1,10 @@
|
|||
""" test for app action functionality """
|
||||
import json
|
||||
import pathlib
|
||||
from unittest.mock import patch
|
||||
from PIL import Image
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.contrib.sessions.middleware import SessionMiddleware
|
||||
from django.core.files.base import ContentFile
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.template.response import TemplateResponse
|
||||
|
@ -59,7 +58,10 @@ class EditUserViews(TestCase):
|
|||
request.user = self.local_user
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_edit_user(self, _):
|
||||
|
@ -91,8 +93,9 @@ class EditUserViews(TestCase):
|
|||
form.data["default_post_privacy"] = "public"
|
||||
form.data["preferred_timezone"] = "UTC"
|
||||
image_file = pathlib.Path(__file__).parent.joinpath(
|
||||
"../../static/images/no_cover.jpg"
|
||||
"../../../static/images/no_cover.jpg"
|
||||
)
|
||||
# pylint: disable=consider-using-with
|
||||
form.data["avatar"] = SimpleUploadedFile(
|
||||
image_file, open(image_file, "rb").read(), content_type="image/jpeg"
|
||||
)
|
||||
|
@ -113,50 +116,11 @@ class EditUserViews(TestCase):
|
|||
def test_crop_avatar(self, _):
|
||||
"""reduce that image size"""
|
||||
image_file = pathlib.Path(__file__).parent.joinpath(
|
||||
"../../static/images/no_cover.jpg"
|
||||
"../../../static/images/no_cover.jpg"
|
||||
)
|
||||
image = Image.open(image_file)
|
||||
|
||||
result = views.edit_user.crop_avatar(image)
|
||||
result = views.preferences.edit_user.crop_avatar(image)
|
||||
self.assertIsInstance(result, ContentFile)
|
||||
image_result = Image.open(result)
|
||||
self.assertEqual(image_result.size, (120, 120))
|
||||
|
||||
def test_delete_user_page(self, _):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
view = views.DeleteUser.as_view()
|
||||
request = self.factory.get("")
|
||||
request.user = self.local_user
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task")
|
||||
def test_delete_user(self, *_):
|
||||
"""use a form to update a user"""
|
||||
view = views.DeleteUser.as_view()
|
||||
form = forms.DeleteUserForm()
|
||||
form.data["password"] = "password"
|
||||
request = self.factory.post("", form.data)
|
||||
request.user = self.local_user
|
||||
middleware = SessionMiddleware()
|
||||
middleware.process_request(request)
|
||||
request.session.save()
|
||||
|
||||
self.assertIsNone(self.local_user.name)
|
||||
with patch(
|
||||
"bookwyrm.models.activitypub_mixin.broadcast_task.delay"
|
||||
) as delay_mock:
|
||||
view(request)
|
||||
self.assertEqual(delay_mock.call_count, 1)
|
||||
activity = json.loads(delay_mock.call_args[0][1])
|
||||
self.assertEqual(activity["type"], "Delete")
|
||||
self.assertEqual(activity["actor"], self.local_user.remote_id)
|
||||
self.assertEqual(
|
||||
activity["cc"][0], "https://www.w3.org/ns/activitystreams#Public"
|
||||
)
|
||||
|
||||
self.local_user.refresh_from_db()
|
||||
self.assertFalse(self.local_user.is_active)
|
||||
self.assertEqual(self.local_user.deactivation_reason, "self_deletion")
|
|
@ -283,6 +283,46 @@ class BookViews(TestCase):
|
|||
self.assertEqual(book.authors.first().name, "Sappho")
|
||||
self.assertEqual(book.authors.first(), book.parent_work.authors.first())
|
||||
|
||||
def _setup_cover_url(self):
|
||||
cover_url = "http://example.com"
|
||||
image_file = pathlib.Path(__file__).parent.joinpath(
|
||||
"../../static/images/default_avi.jpg"
|
||||
)
|
||||
image = Image.open(image_file)
|
||||
output = BytesIO()
|
||||
image.save(output, format=image.format)
|
||||
responses.add(
|
||||
responses.GET,
|
||||
cover_url,
|
||||
body=output.getvalue(),
|
||||
status=200,
|
||||
)
|
||||
return cover_url
|
||||
|
||||
@responses.activate
|
||||
def test_create_book_upload_cover_url(self):
|
||||
"""create an entirely new book and work with cover url"""
|
||||
self.assertFalse(self.book.cover)
|
||||
view = views.ConfirmEditBook.as_view()
|
||||
self.local_user.groups.add(self.group)
|
||||
cover_url = self._setup_cover_url()
|
||||
|
||||
form = forms.EditionForm()
|
||||
form.data["title"] = "New Title"
|
||||
form.data["last_edited_by"] = self.local_user.id
|
||||
form.data["cover-url"] = cover_url
|
||||
request = self.factory.post("", form.data)
|
||||
request.user = self.local_user
|
||||
|
||||
with patch(
|
||||
"bookwyrm.models.activitypub_mixin.broadcast_task.delay"
|
||||
) as delay_mock:
|
||||
views.upload_cover(request, self.book.id)
|
||||
self.assertEqual(delay_mock.call_count, 1)
|
||||
|
||||
self.book.refresh_from_db()
|
||||
self.assertTrue(self.book.cover)
|
||||
|
||||
def test_upload_cover_file(self):
|
||||
"""add a cover via file upload"""
|
||||
self.assertFalse(self.book.cover)
|
||||
|
@ -311,21 +351,8 @@ class BookViews(TestCase):
|
|||
def test_upload_cover_url(self):
|
||||
"""add a cover via url"""
|
||||
self.assertFalse(self.book.cover)
|
||||
image_file = pathlib.Path(__file__).parent.joinpath(
|
||||
"../../static/images/default_avi.jpg"
|
||||
)
|
||||
image = Image.open(image_file)
|
||||
output = BytesIO()
|
||||
image.save(output, format=image.format)
|
||||
responses.add(
|
||||
responses.GET,
|
||||
"http://example.com",
|
||||
body=output.getvalue(),
|
||||
status=200,
|
||||
)
|
||||
|
||||
form = forms.CoverForm(instance=self.book)
|
||||
form.data["cover-url"] = "http://example.com"
|
||||
form.data["cover-url"] = self._setup_cover_url()
|
||||
|
||||
request = self.factory.post("", form.data)
|
||||
request.user = self.local_user
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
""" test for app action functionality """
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.template.response import TemplateResponse
|
||||
|
@ -51,7 +52,16 @@ class DirectoryViews(TestCase):
|
|||
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(
|
||||
html.content,
|
||||
options={
|
||||
"drop-empty-elements": False,
|
||||
"warn-proprietary-attributes": False,
|
||||
},
|
||||
)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_directory_page_empty(self):
|
||||
|
@ -62,7 +72,10 @@ class DirectoryViews(TestCase):
|
|||
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(html.content, options={"drop-empty-elements": False})
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_directory_page_logged_out(self):
|
||||
|
|
|
@ -95,33 +95,3 @@ class PasswordViews(TestCase):
|
|||
resp = view(request, code.code)
|
||||
resp.render()
|
||||
self.assertTrue(models.PasswordReset.objects.exists())
|
||||
|
||||
def test_password_change_get(self):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
view = views.ChangePassword.as_view()
|
||||
request = self.factory.get("")
|
||||
request.user = self.local_user
|
||||
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_password_change(self):
|
||||
"""change password"""
|
||||
view = views.ChangePassword.as_view()
|
||||
password_hash = self.local_user.password
|
||||
request = self.factory.post("", {"password": "hi", "confirm-password": "hi"})
|
||||
request.user = self.local_user
|
||||
with patch("bookwyrm.views.password.login"):
|
||||
view(request)
|
||||
self.assertNotEqual(self.local_user.password, password_hash)
|
||||
|
||||
def test_password_change_mismatch(self):
|
||||
"""change password"""
|
||||
view = views.ChangePassword.as_view()
|
||||
password_hash = self.local_user.password
|
||||
request = self.factory.post("", {"password": "hi", "confirm-password": "hihi"})
|
||||
request.user = self.local_user
|
||||
view(request)
|
||||
self.assertEqual(self.local_user.password, password_hash)
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
""" test for app action functionality """
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from bookwyrm import models, views
|
||||
from bookwyrm import forms, models, views
|
||||
from bookwyrm.activitypub import ActivitypubResponse
|
||||
|
||||
|
||||
|
@ -53,7 +56,16 @@ class ShelfViews(TestCase):
|
|||
is_api.return_value = False
|
||||
result = view(request, self.local_user.username, shelf.identifier)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(
|
||||
html.content,
|
||||
options={
|
||||
"drop-empty-elements": False,
|
||||
"warn-proprietary-attributes": False,
|
||||
},
|
||||
)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
with patch("bookwyrm.views.shelf.is_api_request") as is_api:
|
||||
|
@ -122,7 +134,7 @@ class ShelfViews(TestCase):
|
|||
|
||||
self.assertEqual(shelf.name, "To Read")
|
||||
|
||||
def test_handle_shelve(self, *_):
|
||||
def test_shelve(self, *_):
|
||||
"""shelve a book"""
|
||||
request = self.factory.post(
|
||||
"", {"book": self.book.id, "shelf": self.shelf.identifier}
|
||||
|
@ -140,7 +152,7 @@ class ShelfViews(TestCase):
|
|||
# make sure the book is on the shelf
|
||||
self.assertEqual(self.shelf.books.get(), self.book)
|
||||
|
||||
def test_handle_shelve_to_read(self, *_):
|
||||
def test_shelve_to_read(self, *_):
|
||||
"""special behavior for the to-read shelf"""
|
||||
shelf = models.Shelf.objects.get(identifier="to-read")
|
||||
request = self.factory.post(
|
||||
|
@ -153,7 +165,7 @@ class ShelfViews(TestCase):
|
|||
# make sure the book is on the shelf
|
||||
self.assertEqual(shelf.books.get(), self.book)
|
||||
|
||||
def test_handle_shelve_reading(self, *_):
|
||||
def test_shelve_reading(self, *_):
|
||||
"""special behavior for the reading shelf"""
|
||||
shelf = models.Shelf.objects.get(identifier="reading")
|
||||
request = self.factory.post(
|
||||
|
@ -166,7 +178,7 @@ class ShelfViews(TestCase):
|
|||
# make sure the book is on the shelf
|
||||
self.assertEqual(shelf.books.get(), self.book)
|
||||
|
||||
def test_handle_shelve_read(self, *_):
|
||||
def test_shelve_read(self, *_):
|
||||
"""special behavior for the read shelf"""
|
||||
shelf = models.Shelf.objects.get(identifier="read")
|
||||
request = self.factory.post(
|
||||
|
@ -179,7 +191,7 @@ class ShelfViews(TestCase):
|
|||
# make sure the book is on the shelf
|
||||
self.assertEqual(shelf.books.get(), self.book)
|
||||
|
||||
def test_handle_unshelve(self, *_):
|
||||
def test_unshelve(self, *_):
|
||||
"""remove a book from a shelf"""
|
||||
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
|
||||
models.ShelfBook.objects.create(
|
||||
|
@ -197,3 +209,76 @@ class ShelfViews(TestCase):
|
|||
self.assertEqual(activity["type"], "Remove")
|
||||
self.assertEqual(activity["object"]["id"], item.remote_id)
|
||||
self.assertEqual(self.shelf.books.count(), 0)
|
||||
|
||||
def test_create_shelf(self, *_):
|
||||
"""a brand new custom shelf"""
|
||||
form = forms.ShelfForm()
|
||||
form.data["user"] = self.local_user.id
|
||||
form.data["name"] = "new shelf name"
|
||||
form.data["description"] = "desc"
|
||||
form.data["privacy"] = "unlisted"
|
||||
request = self.factory.post("", form.data)
|
||||
request.user = self.local_user
|
||||
|
||||
views.create_shelf(request)
|
||||
|
||||
shelf = models.Shelf.objects.get(name="new shelf name")
|
||||
self.assertEqual(shelf.privacy, "unlisted")
|
||||
self.assertEqual(shelf.description, "desc")
|
||||
self.assertEqual(shelf.user, self.local_user)
|
||||
|
||||
def test_delete_shelf(self, *_):
|
||||
"""delete a brand new custom shelf"""
|
||||
request = self.factory.post("")
|
||||
request.user = self.local_user
|
||||
shelf_id = self.shelf.id
|
||||
|
||||
views.delete_shelf(request, shelf_id)
|
||||
|
||||
self.assertFalse(models.Shelf.objects.filter(id=shelf_id).exists())
|
||||
|
||||
def test_delete_shelf_unauthorized(self, *_):
|
||||
"""delete a brand new custom shelf"""
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
):
|
||||
rat = models.User.objects.create_user(
|
||||
"rat@local.com",
|
||||
"rat@mouse.mouse",
|
||||
"password",
|
||||
local=True,
|
||||
localname="rat",
|
||||
)
|
||||
request = self.factory.post("")
|
||||
request.user = rat
|
||||
|
||||
with self.assertRaises(PermissionDenied):
|
||||
views.delete_shelf(request, self.shelf.id)
|
||||
|
||||
self.assertTrue(models.Shelf.objects.filter(id=self.shelf.id).exists())
|
||||
|
||||
def test_delete_shelf_has_book(self, *_):
|
||||
"""delete a brand new custom shelf"""
|
||||
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
|
||||
models.ShelfBook.objects.create(
|
||||
book=self.book, user=self.local_user, shelf=self.shelf
|
||||
)
|
||||
request = self.factory.post("")
|
||||
request.user = self.local_user
|
||||
|
||||
with self.assertRaises(PermissionDenied):
|
||||
views.delete_shelf(request, self.shelf.id)
|
||||
|
||||
self.assertTrue(models.Shelf.objects.filter(id=self.shelf.id).exists())
|
||||
|
||||
def test_delete_shelf_not_editable(self, *_):
|
||||
"""delete a brand new custom shelf"""
|
||||
shelf = self.local_user.shelf_set.first()
|
||||
self.assertFalse(shelf.editable)
|
||||
request = self.factory.post("")
|
||||
request.user = self.local_user
|
||||
|
||||
with self.assertRaises(PermissionDenied):
|
||||
views.delete_shelf(request, shelf.id)
|
||||
|
||||
self.assertTrue(models.Shelf.objects.filter(id=shelf.id).exists())
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
""" test for app action functionality """
|
||||
from unittest.mock import patch
|
||||
from tidylib import tidy_document
|
||||
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.http.response import Http404
|
||||
|
@ -55,7 +56,16 @@ class UserViews(TestCase):
|
|||
is_api.return_value = False
|
||||
result = view(request, "mouse")
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(
|
||||
html.content,
|
||||
options={
|
||||
"drop-empty-elements": False,
|
||||
"warn-proprietary-attributes": False,
|
||||
},
|
||||
)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
request.user = self.anonymous_user
|
||||
|
@ -63,7 +73,16 @@ class UserViews(TestCase):
|
|||
is_api.return_value = False
|
||||
result = view(request, "mouse")
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(
|
||||
html.content,
|
||||
options={
|
||||
"drop-empty-elements": False,
|
||||
"warn-proprietary-attributes": False,
|
||||
},
|
||||
)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
with patch("bookwyrm.views.user.is_api_request") as is_api:
|
||||
|
@ -92,7 +111,16 @@ class UserViews(TestCase):
|
|||
is_api.return_value = False
|
||||
result = view(request, "mouse")
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(
|
||||
html.content,
|
||||
options={
|
||||
"drop-empty-elements": False,
|
||||
"warn-proprietary-attributes": False,
|
||||
},
|
||||
)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
with patch("bookwyrm.views.user.is_api_request") as is_api:
|
||||
|
@ -123,7 +151,16 @@ class UserViews(TestCase):
|
|||
is_api.return_value = False
|
||||
result = view(request, "mouse")
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
result.render()
|
||||
html = result.render()
|
||||
_, errors = tidy_document(
|
||||
html.content,
|
||||
options={
|
||||
"drop-empty-elements": False,
|
||||
"warn-proprietary-attributes": False,
|
||||
},
|
||||
)
|
||||
if errors:
|
||||
raise Exception(errors)
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
with patch("bookwyrm.views.user.is_api_request") as is_api:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
""" make sure all our nice views are available """
|
||||
# site admin
|
||||
from .admin.announcements import Announcements, Announcement, delete_announcement
|
||||
from .admin.dashboard import Dashboard
|
||||
from .admin.federation import Federation, FederatedServer
|
||||
|
@ -19,13 +20,19 @@ from .admin.reports import (
|
|||
)
|
||||
from .admin.site import Site
|
||||
from .admin.user_admin import UserAdmin, UserAdminList
|
||||
|
||||
# user preferences
|
||||
from .preferences.change_password import ChangePassword
|
||||
from .preferences.edit_user import EditUser
|
||||
from .preferences.delete_user import DeleteUser
|
||||
from .preferences.block import Block, unblock
|
||||
|
||||
# misc views
|
||||
from .author import Author, EditAuthor
|
||||
from .block import Block, unblock
|
||||
from .books import Book, EditBook, ConfirmEditBook
|
||||
from .books import upload_cover, add_description, resolve_book
|
||||
from .directory import Directory
|
||||
from .discover import Discover
|
||||
from .edit_user import EditUser, DeleteUser
|
||||
from .editions import Editions, switch_edition
|
||||
from .feed import DirectMessage, Feed, Replies, Status
|
||||
from .follow import follow, unfollow
|
||||
|
@ -47,7 +54,7 @@ from .reading import delete_readthrough, delete_progressupdate
|
|||
from .reading import ReadingStatus
|
||||
from .register import Register, ConfirmEmail, ConfirmEmailCode, resend_link
|
||||
from .rss_feed import RssFeed
|
||||
from .password import PasswordResetRequest, PasswordReset, ChangePassword
|
||||
from .password import PasswordResetRequest, PasswordReset
|
||||
from .search import Search
|
||||
from .shelf import Shelf
|
||||
from .shelf import create_shelf, delete_shelf
|
||||
|
|
|
@ -41,7 +41,9 @@ class Announcements(View):
|
|||
"form": forms.AnnouncementForm(),
|
||||
"sort": sort,
|
||||
}
|
||||
return TemplateResponse(request, "settings/announcements.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/announcements/announcements.html", data
|
||||
)
|
||||
|
||||
def post(self, request):
|
||||
"""edit the site settings"""
|
||||
|
@ -56,7 +58,9 @@ class Announcements(View):
|
|||
).get_page(request.GET.get("page")),
|
||||
"form": form,
|
||||
}
|
||||
return TemplateResponse(request, "settings/announcements.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/announcements/announcements.html", data
|
||||
)
|
||||
|
||||
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
|
@ -74,7 +78,9 @@ class Announcement(View):
|
|||
"announcement": announcement,
|
||||
"form": forms.AnnouncementForm(instance=announcement),
|
||||
}
|
||||
return TemplateResponse(request, "settings/announcement.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/announcements/announcement.html", data
|
||||
)
|
||||
|
||||
def post(self, request, announcement_id):
|
||||
"""edit announcement"""
|
||||
|
@ -87,7 +93,9 @@ class Announcement(View):
|
|||
"announcement": announcement,
|
||||
"form": form,
|
||||
}
|
||||
return TemplateResponse(request, "settings/announcement.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/announcements/announcement.html", data
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
|
|
|
@ -85,4 +85,4 @@ class Dashboard(View):
|
|||
"user_stats": user_stats,
|
||||
"status_stats": status_stats,
|
||||
}
|
||||
return TemplateResponse(request, "settings/dashboard.html", data)
|
||||
return TemplateResponse(request, "settings/dashboard/dashboard.html", data)
|
||||
|
|
|
@ -22,7 +22,9 @@ class EmailBlocklist(View):
|
|||
"domains": models.EmailBlocklist.objects.order_by("-created_date").all(),
|
||||
"form": forms.EmailBlocklistForm(),
|
||||
}
|
||||
return TemplateResponse(request, "settings/email_blocklist.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/email_blocklist/email_blocklist.html", data
|
||||
)
|
||||
|
||||
def post(self, request, domain_id=None):
|
||||
"""create a new domain block"""
|
||||
|
@ -35,11 +37,15 @@ class EmailBlocklist(View):
|
|||
"form": form,
|
||||
}
|
||||
if not form.is_valid():
|
||||
return TemplateResponse(request, "settings/email_blocklist.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/email_blocklist/email_blocklist.html", data
|
||||
)
|
||||
form.save()
|
||||
|
||||
data["form"] = forms.EmailBlocklistForm()
|
||||
return TemplateResponse(request, "settings/email_blocklist.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/email_blocklist/email_blocklist.html", data
|
||||
)
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def delete(self, request, domain_id):
|
||||
|
|
|
@ -44,7 +44,7 @@ class Federation(View):
|
|||
"sort": sort,
|
||||
"form": forms.ServerForm(),
|
||||
}
|
||||
return TemplateResponse(request, "settings/federation.html", data)
|
||||
return TemplateResponse(request, "settings/federation/instance_list.html", data)
|
||||
|
||||
|
||||
class AddFederatedServer(View):
|
||||
|
@ -53,14 +53,16 @@ class AddFederatedServer(View):
|
|||
def get(self, request):
|
||||
"""add server form"""
|
||||
data = {"form": forms.ServerForm()}
|
||||
return TemplateResponse(request, "settings/edit_server.html", data)
|
||||
return TemplateResponse(request, "settings/federation/edit_instance.html", data)
|
||||
|
||||
def post(self, request):
|
||||
"""add a server from the admin panel"""
|
||||
form = forms.ServerForm(request.POST)
|
||||
if not form.is_valid():
|
||||
data = {"form": form}
|
||||
return TemplateResponse(request, "settings/edit_server.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/federation/edit_instance.html", data
|
||||
)
|
||||
server = form.save()
|
||||
return redirect("settings-federated-server", server.id)
|
||||
|
||||
|
@ -75,7 +77,7 @@ class ImportServerBlocklist(View):
|
|||
|
||||
def get(self, request):
|
||||
"""add server form"""
|
||||
return TemplateResponse(request, "settings/server_blocklist.html")
|
||||
return TemplateResponse(request, "settings/federation/instance_blocklist.html")
|
||||
|
||||
def post(self, request):
|
||||
"""add a server from the admin panel"""
|
||||
|
@ -98,7 +100,9 @@ class ImportServerBlocklist(View):
|
|||
server.block()
|
||||
success_count += 1
|
||||
data = {"failed": failed, "succeeded": success_count}
|
||||
return TemplateResponse(request, "settings/server_blocklist.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/federation/instance_blocklist.html", data
|
||||
)
|
||||
|
||||
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
|
@ -123,7 +127,7 @@ class FederatedServer(View):
|
|||
user_subject__in=users.all()
|
||||
),
|
||||
}
|
||||
return TemplateResponse(request, "settings/federated_server.html", data)
|
||||
return TemplateResponse(request, "settings/federation/instance.html", data)
|
||||
|
||||
def post(self, request, server): # pylint: disable=unused-argument
|
||||
"""update note"""
|
||||
|
|
|
@ -45,7 +45,7 @@ class ManageInvites(View):
|
|||
),
|
||||
"form": forms.CreateInviteForm(),
|
||||
}
|
||||
return TemplateResponse(request, "settings/manage_invites.html", data)
|
||||
return TemplateResponse(request, "settings/invites/manage_invites.html", data)
|
||||
|
||||
def post(self, request):
|
||||
"""creates an invite database entry"""
|
||||
|
@ -64,7 +64,7 @@ class ManageInvites(View):
|
|||
PAGE_LENGTH,
|
||||
)
|
||||
data = {"invites": paginated.page(1), "form": form}
|
||||
return TemplateResponse(request, "settings/manage_invites.html", data)
|
||||
return TemplateResponse(request, "settings/invites/manage_invites.html", data)
|
||||
|
||||
|
||||
class Invite(View):
|
||||
|
@ -135,7 +135,9 @@ class ManageInviteRequests(View):
|
|||
),
|
||||
"sort": sort,
|
||||
}
|
||||
return TemplateResponse(request, "settings/manage_invite_requests.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/invites/manage_invite_requests.html", data
|
||||
)
|
||||
|
||||
def post(self, request):
|
||||
"""send out an invite"""
|
||||
|
|
|
@ -22,7 +22,9 @@ class IPBlocklist(View):
|
|||
"addresses": models.IPBlocklist.objects.all(),
|
||||
"form": forms.IPBlocklistForm(),
|
||||
}
|
||||
return TemplateResponse(request, "settings/ip_blocklist.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/ip_blocklist/ip_blocklist.html", data
|
||||
)
|
||||
|
||||
def post(self, request, block_id=None):
|
||||
"""create a new ip address block"""
|
||||
|
@ -35,11 +37,15 @@ class IPBlocklist(View):
|
|||
"form": form,
|
||||
}
|
||||
if not form.is_valid():
|
||||
return TemplateResponse(request, "settings/ip_blocklist.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/ip_blocklist/ip_blocklist.html", data
|
||||
)
|
||||
form.save()
|
||||
|
||||
data["form"] = forms.IPBlocklistForm()
|
||||
return TemplateResponse(request, "settings/ip_blocklist.html", data)
|
||||
return TemplateResponse(
|
||||
request, "settings/ip_blocklist/ip_blocklist.html", data
|
||||
)
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def delete(self, request, domain_id):
|
||||
|
|
|
@ -40,7 +40,7 @@ class Reports(View):
|
|||
"server": server,
|
||||
"reports": models.Report.objects.filter(**filters),
|
||||
}
|
||||
return TemplateResponse(request, "moderation/reports.html", data)
|
||||
return TemplateResponse(request, "settings/reports/reports.html", data)
|
||||
|
||||
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
|
@ -60,7 +60,7 @@ class Report(View):
|
|||
data = {
|
||||
"report": get_object_or_404(models.Report, id=report_id),
|
||||
}
|
||||
return TemplateResponse(request, "moderation/report.html", data)
|
||||
return TemplateResponse(request, "settings/reports/report.html", data)
|
||||
|
||||
def post(self, request, report_id):
|
||||
"""comment on a report"""
|
||||
|
|
|
@ -57,7 +57,7 @@ class UserAdminList(View):
|
|||
"sort": sort,
|
||||
"server": server,
|
||||
}
|
||||
return TemplateResponse(request, "user_admin/user_admin.html", data)
|
||||
return TemplateResponse(request, "settings/users/user_admin.html", data)
|
||||
|
||||
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
|
@ -72,7 +72,7 @@ class UserAdmin(View):
|
|||
"""user view"""
|
||||
user = get_object_or_404(models.User, id=user)
|
||||
data = {"user": user, "group_form": forms.UserGroupForm()}
|
||||
return TemplateResponse(request, "user_admin/user.html", data)
|
||||
return TemplateResponse(request, "settings/users/user.html", data)
|
||||
|
||||
def post(self, request, user):
|
||||
"""update user group"""
|
||||
|
@ -81,4 +81,4 @@ class UserAdmin(View):
|
|||
if form.is_valid():
|
||||
form.save()
|
||||
data = {"user": user, "group_form": form}
|
||||
return TemplateResponse(request, "user_admin/user.html", data)
|
||||
return TemplateResponse(request, "settings/users/user.html", data)
|
||||
|
|
|
@ -191,6 +191,8 @@ class EditBook(View):
|
|||
data["confirm_mode"] = True
|
||||
# this isn't preserved because it isn't part of the form obj
|
||||
data["remove_authors"] = request.POST.getlist("remove_authors")
|
||||
data["cover_url"] = request.POST.get("cover-url")
|
||||
|
||||
# make sure the dates are passed in as datetime, they're currently a string
|
||||
# QueryDicts are immutable, we need to copy
|
||||
formcopy = data["form"].data.copy()
|
||||
|
@ -267,12 +269,20 @@ class ConfirmEditBook(View):
|
|||
work = models.Work.objects.create(title=form.cleaned_data["title"])
|
||||
work.authors.set(book.authors.all())
|
||||
book.parent_work = work
|
||||
# we don't tell the world when creating a book
|
||||
book.save(broadcast=False)
|
||||
|
||||
for author_id in request.POST.getlist("remove_authors"):
|
||||
book.authors.remove(author_id)
|
||||
|
||||
# import cover, if requested
|
||||
url = request.POST.get("cover-url")
|
||||
if url:
|
||||
image = set_cover_from_url(url)
|
||||
if image:
|
||||
book.cover.save(*image, save=False)
|
||||
|
||||
# we don't tell the world when creating a book
|
||||
book.save(broadcast=False)
|
||||
|
||||
return redirect(f"/book/{book.id}")
|
||||
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ class Directory(View):
|
|||
|
||||
users = suggested_users.get_annotated_users(request.user, **filters)
|
||||
sort = request.GET.get("sort")
|
||||
if sort == "recent":
|
||||
users = users.order_by("-last_active_date")
|
||||
else:
|
||||
if sort == "suggested":
|
||||
users = users.order_by("-mutuals", "-last_active_date")
|
||||
else:
|
||||
users = users.order_by("-last_active_date")
|
||||
|
||||
paginated = Paginator(users, 12)
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ from django.views import View
|
|||
from bookwyrm import forms, models
|
||||
from bookwyrm.connectors import connector_manager
|
||||
from bookwyrm.suggested_users import suggested_users
|
||||
from .edit_user import save_user_form
|
||||
from .preferences.edit_user import save_user_form
|
||||
|
||||
|
||||
# pylint: disable= no-self-use
|
||||
|
|
|
@ -41,7 +41,7 @@ class Goal(View):
|
|||
"year": year,
|
||||
"is_self": request.user == user,
|
||||
}
|
||||
return TemplateResponse(request, "goal.html", data)
|
||||
return TemplateResponse(request, "user/goal.html", data)
|
||||
|
||||
def post(self, request, username, year):
|
||||
"""update or create an annual goal"""
|
||||
|
@ -58,7 +58,7 @@ class Goal(View):
|
|||
"goal": goal,
|
||||
"year": year,
|
||||
}
|
||||
return TemplateResponse(request, "goal.html", data)
|
||||
return TemplateResponse(request, "user/goal.html", data)
|
||||
goal = form.save()
|
||||
|
||||
if request.POST.get("post-status"):
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
""" class views for password management """
|
||||
from django.contrib.auth import login
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.shortcuts import redirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views import View
|
||||
|
||||
|
@ -82,26 +80,3 @@ class PasswordReset(View):
|
|||
login(request, user)
|
||||
reset_code.delete()
|
||||
return redirect("/")
|
||||
|
||||
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
class ChangePassword(View):
|
||||
"""change password as logged in user"""
|
||||
|
||||
def get(self, request):
|
||||
"""change password page"""
|
||||
data = {"user": request.user}
|
||||
return TemplateResponse(request, "preferences/change_password.html", data)
|
||||
|
||||
def post(self, request):
|
||||
"""allow a user to change their password"""
|
||||
new_password = request.POST.get("password")
|
||||
confirm_password = request.POST.get("confirm-password")
|
||||
|
||||
if new_password != confirm_password:
|
||||
return redirect("prefs-password")
|
||||
|
||||
request.user.set_password(new_password)
|
||||
request.user.save(broadcast=False, update_fields=["password"])
|
||||
login(request, request.user)
|
||||
return redirect("user-feed", request.user.localname)
|
||||
|
|
0
bookwyrm/views/preferences/__init__.py
Normal file
0
bookwyrm/views/preferences/__init__.py
Normal file
31
bookwyrm/views/preferences/change_password.py
Normal file
31
bookwyrm/views/preferences/change_password.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
""" class views for password management """
|
||||
from django.contrib.auth import login
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
|
||||
|
||||
# pylint: disable= no-self-use
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
class ChangePassword(View):
|
||||
"""change password as logged in user"""
|
||||
|
||||
def get(self, request):
|
||||
"""change password page"""
|
||||
data = {"user": request.user}
|
||||
return TemplateResponse(request, "preferences/change_password.html", data)
|
||||
|
||||
def post(self, request):
|
||||
"""allow a user to change their password"""
|
||||
new_password = request.POST.get("password")
|
||||
confirm_password = request.POST.get("confirm-password")
|
||||
|
||||
if new_password != confirm_password:
|
||||
return redirect("prefs-password")
|
||||
|
||||
request.user.set_password(new_password)
|
||||
request.user.save(broadcast=False, update_fields=["password"])
|
||||
login(request, request.user)
|
||||
return redirect("user-feed", request.user.localname)
|
38
bookwyrm/views/preferences/delete_user.py
Normal file
38
bookwyrm/views/preferences/delete_user.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
""" edit your own account """
|
||||
from django.contrib.auth import logout
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
|
||||
from bookwyrm import forms, models
|
||||
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
class DeleteUser(View):
|
||||
"""delete user view"""
|
||||
|
||||
def get(self, request):
|
||||
"""delete page for a user"""
|
||||
data = {
|
||||
"form": forms.DeleteUserForm(),
|
||||
"user": request.user,
|
||||
}
|
||||
return TemplateResponse(request, "preferences/delete_user.html", data)
|
||||
|
||||
def post(self, request):
|
||||
"""les get fancy with images"""
|
||||
form = forms.DeleteUserForm(request.POST, instance=request.user)
|
||||
# idk why but I couldn't get check_password to work on request.user
|
||||
user = models.User.objects.get(id=request.user.id)
|
||||
if form.is_valid() and user.check_password(form.cleaned_data["password"]):
|
||||
user.deactivation_reason = "self_deletion"
|
||||
user.delete()
|
||||
logout(request)
|
||||
return redirect("/")
|
||||
|
||||
form.errors["password"] = ["Invalid password"]
|
||||
data = {"form": form, "user": request.user}
|
||||
return TemplateResponse(request, "preferences/delete_user.html", data)
|
|
@ -1,9 +1,8 @@
|
|||
""" edit or delete ones own account"""
|
||||
""" edit your own account """
|
||||
from io import BytesIO
|
||||
from uuid import uuid4
|
||||
from PIL import Image
|
||||
|
||||
from django.contrib.auth import logout
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.files.base import ContentFile
|
||||
from django.shortcuts import redirect
|
||||
|
@ -11,7 +10,7 @@ from django.template.response import TemplateResponse
|
|||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
|
||||
from bookwyrm import forms, models
|
||||
from bookwyrm import forms
|
||||
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
|
@ -39,35 +38,6 @@ class EditUser(View):
|
|||
return redirect("user-feed", request.user.localname)
|
||||
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
class DeleteUser(View):
|
||||
"""delete user view"""
|
||||
|
||||
def get(self, request):
|
||||
"""delete page for a user"""
|
||||
data = {
|
||||
"form": forms.DeleteUserForm(),
|
||||
"user": request.user,
|
||||
}
|
||||
return TemplateResponse(request, "preferences/delete_user.html", data)
|
||||
|
||||
def post(self, request):
|
||||
"""les get fancy with images"""
|
||||
form = forms.DeleteUserForm(request.POST, instance=request.user)
|
||||
# idk why but I couldn't get check_password to work on request.user
|
||||
user = models.User.objects.get(id=request.user.id)
|
||||
if form.is_valid() and user.check_password(form.cleaned_data["password"]):
|
||||
user.deactivation_reason = "self_deletion"
|
||||
user.delete()
|
||||
logout(request)
|
||||
return redirect("/")
|
||||
|
||||
form.errors["password"] = ["Invalid password"]
|
||||
data = {"form": form, "user": request.user}
|
||||
return TemplateResponse(request, "preferences/delete_user.html", data)
|
||||
|
||||
|
||||
def save_user_form(form):
|
||||
"""special handling for the user form"""
|
||||
user = form.save(commit=False)
|
|
@ -85,12 +85,14 @@ class Shelf(View):
|
|||
"shelves": shelves,
|
||||
"shelf": shelf,
|
||||
"books": page,
|
||||
"edit_form": forms.ShelfForm(instance=shelf if shelf_identifier else None),
|
||||
"create_form": forms.ShelfForm(),
|
||||
"page_range": paginated.get_elided_page_range(
|
||||
page.number, on_each_side=2, on_ends=1
|
||||
),
|
||||
}
|
||||
|
||||
return TemplateResponse(request, "user/shelf/shelf.html", data)
|
||||
return TemplateResponse(request, "shelf/shelf.html", data)
|
||||
|
||||
@method_decorator(login_required, name="dispatch")
|
||||
# pylint: disable=unused-argument
|
||||
|
@ -128,7 +130,7 @@ def create_shelf(request):
|
|||
def delete_shelf(request, shelf_id):
|
||||
"""user generated shelves"""
|
||||
shelf = get_object_or_404(models.Shelf, id=shelf_id)
|
||||
shelf.raise_not_deletable()
|
||||
shelf.raise_not_deletable(request.user)
|
||||
|
||||
shelf.delete()
|
||||
return redirect("user-shelves", request.user.localname)
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-20 19:44+0000\n"
|
||||
"POT-Creation-Date: 2021-09-28 18:31+0000\n"
|
||||
"PO-Revision-Date: 2021-03-02 17:19-0800\n"
|
||||
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
|
||||
"Language-Team: English <LL@li.org>\n"
|
||||
|
@ -18,67 +18,68 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: bookwyrm/forms.py:242
|
||||
#: bookwyrm/forms.py:241
|
||||
#, fuzzy
|
||||
#| msgid "A user with that username already exists."
|
||||
msgid "A user with this email already exists."
|
||||
msgstr "Dieser Benutzename ist bereits vergeben."
|
||||
|
||||
#: bookwyrm/forms.py:256
|
||||
#: bookwyrm/forms.py:255
|
||||
msgid "One Day"
|
||||
msgstr "Ein Tag"
|
||||
|
||||
#: bookwyrm/forms.py:257
|
||||
#: bookwyrm/forms.py:256
|
||||
msgid "One Week"
|
||||
msgstr "Eine Woche"
|
||||
|
||||
#: bookwyrm/forms.py:258
|
||||
#: bookwyrm/forms.py:257
|
||||
msgid "One Month"
|
||||
msgstr "Ein Monat"
|
||||
|
||||
#: bookwyrm/forms.py:259
|
||||
#: bookwyrm/forms.py:258
|
||||
msgid "Does Not Expire"
|
||||
msgstr "Läuft nicht aus"
|
||||
|
||||
#: bookwyrm/forms.py:264
|
||||
#, python-format
|
||||
msgid "%(count)d uses"
|
||||
msgstr "%(count)d Benutzungen"
|
||||
#: bookwyrm/forms.py:262
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Max uses"
|
||||
msgid "{i} uses"
|
||||
msgstr "Maximale Benutzungen"
|
||||
|
||||
#: bookwyrm/forms.py:267
|
||||
#: bookwyrm/forms.py:263
|
||||
#, fuzzy
|
||||
#| msgid "Unlisted"
|
||||
msgid "Unlimited"
|
||||
msgstr "Ungelistet"
|
||||
|
||||
#: bookwyrm/forms.py:329
|
||||
#: bookwyrm/forms.py:325
|
||||
msgid "List Order"
|
||||
msgstr "Reihenfolge der Liste"
|
||||
|
||||
#: bookwyrm/forms.py:330
|
||||
#: bookwyrm/forms.py:326
|
||||
#, fuzzy
|
||||
#| msgid "Title"
|
||||
msgid "Book Title"
|
||||
msgstr "Titel"
|
||||
|
||||
#: bookwyrm/forms.py:331
|
||||
#: bookwyrm/forms.py:327
|
||||
#: bookwyrm/templates/snippets/create_status/review.html:33
|
||||
#: bookwyrm/templates/user/shelf/shelf.html:117
|
||||
#: bookwyrm/templates/user/shelf/shelf.html:148
|
||||
msgid "Rating"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:333 bookwyrm/templates/lists/list.html:107
|
||||
#: bookwyrm/forms.py:329 bookwyrm/templates/lists/list.html:109
|
||||
msgid "Sort By"
|
||||
msgstr "Sortieren nach"
|
||||
|
||||
#: bookwyrm/forms.py:337
|
||||
#: bookwyrm/forms.py:333
|
||||
#, fuzzy
|
||||
#| msgid "Started reading"
|
||||
msgid "Ascending"
|
||||
msgstr "Zu lesen angefangen"
|
||||
|
||||
#: bookwyrm/forms.py:338
|
||||
#: bookwyrm/forms.py:334
|
||||
#, fuzzy
|
||||
#| msgid "Started reading"
|
||||
msgid "Descending"
|
||||
|
@ -92,29 +93,29 @@ msgstr ""
|
|||
msgid "Could not find a match for book"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/base_model.py:13
|
||||
#: bookwyrm/models/base_model.py:16
|
||||
#, fuzzy
|
||||
#| msgid "Started reading"
|
||||
msgid "Pending"
|
||||
msgstr "Zu lesen angefangen"
|
||||
|
||||
#: bookwyrm/models/base_model.py:14
|
||||
#: bookwyrm/models/base_model.py:17
|
||||
msgid "Self deletion"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/base_model.py:15
|
||||
#: bookwyrm/models/base_model.py:18
|
||||
#, fuzzy
|
||||
#| msgid "Moderator Comments"
|
||||
msgid "Moderator suspension"
|
||||
msgstr "Moderator:innenkommentare"
|
||||
|
||||
#: bookwyrm/models/base_model.py:16
|
||||
#: bookwyrm/models/base_model.py:19
|
||||
#, fuzzy
|
||||
#| msgid "List curation:"
|
||||
msgid "Moderator deletion"
|
||||
msgstr "Listenkuratierung:"
|
||||
|
||||
#: bookwyrm/models/base_model.py:17
|
||||
#: bookwyrm/models/base_model.py:20
|
||||
msgid "Domain block"
|
||||
msgstr ""
|
||||
|
||||
|
@ -143,7 +144,7 @@ msgstr "%(value)s ist keine gültige remote_id"
|
|||
msgid "%(value)s is not a valid username"
|
||||
msgstr "%(value)s ist kein gültiger Username"
|
||||
|
||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:169
|
||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171
|
||||
msgid "username"
|
||||
msgstr "Username"
|
||||
|
||||
|
@ -353,7 +354,7 @@ msgstr ""
|
|||
#: bookwyrm/templates/book/readthrough.html:76
|
||||
#: bookwyrm/templates/lists/bookmark_button.html:15
|
||||
#: bookwyrm/templates/lists/form.html:44
|
||||
#: bookwyrm/templates/preferences/edit_user.html:80
|
||||
#: bookwyrm/templates/preferences/edit_user.html:118
|
||||
#: bookwyrm/templates/settings/announcement_form.html:69
|
||||
#: bookwyrm/templates/settings/edit_server.html:68
|
||||
#: bookwyrm/templates/settings/federated_server.html:98
|
||||
|
@ -483,7 +484,7 @@ msgstr "Themen"
|
|||
msgid "Places"
|
||||
msgstr "Orte"
|
||||
|
||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:73
|
||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:75
|
||||
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
||||
#: bookwyrm/templates/search/layout.html:25
|
||||
#: bookwyrm/templates/search/layout.html:50
|
||||
|
@ -499,7 +500,7 @@ msgstr "Zur Liste"
|
|||
|
||||
#: bookwyrm/templates/book/book.html:313
|
||||
#: bookwyrm/templates/book/cover_modal.html:31
|
||||
#: bookwyrm/templates/lists/list.html:179
|
||||
#: bookwyrm/templates/lists/list.html:181
|
||||
#: bookwyrm/templates/settings/domain_form.html:26
|
||||
#: bookwyrm/templates/settings/ip_address_form.html:32
|
||||
msgid "Add"
|
||||
|
@ -847,7 +848,7 @@ msgstr "Bestätigungslink erneut senden"
|
|||
#: bookwyrm/templates/confirm_email/resend_form.html:11
|
||||
#: bookwyrm/templates/landing/layout.html:67
|
||||
#: bookwyrm/templates/password_reset_request.html:18
|
||||
#: bookwyrm/templates/preferences/edit_user.html:38
|
||||
#: bookwyrm/templates/preferences/edit_user.html:56
|
||||
#: bookwyrm/templates/snippets/register_form.html:13
|
||||
msgid "Email address:"
|
||||
msgstr "E-Mail Adresse"
|
||||
|
@ -876,7 +877,7 @@ msgstr "Föderiert"
|
|||
|
||||
#: bookwyrm/templates/directory/directory.html:4
|
||||
#: bookwyrm/templates/directory/directory.html:9
|
||||
#: bookwyrm/templates/layout.html:99
|
||||
#: bookwyrm/templates/layout.html:101
|
||||
msgid "Directory"
|
||||
msgstr "Vereichnis"
|
||||
|
||||
|
@ -959,7 +960,7 @@ msgstr "Alle bekannten Nutzer*innen"
|
|||
|
||||
#: bookwyrm/templates/discover/discover.html:4
|
||||
#: bookwyrm/templates/discover/discover.html:10
|
||||
#: bookwyrm/templates/layout.html:76
|
||||
#: bookwyrm/templates/layout.html:78
|
||||
#, fuzzy
|
||||
#| msgid "Discard"
|
||||
msgid "Discover"
|
||||
|
@ -1095,7 +1096,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
|||
msgstr "Direktnachrichten mit <a href=\"%(path)s\">%(username)s</a>"
|
||||
|
||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||
#: bookwyrm/templates/layout.html:109
|
||||
#: bookwyrm/templates/layout.html:111
|
||||
msgid "Direct Messages"
|
||||
msgstr "Direktnachrichten"
|
||||
|
||||
|
@ -1182,7 +1183,7 @@ msgid "What are you reading?"
|
|||
msgstr "Zu lesen angefangen"
|
||||
|
||||
#: bookwyrm/templates/get_started/books.html:9
|
||||
#: bookwyrm/templates/layout.html:43 bookwyrm/templates/lists/list.html:135
|
||||
#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:137
|
||||
msgid "Search for a book"
|
||||
msgstr "Nach einem Buch suchen"
|
||||
|
||||
|
@ -1200,8 +1201,8 @@ msgstr "Du kannst Bücher hinzufügen, wenn du %(site_name)s benutzt."
|
|||
#: bookwyrm/templates/get_started/books.html:17
|
||||
#: bookwyrm/templates/get_started/users.html:18
|
||||
#: bookwyrm/templates/get_started/users.html:19
|
||||
#: bookwyrm/templates/layout.html:49 bookwyrm/templates/layout.html:50
|
||||
#: bookwyrm/templates/lists/list.html:139
|
||||
#: bookwyrm/templates/layout.html:51 bookwyrm/templates/layout.html:52
|
||||
#: bookwyrm/templates/lists/list.html:141
|
||||
#: bookwyrm/templates/search/layout.html:4
|
||||
#: bookwyrm/templates/search/layout.html:9
|
||||
msgid "Search"
|
||||
|
@ -1220,7 +1221,7 @@ msgid "Popular on %(site_name)s"
|
|||
msgstr "Über %(site_name)s"
|
||||
|
||||
#: bookwyrm/templates/get_started/books.html:58
|
||||
#: bookwyrm/templates/lists/list.html:152
|
||||
#: bookwyrm/templates/lists/list.html:154
|
||||
msgid "No books found"
|
||||
msgstr "Keine Bücher gefunden"
|
||||
|
||||
|
@ -1274,12 +1275,12 @@ msgid "Finish"
|
|||
msgstr "Abgeschlossen"
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:15
|
||||
#: bookwyrm/templates/preferences/edit_user.html:24
|
||||
#: bookwyrm/templates/preferences/edit_user.html:42
|
||||
msgid "Display name:"
|
||||
msgstr "Displayname:"
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:22
|
||||
#: bookwyrm/templates/preferences/edit_user.html:31
|
||||
#: bookwyrm/templates/preferences/edit_user.html:49
|
||||
msgid "Summary:"
|
||||
msgstr "Bio:"
|
||||
|
||||
|
@ -1288,17 +1289,17 @@ msgid "A little bit about you"
|
|||
msgstr "Etwas über dich"
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:32
|
||||
#: bookwyrm/templates/preferences/edit_user.html:17
|
||||
#: bookwyrm/templates/preferences/edit_user.html:27
|
||||
msgid "Avatar:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:42
|
||||
#: bookwyrm/templates/preferences/edit_user.html:62
|
||||
#: bookwyrm/templates/preferences/edit_user.html:104
|
||||
msgid "Manually approve followers:"
|
||||
msgstr "Folgende manuell bestätigen"
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:48
|
||||
#: bookwyrm/templates/preferences/edit_user.html:54
|
||||
#: bookwyrm/templates/preferences/edit_user.html:80
|
||||
msgid "Show this account in suggested users:"
|
||||
msgstr "Diesen Account in vorgeschlagenen Usern zeigen"
|
||||
|
||||
|
@ -1538,31 +1539,37 @@ msgstr "Danke! Deine Anfrage ist eingegangen."
|
|||
msgid "Your Account"
|
||||
msgstr "Dein Account"
|
||||
|
||||
#: bookwyrm/templates/layout.html:41
|
||||
#: bookwyrm/templates/layout.html:13
|
||||
#, fuzzy, python-format
|
||||
#| msgid "About %(site_name)s"
|
||||
msgid "%(site_name)s search"
|
||||
msgstr "Über %(site_name)s"
|
||||
|
||||
#: bookwyrm/templates/layout.html:43
|
||||
#, fuzzy
|
||||
#| msgid "Search for a book or user"
|
||||
msgid "Search for a book, user, or list"
|
||||
msgstr "Suche nach Buch oder Benutzer*in"
|
||||
|
||||
#: bookwyrm/templates/layout.html:59 bookwyrm/templates/layout.html:60
|
||||
#: bookwyrm/templates/layout.html:61 bookwyrm/templates/layout.html:62
|
||||
msgid "Main navigation menu"
|
||||
msgstr "Navigationshauptmenü"
|
||||
|
||||
#: bookwyrm/templates/layout.html:70
|
||||
#: bookwyrm/templates/layout.html:72
|
||||
msgid "Feed"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:104
|
||||
#: bookwyrm/templates/layout.html:106
|
||||
#, fuzzy
|
||||
#| msgid "Your books"
|
||||
msgid "Your Books"
|
||||
msgstr "Deine Bücher"
|
||||
|
||||
#: bookwyrm/templates/layout.html:114
|
||||
#: bookwyrm/templates/layout.html:116
|
||||
msgid "Settings"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: bookwyrm/templates/layout.html:123
|
||||
#: bookwyrm/templates/layout.html:125
|
||||
#: bookwyrm/templates/settings/layout.html:40
|
||||
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||
|
@ -1570,77 +1577,77 @@ msgstr "Einstellungen"
|
|||
msgid "Invites"
|
||||
msgstr "Einladungen"
|
||||
|
||||
#: bookwyrm/templates/layout.html:130
|
||||
#: bookwyrm/templates/layout.html:132
|
||||
msgid "Admin"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:137
|
||||
#: bookwyrm/templates/layout.html:139
|
||||
msgid "Log out"
|
||||
msgstr "Abmelden"
|
||||
|
||||
#: bookwyrm/templates/layout.html:145 bookwyrm/templates/layout.html:146
|
||||
#: bookwyrm/templates/layout.html:147 bookwyrm/templates/layout.html:148
|
||||
#: bookwyrm/templates/notifications.html:6
|
||||
#: bookwyrm/templates/notifications.html:11
|
||||
msgid "Notifications"
|
||||
msgstr "Benachrichtigungen"
|
||||
|
||||
#: bookwyrm/templates/layout.html:168 bookwyrm/templates/layout.html:172
|
||||
#: bookwyrm/templates/layout.html:170 bookwyrm/templates/layout.html:174
|
||||
#: bookwyrm/templates/login.html:21
|
||||
#: bookwyrm/templates/snippets/register_form.html:4
|
||||
msgid "Username:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:173
|
||||
#: bookwyrm/templates/layout.html:175
|
||||
msgid "password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: bookwyrm/templates/layout.html:174 bookwyrm/templates/login.html:40
|
||||
#: bookwyrm/templates/layout.html:176 bookwyrm/templates/login.html:40
|
||||
msgid "Forgot your password?"
|
||||
msgstr "Passwort vergessen?"
|
||||
|
||||
#: bookwyrm/templates/layout.html:177 bookwyrm/templates/login.html:7
|
||||
#: bookwyrm/templates/layout.html:179 bookwyrm/templates/login.html:7
|
||||
#: bookwyrm/templates/login.html:37
|
||||
msgid "Log in"
|
||||
msgstr "Anmelden"
|
||||
|
||||
#: bookwyrm/templates/layout.html:185
|
||||
#: bookwyrm/templates/layout.html:187
|
||||
msgid "Join"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:219
|
||||
#: bookwyrm/templates/layout.html:221
|
||||
#, fuzzy
|
||||
#| msgid "Successfully imported"
|
||||
msgid "Successfully posted status"
|
||||
msgstr "Erfolgreich importiert"
|
||||
|
||||
#: bookwyrm/templates/layout.html:220
|
||||
#: bookwyrm/templates/layout.html:222
|
||||
#, fuzzy
|
||||
#| msgid "Boost status"
|
||||
msgid "Error posting status"
|
||||
msgstr "Status teilen"
|
||||
|
||||
#: bookwyrm/templates/layout.html:228
|
||||
#: bookwyrm/templates/layout.html:230
|
||||
#, fuzzy
|
||||
#| msgid "About this server"
|
||||
msgid "About this instance"
|
||||
msgstr "Über diesen Server"
|
||||
|
||||
#: bookwyrm/templates/layout.html:232
|
||||
#: bookwyrm/templates/layout.html:234
|
||||
msgid "Contact site admin"
|
||||
msgstr "Admin kontaktieren"
|
||||
|
||||
#: bookwyrm/templates/layout.html:236
|
||||
#: bookwyrm/templates/layout.html:238
|
||||
#, fuzzy
|
||||
#| msgid "List curation:"
|
||||
msgid "Documentation"
|
||||
msgstr "Listenkuratierung:"
|
||||
|
||||
#: bookwyrm/templates/layout.html:243
|
||||
#: bookwyrm/templates/layout.html:245
|
||||
#, python-format
|
||||
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||
msgstr "%(site_name)s auf <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a> unterstützen"
|
||||
|
||||
#: bookwyrm/templates/layout.html:247
|
||||
#: bookwyrm/templates/layout.html:249
|
||||
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||
msgstr "BookWyrm ist open source Software. Du kannst dich auf <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a> beteiligen oder etwas melden."
|
||||
|
||||
|
@ -1746,7 +1753,7 @@ msgstr "Offen"
|
|||
msgid "Anyone can add books to this list"
|
||||
msgstr "Alle können Bücher hinzufügen"
|
||||
|
||||
#: bookwyrm/templates/lists/form.html:49
|
||||
#: bookwyrm/templates/lists/form.html:50
|
||||
#, fuzzy
|
||||
#| msgid "Delete status"
|
||||
msgid "Delete list"
|
||||
|
@ -1772,7 +1779,7 @@ msgstr "Diese Liste ist momentan leer"
|
|||
msgid "Added by <a href=\"%(user_path)s\">%(username)s</a>"
|
||||
msgstr "Direktnachrichten mit <a href=\"%(path)s\">%(username)s</a>"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:74
|
||||
#: bookwyrm/templates/lists/list.html:75
|
||||
#, fuzzy
|
||||
#| msgid "List curation:"
|
||||
msgid "List position"
|
||||
|
@ -1784,46 +1791,46 @@ msgstr "Listenkuratierung:"
|
|||
msgid "Set"
|
||||
msgstr "Gestartet"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:89
|
||||
#: bookwyrm/templates/lists/list.html:91
|
||||
#: bookwyrm/templates/snippets/shelf_selector.html:26
|
||||
msgid "Remove"
|
||||
msgstr "Entfernen"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:103
|
||||
#: bookwyrm/templates/lists/list.html:120
|
||||
#: bookwyrm/templates/lists/list.html:105
|
||||
#: bookwyrm/templates/lists/list.html:122
|
||||
#, fuzzy
|
||||
#| msgid "Your Lists"
|
||||
msgid "Sort List"
|
||||
msgstr "Deine Listen"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:113
|
||||
#: bookwyrm/templates/lists/list.html:115
|
||||
#, fuzzy
|
||||
#| msgid "List curation:"
|
||||
msgid "Direction"
|
||||
msgstr "Listenkuratierung:"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:127
|
||||
#: bookwyrm/templates/lists/list.html:129
|
||||
msgid "Add Books"
|
||||
msgstr "Bücher hinzufügen"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:129
|
||||
#: bookwyrm/templates/lists/list.html:131
|
||||
msgid "Suggest Books"
|
||||
msgstr "Bücher vorschlagen"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:140
|
||||
#: bookwyrm/templates/lists/list.html:142
|
||||
msgid "search"
|
||||
msgstr "suchen"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:146
|
||||
#: bookwyrm/templates/lists/list.html:148
|
||||
msgid "Clear search"
|
||||
msgstr "Suche leeren"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:151
|
||||
#: bookwyrm/templates/lists/list.html:153
|
||||
#, python-format
|
||||
msgid "No books found matching the query \"%(query)s\""
|
||||
msgstr "Keine passenden Bücher zu \"%(query)s\" gefunden"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:179
|
||||
#: bookwyrm/templates/lists/list.html:181
|
||||
msgid "Suggest"
|
||||
msgstr "Vorschlagen"
|
||||
|
||||
|
@ -2112,7 +2119,7 @@ msgstr "Passwort zurücksetzen"
|
|||
|
||||
#: bookwyrm/templates/preferences/blocks.html:4
|
||||
#: bookwyrm/templates/preferences/blocks.html:7
|
||||
#: bookwyrm/templates/preferences/layout.html:30
|
||||
#: bookwyrm/templates/preferences/layout.html:31
|
||||
msgid "Blocked Users"
|
||||
msgstr "Blockierte Nutzer*innen"
|
||||
|
||||
|
@ -2123,7 +2130,7 @@ msgstr "Momentan keine Nutzer*innen blockiert."
|
|||
#: bookwyrm/templates/preferences/change_password.html:4
|
||||
#: bookwyrm/templates/preferences/change_password.html:7
|
||||
#: bookwyrm/templates/preferences/change_password.html:21
|
||||
#: bookwyrm/templates/preferences/layout.html:19
|
||||
#: bookwyrm/templates/preferences/layout.html:20
|
||||
msgid "Change Password"
|
||||
msgstr "Passwort ändern"
|
||||
|
||||
|
@ -2134,7 +2141,7 @@ msgstr "Neues Passwort:"
|
|||
#: bookwyrm/templates/preferences/delete_user.html:4
|
||||
#: bookwyrm/templates/preferences/delete_user.html:7
|
||||
#: bookwyrm/templates/preferences/delete_user.html:26
|
||||
#: bookwyrm/templates/preferences/layout.html:23
|
||||
#: bookwyrm/templates/preferences/layout.html:24
|
||||
#: bookwyrm/templates/user_admin/delete_user_form.html:23
|
||||
#, fuzzy
|
||||
#| msgid "Create an Account"
|
||||
|
@ -2151,46 +2158,62 @@ msgstr "Das Löschen des Accounts kann nicht rückgängig gemacht werden. Der Us
|
|||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:4
|
||||
#: bookwyrm/templates/preferences/edit_user.html:7
|
||||
#: bookwyrm/templates/preferences/layout.html:15
|
||||
msgid "Edit Profile"
|
||||
msgstr "Profil bearbeiten:"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:46
|
||||
#: bookwyrm/templates/preferences/edit_user.html:12
|
||||
#: bookwyrm/templates/preferences/edit_user.html:25
|
||||
#: bookwyrm/templates/user_admin/user_info.html:7
|
||||
msgid "Profile"
|
||||
msgstr "Profil"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:13
|
||||
#: bookwyrm/templates/preferences/edit_user.html:68
|
||||
#, fuzzy
|
||||
#| msgid "Email preference"
|
||||
msgid "Display preferences"
|
||||
msgstr "E-Mail Einstellungen"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:14
|
||||
#: bookwyrm/templates/preferences/edit_user.html:100
|
||||
#, fuzzy
|
||||
#| msgid "Private"
|
||||
msgid "Privacy"
|
||||
msgstr "Privat"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:72
|
||||
#, fuzzy
|
||||
#| msgid "Show set reading goal prompt in feed:"
|
||||
msgid "Show reading goal prompt in feed:"
|
||||
msgstr "Angegebenes Leseziel im Feed anzeigen."
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:50
|
||||
#: bookwyrm/templates/preferences/edit_user.html:76
|
||||
#, fuzzy
|
||||
#| msgid "Suggest Books"
|
||||
msgid "Show suggested users:"
|
||||
msgstr "Bücher vorschlagen"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:58
|
||||
#: bookwyrm/templates/preferences/edit_user.html:85
|
||||
#, python-format
|
||||
msgid "Your account will show up in the <a href=\"%(path)s\">directory</a>, and may be recommended to other BookWyrm users."
|
||||
msgstr "Dein Account wird im <a href=\"%(path)s\">directory</a> angezeigt und eventuell anderen Usern empfohlen."
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:68
|
||||
#: bookwyrm/templates/preferences/edit_user.html:89
|
||||
msgid "Preferred Timezone: "
|
||||
msgstr "Bevorzugte Zeitzone:"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:110
|
||||
#, fuzzy
|
||||
#| msgid "Goal privacy:"
|
||||
msgid "Default post privacy:"
|
||||
msgstr "Sichtbarkeit des Ziels"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:75
|
||||
msgid "Preferred Timezone: "
|
||||
msgstr "Bevorzugte Zeitzone:"
|
||||
|
||||
#: bookwyrm/templates/preferences/layout.html:11
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/layout.html:15
|
||||
#: bookwyrm/templates/user_admin/user_info.html:7
|
||||
msgid "Profile"
|
||||
msgstr "Profil"
|
||||
|
||||
#: bookwyrm/templates/preferences/layout.html:26
|
||||
#: bookwyrm/templates/preferences/layout.html:27
|
||||
msgid "Relationships"
|
||||
msgstr "Beziehungen"
|
||||
|
||||
|
@ -3604,7 +3627,7 @@ msgstr "Zu lesen angefangen"
|
|||
msgid "Show more"
|
||||
msgstr "Mehr anzeigen"
|
||||
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:35
|
||||
msgid "Show less"
|
||||
msgstr "Weniger anzeigen"
|
||||
|
||||
|
@ -3938,7 +3961,7 @@ msgstr ""
|
|||
msgid "Not a valid csv file"
|
||||
msgstr "E-Mail Adresse"
|
||||
|
||||
#: bookwyrm/views/login.py:70
|
||||
#: bookwyrm/views/login.py:68
|
||||
msgid "Username or password are incorrect"
|
||||
msgstr "Username oder Passwort sind falsch"
|
||||
|
||||
|
@ -3949,8 +3972,9 @@ msgid "No user with that email address was found."
|
|||
msgstr "Dieser Benutzename ist bereits vergeben."
|
||||
|
||||
#: bookwyrm/views/password.py:41
|
||||
#, python-format
|
||||
msgid "A password reset link sent to %s"
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "A password reset link sent to %s"
|
||||
msgid "A password reset link sent to {email}"
|
||||
msgstr "Ein Passwortwiederherstellungslinl wurde zu %s gesendet"
|
||||
|
||||
#: bookwyrm/views/rss_feed.py:34
|
||||
|
@ -3958,6 +3982,9 @@ msgstr "Ein Passwortwiederherstellungslinl wurde zu %s gesendet"
|
|||
msgid "Status updates from {obj.display_name}"
|
||||
msgstr "Status updates von {obj.display_name}"
|
||||
|
||||
#~ msgid "%(count)d uses"
|
||||
#~ msgstr "%(count)d Benutzungen"
|
||||
|
||||
#~ msgid "This instance is closed"
|
||||
#~ msgstr "Diese Instanz ist geschlossen"
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-20 19:44+0000\n"
|
||||
"POT-Creation-Date: 2021-09-28 18:31+0000\n"
|
||||
"PO-Revision-Date: 2021-02-28 17:19-0800\n"
|
||||
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
|
||||
"Language-Team: English <LL@li.org>\n"
|
||||
|
@ -18,59 +18,59 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: bookwyrm/forms.py:242
|
||||
#: bookwyrm/forms.py:241
|
||||
msgid "A user with this email already exists."
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:256
|
||||
#: bookwyrm/forms.py:255
|
||||
msgid "One Day"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:257
|
||||
#: bookwyrm/forms.py:256
|
||||
msgid "One Week"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:258
|
||||
#: bookwyrm/forms.py:257
|
||||
msgid "One Month"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:259
|
||||
#: bookwyrm/forms.py:258
|
||||
msgid "Does Not Expire"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:264
|
||||
#, python-format
|
||||
msgid "%(count)d uses"
|
||||
#: bookwyrm/forms.py:262
|
||||
#, python-brace-format
|
||||
msgid "{i} uses"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:267
|
||||
#: bookwyrm/forms.py:263
|
||||
msgid "Unlimited"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:329
|
||||
#: bookwyrm/forms.py:325
|
||||
msgid "List Order"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:330
|
||||
#: bookwyrm/forms.py:326
|
||||
msgid "Book Title"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:331
|
||||
#: bookwyrm/forms.py:327
|
||||
#: bookwyrm/templates/snippets/create_status/review.html:33
|
||||
#: bookwyrm/templates/user/shelf/shelf.html:117
|
||||
#: bookwyrm/templates/user/shelf/shelf.html:148
|
||||
msgid "Rating"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:333 bookwyrm/templates/lists/list.html:107
|
||||
#: bookwyrm/forms.py:329 bookwyrm/templates/lists/list.html:109
|
||||
msgid "Sort By"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:337
|
||||
#: bookwyrm/forms.py:333
|
||||
msgid "Ascending"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/forms.py:338
|
||||
#: bookwyrm/forms.py:334
|
||||
msgid "Descending"
|
||||
msgstr ""
|
||||
|
||||
|
@ -82,23 +82,23 @@ msgstr ""
|
|||
msgid "Could not find a match for book"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/base_model.py:13
|
||||
#: bookwyrm/models/base_model.py:16
|
||||
msgid "Pending"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/base_model.py:14
|
||||
#: bookwyrm/models/base_model.py:17
|
||||
msgid "Self deletion"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/base_model.py:15
|
||||
#: bookwyrm/models/base_model.py:18
|
||||
msgid "Moderator suspension"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/base_model.py:16
|
||||
#: bookwyrm/models/base_model.py:19
|
||||
msgid "Moderator deletion"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/base_model.py:17
|
||||
#: bookwyrm/models/base_model.py:20
|
||||
msgid "Domain block"
|
||||
msgstr ""
|
||||
|
||||
|
@ -125,7 +125,7 @@ msgstr ""
|
|||
msgid "%(value)s is not a valid username"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:169
|
||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171
|
||||
msgid "username"
|
||||
msgstr ""
|
||||
|
||||
|
@ -321,7 +321,7 @@ msgstr ""
|
|||
#: bookwyrm/templates/book/readthrough.html:76
|
||||
#: bookwyrm/templates/lists/bookmark_button.html:15
|
||||
#: bookwyrm/templates/lists/form.html:44
|
||||
#: bookwyrm/templates/preferences/edit_user.html:80
|
||||
#: bookwyrm/templates/preferences/edit_user.html:118
|
||||
#: bookwyrm/templates/settings/announcement_form.html:69
|
||||
#: bookwyrm/templates/settings/edit_server.html:68
|
||||
#: bookwyrm/templates/settings/federated_server.html:98
|
||||
|
@ -438,7 +438,7 @@ msgstr ""
|
|||
msgid "Places"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:73
|
||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:75
|
||||
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
||||
#: bookwyrm/templates/search/layout.html:25
|
||||
#: bookwyrm/templates/search/layout.html:50
|
||||
|
@ -452,7 +452,7 @@ msgstr ""
|
|||
|
||||
#: bookwyrm/templates/book/book.html:313
|
||||
#: bookwyrm/templates/book/cover_modal.html:31
|
||||
#: bookwyrm/templates/lists/list.html:179
|
||||
#: bookwyrm/templates/lists/list.html:181
|
||||
#: bookwyrm/templates/settings/domain_form.html:26
|
||||
#: bookwyrm/templates/settings/ip_address_form.html:32
|
||||
msgid "Add"
|
||||
|
@ -772,7 +772,7 @@ msgstr ""
|
|||
#: bookwyrm/templates/confirm_email/resend_form.html:11
|
||||
#: bookwyrm/templates/landing/layout.html:67
|
||||
#: bookwyrm/templates/password_reset_request.html:18
|
||||
#: bookwyrm/templates/preferences/edit_user.html:38
|
||||
#: bookwyrm/templates/preferences/edit_user.html:56
|
||||
#: bookwyrm/templates/snippets/register_form.html:13
|
||||
msgid "Email address:"
|
||||
msgstr ""
|
||||
|
@ -795,7 +795,7 @@ msgstr ""
|
|||
|
||||
#: bookwyrm/templates/directory/directory.html:4
|
||||
#: bookwyrm/templates/directory/directory.html:9
|
||||
#: bookwyrm/templates/layout.html:99
|
||||
#: bookwyrm/templates/layout.html:101
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
|
@ -867,7 +867,7 @@ msgstr ""
|
|||
|
||||
#: bookwyrm/templates/discover/discover.html:4
|
||||
#: bookwyrm/templates/discover/discover.html:10
|
||||
#: bookwyrm/templates/layout.html:76
|
||||
#: bookwyrm/templates/layout.html:78
|
||||
msgid "Discover"
|
||||
msgstr ""
|
||||
|
||||
|
@ -993,7 +993,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||
#: bookwyrm/templates/layout.html:109
|
||||
#: bookwyrm/templates/layout.html:111
|
||||
msgid "Direct Messages"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1073,7 +1073,7 @@ msgid "What are you reading?"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/get_started/books.html:9
|
||||
#: bookwyrm/templates/layout.html:43 bookwyrm/templates/lists/list.html:135
|
||||
#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:137
|
||||
msgid "Search for a book"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1091,8 +1091,8 @@ msgstr ""
|
|||
#: bookwyrm/templates/get_started/books.html:17
|
||||
#: bookwyrm/templates/get_started/users.html:18
|
||||
#: bookwyrm/templates/get_started/users.html:19
|
||||
#: bookwyrm/templates/layout.html:49 bookwyrm/templates/layout.html:50
|
||||
#: bookwyrm/templates/lists/list.html:139
|
||||
#: bookwyrm/templates/layout.html:51 bookwyrm/templates/layout.html:52
|
||||
#: bookwyrm/templates/lists/list.html:141
|
||||
#: bookwyrm/templates/search/layout.html:4
|
||||
#: bookwyrm/templates/search/layout.html:9
|
||||
msgid "Search"
|
||||
|
@ -1108,7 +1108,7 @@ msgid "Popular on %(site_name)s"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/get_started/books.html:58
|
||||
#: bookwyrm/templates/lists/list.html:152
|
||||
#: bookwyrm/templates/lists/list.html:154
|
||||
msgid "No books found"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1153,12 +1153,12 @@ msgid "Finish"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:15
|
||||
#: bookwyrm/templates/preferences/edit_user.html:24
|
||||
#: bookwyrm/templates/preferences/edit_user.html:42
|
||||
msgid "Display name:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:22
|
||||
#: bookwyrm/templates/preferences/edit_user.html:31
|
||||
#: bookwyrm/templates/preferences/edit_user.html:49
|
||||
msgid "Summary:"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1167,17 +1167,17 @@ msgid "A little bit about you"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:32
|
||||
#: bookwyrm/templates/preferences/edit_user.html:17
|
||||
#: bookwyrm/templates/preferences/edit_user.html:27
|
||||
msgid "Avatar:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:42
|
||||
#: bookwyrm/templates/preferences/edit_user.html:62
|
||||
#: bookwyrm/templates/preferences/edit_user.html:104
|
||||
msgid "Manually approve followers:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:48
|
||||
#: bookwyrm/templates/preferences/edit_user.html:54
|
||||
#: bookwyrm/templates/preferences/edit_user.html:80
|
||||
msgid "Show this account in suggested users:"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1408,27 +1408,32 @@ msgstr ""
|
|||
msgid "Your Account"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:41
|
||||
#: bookwyrm/templates/layout.html:13
|
||||
#, python-format
|
||||
msgid "%(site_name)s search"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:43
|
||||
msgid "Search for a book, user, or list"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:59 bookwyrm/templates/layout.html:60
|
||||
#: bookwyrm/templates/layout.html:61 bookwyrm/templates/layout.html:62
|
||||
msgid "Main navigation menu"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:70
|
||||
#: bookwyrm/templates/layout.html:72
|
||||
msgid "Feed"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:104
|
||||
#: bookwyrm/templates/layout.html:106
|
||||
msgid "Your Books"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:114
|
||||
#: bookwyrm/templates/layout.html:116
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:123
|
||||
#: bookwyrm/templates/layout.html:125
|
||||
#: bookwyrm/templates/settings/layout.html:40
|
||||
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||
|
@ -1436,69 +1441,69 @@ msgstr ""
|
|||
msgid "Invites"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:130
|
||||
#: bookwyrm/templates/layout.html:132
|
||||
msgid "Admin"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:137
|
||||
#: bookwyrm/templates/layout.html:139
|
||||
msgid "Log out"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:145 bookwyrm/templates/layout.html:146
|
||||
#: bookwyrm/templates/layout.html:147 bookwyrm/templates/layout.html:148
|
||||
#: bookwyrm/templates/notifications.html:6
|
||||
#: bookwyrm/templates/notifications.html:11
|
||||
msgid "Notifications"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:168 bookwyrm/templates/layout.html:172
|
||||
#: bookwyrm/templates/layout.html:170 bookwyrm/templates/layout.html:174
|
||||
#: bookwyrm/templates/login.html:21
|
||||
#: bookwyrm/templates/snippets/register_form.html:4
|
||||
msgid "Username:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:173
|
||||
#: bookwyrm/templates/layout.html:175
|
||||
msgid "password"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:174 bookwyrm/templates/login.html:40
|
||||
#: bookwyrm/templates/layout.html:176 bookwyrm/templates/login.html:40
|
||||
msgid "Forgot your password?"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:177 bookwyrm/templates/login.html:7
|
||||
#: bookwyrm/templates/layout.html:179 bookwyrm/templates/login.html:7
|
||||
#: bookwyrm/templates/login.html:37
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:185
|
||||
#: bookwyrm/templates/layout.html:187
|
||||
msgid "Join"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:219
|
||||
#: bookwyrm/templates/layout.html:221
|
||||
msgid "Successfully posted status"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:220
|
||||
#: bookwyrm/templates/layout.html:222
|
||||
msgid "Error posting status"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:228
|
||||
#: bookwyrm/templates/layout.html:230
|
||||
msgid "About this instance"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:232
|
||||
#: bookwyrm/templates/layout.html:234
|
||||
msgid "Contact site admin"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:236
|
||||
#: bookwyrm/templates/layout.html:238
|
||||
msgid "Documentation"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:243
|
||||
#: bookwyrm/templates/layout.html:245
|
||||
#, python-format
|
||||
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:247
|
||||
#: bookwyrm/templates/layout.html:249
|
||||
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||
msgstr ""
|
||||
|
||||
|
@ -1598,7 +1603,7 @@ msgstr ""
|
|||
msgid "Anyone can add books to this list"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/form.html:49
|
||||
#: bookwyrm/templates/lists/form.html:50
|
||||
msgid "Delete list"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1619,7 +1624,7 @@ msgstr ""
|
|||
msgid "Added by <a href=\"%(user_path)s\">%(username)s</a>"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:74
|
||||
#: bookwyrm/templates/lists/list.html:75
|
||||
msgid "List position"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1627,42 +1632,42 @@ msgstr ""
|
|||
msgid "Set"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:89
|
||||
#: bookwyrm/templates/lists/list.html:91
|
||||
#: bookwyrm/templates/snippets/shelf_selector.html:26
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:103
|
||||
#: bookwyrm/templates/lists/list.html:120
|
||||
#: bookwyrm/templates/lists/list.html:105
|
||||
#: bookwyrm/templates/lists/list.html:122
|
||||
msgid "Sort List"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:113
|
||||
#: bookwyrm/templates/lists/list.html:115
|
||||
msgid "Direction"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:127
|
||||
#: bookwyrm/templates/lists/list.html:129
|
||||
msgid "Add Books"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:129
|
||||
#: bookwyrm/templates/lists/list.html:131
|
||||
msgid "Suggest Books"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:140
|
||||
#: bookwyrm/templates/lists/list.html:142
|
||||
msgid "search"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:146
|
||||
#: bookwyrm/templates/lists/list.html:148
|
||||
msgid "Clear search"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:151
|
||||
#: bookwyrm/templates/lists/list.html:153
|
||||
#, python-format
|
||||
msgid "No books found matching the query \"%(query)s\""
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:179
|
||||
#: bookwyrm/templates/lists/list.html:181
|
||||
msgid "Suggest"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1926,7 +1931,7 @@ msgstr ""
|
|||
|
||||
#: bookwyrm/templates/preferences/blocks.html:4
|
||||
#: bookwyrm/templates/preferences/blocks.html:7
|
||||
#: bookwyrm/templates/preferences/layout.html:30
|
||||
#: bookwyrm/templates/preferences/layout.html:31
|
||||
msgid "Blocked Users"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1937,7 +1942,7 @@ msgstr ""
|
|||
#: bookwyrm/templates/preferences/change_password.html:4
|
||||
#: bookwyrm/templates/preferences/change_password.html:7
|
||||
#: bookwyrm/templates/preferences/change_password.html:21
|
||||
#: bookwyrm/templates/preferences/layout.html:19
|
||||
#: bookwyrm/templates/preferences/layout.html:20
|
||||
msgid "Change Password"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1948,7 +1953,7 @@ msgstr ""
|
|||
#: bookwyrm/templates/preferences/delete_user.html:4
|
||||
#: bookwyrm/templates/preferences/delete_user.html:7
|
||||
#: bookwyrm/templates/preferences/delete_user.html:26
|
||||
#: bookwyrm/templates/preferences/layout.html:23
|
||||
#: bookwyrm/templates/preferences/layout.html:24
|
||||
#: bookwyrm/templates/user_admin/delete_user_form.html:23
|
||||
msgid "Delete Account"
|
||||
msgstr ""
|
||||
|
@ -1963,40 +1968,52 @@ msgstr ""
|
|||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:4
|
||||
#: bookwyrm/templates/preferences/edit_user.html:7
|
||||
#: bookwyrm/templates/preferences/layout.html:15
|
||||
msgid "Edit Profile"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:46
|
||||
#: bookwyrm/templates/preferences/edit_user.html:12
|
||||
#: bookwyrm/templates/preferences/edit_user.html:25
|
||||
#: bookwyrm/templates/user_admin/user_info.html:7
|
||||
msgid "Profile"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:13
|
||||
#: bookwyrm/templates/preferences/edit_user.html:68
|
||||
msgid "Display preferences"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:14
|
||||
#: bookwyrm/templates/preferences/edit_user.html:100
|
||||
msgid "Privacy"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:72
|
||||
msgid "Show reading goal prompt in feed:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:50
|
||||
#: bookwyrm/templates/preferences/edit_user.html:76
|
||||
msgid "Show suggested users:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:58
|
||||
#: bookwyrm/templates/preferences/edit_user.html:85
|
||||
#, python-format
|
||||
msgid "Your account will show up in the <a href=\"%(path)s\">directory</a>, and may be recommended to other BookWyrm users."
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:68
|
||||
msgid "Default post privacy:"
|
||||
#: bookwyrm/templates/preferences/edit_user.html:89
|
||||
msgid "Preferred Timezone: "
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:75
|
||||
msgid "Preferred Timezone: "
|
||||
#: bookwyrm/templates/preferences/edit_user.html:110
|
||||
msgid "Default post privacy:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/layout.html:11
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/layout.html:15
|
||||
#: bookwyrm/templates/user_admin/user_info.html:7
|
||||
msgid "Profile"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/preferences/layout.html:26
|
||||
#: bookwyrm/templates/preferences/layout.html:27
|
||||
msgid "Relationships"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3211,7 +3228,7 @@ msgstr ""
|
|||
msgid "Show more"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:35
|
||||
msgid "Show less"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3505,7 +3522,7 @@ msgstr ""
|
|||
msgid "Not a valid csv file"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/views/login.py:70
|
||||
#: bookwyrm/views/login.py:68
|
||||
msgid "Username or password are incorrect"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3514,8 +3531,8 @@ msgid "No user with that email address was found."
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/views/password.py:41
|
||||
#, python-format
|
||||
msgid "A password reset link sent to %s"
|
||||
#, python-brace-format
|
||||
msgid "A password reset link sent to {email}"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/views/rss_feed.py:34
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-20 19:44+0000\n"
|
||||
"POT-Creation-Date: 2021-09-28 18:31+0000\n"
|
||||
"PO-Revision-Date: 2021-03-19 11:49+0800\n"
|
||||
"Last-Translator: Reese Porter <reesedporter@gmail.com>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -18,59 +18,60 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: bookwyrm/forms.py:242
|
||||
#: bookwyrm/forms.py:241
|
||||
msgid "A user with this email already exists."
|
||||
msgstr "Ya existe un usuario con ese correo electrónico."
|
||||
|
||||
#: bookwyrm/forms.py:256
|
||||
#: bookwyrm/forms.py:255
|
||||
msgid "One Day"
|
||||
msgstr "Un día"
|
||||
|
||||
#: bookwyrm/forms.py:257
|
||||
#: bookwyrm/forms.py:256
|
||||
msgid "One Week"
|
||||
msgstr "Una semana"
|
||||
|
||||
#: bookwyrm/forms.py:258
|
||||
#: bookwyrm/forms.py:257
|
||||
msgid "One Month"
|
||||
msgstr "Un mes"
|
||||
|
||||
#: bookwyrm/forms.py:259
|
||||
#: bookwyrm/forms.py:258
|
||||
msgid "Does Not Expire"
|
||||
msgstr "Nunca se vence"
|
||||
|
||||
#: bookwyrm/forms.py:264
|
||||
#, python-format
|
||||
msgid "%(count)d uses"
|
||||
msgstr "%(count)d usos"
|
||||
#: bookwyrm/forms.py:262
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Max uses"
|
||||
msgid "{i} uses"
|
||||
msgstr "Número máximo de usos"
|
||||
|
||||
#: bookwyrm/forms.py:267
|
||||
#: bookwyrm/forms.py:263
|
||||
msgid "Unlimited"
|
||||
msgstr "Sin límite"
|
||||
|
||||
#: bookwyrm/forms.py:329
|
||||
#: bookwyrm/forms.py:325
|
||||
msgid "List Order"
|
||||
msgstr "Orden de la lista"
|
||||
|
||||
#: bookwyrm/forms.py:330
|
||||
#: bookwyrm/forms.py:326
|
||||
msgid "Book Title"
|
||||
msgstr "Título"
|
||||
|
||||
#: bookwyrm/forms.py:331
|
||||
#: bookwyrm/forms.py:327
|
||||
#: bookwyrm/templates/snippets/create_status/review.html:33
|
||||
#: bookwyrm/templates/user/shelf/shelf.html:117
|
||||
#: bookwyrm/templates/user/shelf/shelf.html:148
|
||||
msgid "Rating"
|
||||
msgstr "Calificación"
|
||||
|
||||
#: bookwyrm/forms.py:333 bookwyrm/templates/lists/list.html:107
|
||||
#: bookwyrm/forms.py:329 bookwyrm/templates/lists/list.html:109
|
||||
msgid "Sort By"
|
||||
msgstr "Ordenar por"
|
||||
|
||||
#: bookwyrm/forms.py:337
|
||||
#: bookwyrm/forms.py:333
|
||||
msgid "Ascending"
|
||||
msgstr "Ascendente"
|
||||
|
||||
#: bookwyrm/forms.py:338
|
||||
#: bookwyrm/forms.py:334
|
||||
msgid "Descending"
|
||||
msgstr "Descendente"
|
||||
|
||||
|
@ -82,23 +83,23 @@ msgstr "Error en cargar libro"
|
|||
msgid "Could not find a match for book"
|
||||
msgstr "No se pudo encontrar el libro"
|
||||
|
||||
#: bookwyrm/models/base_model.py:13
|
||||
#: bookwyrm/models/base_model.py:16
|
||||
msgid "Pending"
|
||||
msgstr "Pendiente"
|
||||
|
||||
#: bookwyrm/models/base_model.py:14
|
||||
#: bookwyrm/models/base_model.py:17
|
||||
msgid "Self deletion"
|
||||
msgstr "Auto-eliminación"
|
||||
|
||||
#: bookwyrm/models/base_model.py:15
|
||||
#: bookwyrm/models/base_model.py:18
|
||||
msgid "Moderator suspension"
|
||||
msgstr "Suspensión de moderador"
|
||||
|
||||
#: bookwyrm/models/base_model.py:16
|
||||
#: bookwyrm/models/base_model.py:19
|
||||
msgid "Moderator deletion"
|
||||
msgstr "Eliminación de moderador"
|
||||
|
||||
#: bookwyrm/models/base_model.py:17
|
||||
#: bookwyrm/models/base_model.py:20
|
||||
msgid "Domain block"
|
||||
msgstr "Bloqueo de dominio"
|
||||
|
||||
|
@ -125,7 +126,7 @@ msgstr "%(value)s no es un remote_id válido"
|
|||
msgid "%(value)s is not a valid username"
|
||||
msgstr "%(value)s no es un usuario válido"
|
||||
|
||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:169
|
||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171
|
||||
msgid "username"
|
||||
msgstr "nombre de usuario"
|
||||
|
||||
|
@ -321,7 +322,7 @@ msgstr "Clave Goodreads:"
|
|||
#: bookwyrm/templates/book/readthrough.html:76
|
||||
#: bookwyrm/templates/lists/bookmark_button.html:15
|
||||
#: bookwyrm/templates/lists/form.html:44
|
||||
#: bookwyrm/templates/preferences/edit_user.html:80
|
||||
#: bookwyrm/templates/preferences/edit_user.html:118
|
||||
#: bookwyrm/templates/settings/announcement_form.html:69
|
||||
#: bookwyrm/templates/settings/edit_server.html:68
|
||||
#: bookwyrm/templates/settings/federated_server.html:98
|
||||
|
@ -438,7 +439,7 @@ msgstr "Sujetos"
|
|||
msgid "Places"
|
||||
msgstr "Lugares"
|
||||
|
||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:73
|
||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:75
|
||||
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
||||
#: bookwyrm/templates/search/layout.html:25
|
||||
#: bookwyrm/templates/search/layout.html:50
|
||||
|
@ -452,7 +453,7 @@ msgstr "Agregar a lista"
|
|||
|
||||
#: bookwyrm/templates/book/book.html:313
|
||||
#: bookwyrm/templates/book/cover_modal.html:31
|
||||
#: bookwyrm/templates/lists/list.html:179
|
||||
#: bookwyrm/templates/lists/list.html:181
|
||||
#: bookwyrm/templates/settings/domain_form.html:26
|
||||
#: bookwyrm/templates/settings/ip_address_form.html:32
|
||||
msgid "Add"
|
||||
|
@ -772,7 +773,7 @@ msgstr "Reenviar enlace de confirmación"
|
|||
#: bookwyrm/templates/confirm_email/resend_form.html:11
|
||||
#: bookwyrm/templates/landing/layout.html:67
|
||||
#: bookwyrm/templates/password_reset_request.html:18
|
||||
#: bookwyrm/templates/preferences/edit_user.html:38
|
||||
#: bookwyrm/templates/preferences/edit_user.html:56
|
||||
#: bookwyrm/templates/snippets/register_form.html:13
|
||||
msgid "Email address:"
|
||||
msgstr "Dirección de correo electrónico:"
|
||||
|
@ -795,7 +796,7 @@ msgstr "Comunidad federalizada"
|
|||
|
||||
#: bookwyrm/templates/directory/directory.html:4
|
||||
#: bookwyrm/templates/directory/directory.html:9
|
||||
#: bookwyrm/templates/layout.html:99
|
||||
#: bookwyrm/templates/layout.html:101
|
||||
msgid "Directory"
|
||||
msgstr "Directorio"
|
||||
|
||||
|
@ -867,7 +868,7 @@ msgstr "Todos los usuarios conocidos"
|
|||
|
||||
#: bookwyrm/templates/discover/discover.html:4
|
||||
#: bookwyrm/templates/discover/discover.html:10
|
||||
#: bookwyrm/templates/layout.html:76
|
||||
#: bookwyrm/templates/layout.html:78
|
||||
msgid "Discover"
|
||||
msgstr "Descubrir"
|
||||
|
||||
|
@ -993,7 +994,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
|||
msgstr "Mensajes directos con <a href=\"%(path)s\">%(username)s</a>"
|
||||
|
||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||
#: bookwyrm/templates/layout.html:109
|
||||
#: bookwyrm/templates/layout.html:111
|
||||
msgid "Direct Messages"
|
||||
msgstr "Mensajes directos"
|
||||
|
||||
|
@ -1073,7 +1074,7 @@ msgid "What are you reading?"
|
|||
msgstr "¿Qué estás leyendo?"
|
||||
|
||||
#: bookwyrm/templates/get_started/books.html:9
|
||||
#: bookwyrm/templates/layout.html:43 bookwyrm/templates/lists/list.html:135
|
||||
#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:137
|
||||
msgid "Search for a book"
|
||||
msgstr "Buscar libros"
|
||||
|
||||
|
@ -1091,8 +1092,8 @@ msgstr "Puedes agregar libros cuando comiences a usar %(site_name)s."
|
|||
#: bookwyrm/templates/get_started/books.html:17
|
||||
#: bookwyrm/templates/get_started/users.html:18
|
||||
#: bookwyrm/templates/get_started/users.html:19
|
||||
#: bookwyrm/templates/layout.html:49 bookwyrm/templates/layout.html:50
|
||||
#: bookwyrm/templates/lists/list.html:139
|
||||
#: bookwyrm/templates/layout.html:51 bookwyrm/templates/layout.html:52
|
||||
#: bookwyrm/templates/lists/list.html:141
|
||||
#: bookwyrm/templates/search/layout.html:4
|
||||
#: bookwyrm/templates/search/layout.html:9
|
||||
msgid "Search"
|
||||
|
@ -1108,7 +1109,7 @@ msgid "Popular on %(site_name)s"
|
|||
msgstr "Popular en %(site_name)s"
|
||||
|
||||
#: bookwyrm/templates/get_started/books.html:58
|
||||
#: bookwyrm/templates/lists/list.html:152
|
||||
#: bookwyrm/templates/lists/list.html:154
|
||||
msgid "No books found"
|
||||
msgstr "No se encontró ningún libro"
|
||||
|
||||
|
@ -1153,12 +1154,12 @@ msgid "Finish"
|
|||
msgstr "Terminar"
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:15
|
||||
#: bookwyrm/templates/preferences/edit_user.html:24
|
||||
#: bookwyrm/templates/preferences/edit_user.html:42
|
||||
msgid "Display name:"
|
||||
msgstr "Nombre de visualización:"
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:22
|
||||
#: bookwyrm/templates/preferences/edit_user.html:31
|
||||
#: bookwyrm/templates/preferences/edit_user.html:49
|
||||
msgid "Summary:"
|
||||
msgstr "Resumen:"
|
||||
|
||||
|
@ -1167,17 +1168,17 @@ msgid "A little bit about you"
|
|||
msgstr "Un poco sobre ti"
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:32
|
||||
#: bookwyrm/templates/preferences/edit_user.html:17
|
||||
#: bookwyrm/templates/preferences/edit_user.html:27
|
||||
msgid "Avatar:"
|
||||
msgstr "Avatar:"
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:42
|
||||
#: bookwyrm/templates/preferences/edit_user.html:62
|
||||
#: bookwyrm/templates/preferences/edit_user.html:104
|
||||
msgid "Manually approve followers:"
|
||||
msgstr "Aprobar seguidores a mano:"
|
||||
|
||||
#: bookwyrm/templates/get_started/profile.html:48
|
||||
#: bookwyrm/templates/preferences/edit_user.html:54
|
||||
#: bookwyrm/templates/preferences/edit_user.html:80
|
||||
msgid "Show this account in suggested users:"
|
||||
msgstr "Mostrar esta cuenta en los usuarios sugeridos:"
|
||||
|
||||
|
@ -1409,29 +1410,35 @@ msgstr "¡Gracias! Tu solicitud ha sido recibido."
|
|||
msgid "Your Account"
|
||||
msgstr "Tu cuenta"
|
||||
|
||||
#: bookwyrm/templates/layout.html:41
|
||||
#: bookwyrm/templates/layout.html:13
|
||||
#, fuzzy, python-format
|
||||
#| msgid "About %(site_name)s"
|
||||
msgid "%(site_name)s search"
|
||||
msgstr "Sobre %(site_name)s"
|
||||
|
||||
#: bookwyrm/templates/layout.html:43
|
||||
#, fuzzy
|
||||
#| msgid "Search for a book or user"
|
||||
msgid "Search for a book, user, or list"
|
||||
msgstr "Buscar un libro o un usuario"
|
||||
|
||||
#: bookwyrm/templates/layout.html:59 bookwyrm/templates/layout.html:60
|
||||
#: bookwyrm/templates/layout.html:61 bookwyrm/templates/layout.html:62
|
||||
msgid "Main navigation menu"
|
||||
msgstr "Menú de navigación central"
|
||||
|
||||
#: bookwyrm/templates/layout.html:70
|
||||
#: bookwyrm/templates/layout.html:72
|
||||
msgid "Feed"
|
||||
msgstr "Actividad"
|
||||
|
||||
#: bookwyrm/templates/layout.html:104
|
||||
#: bookwyrm/templates/layout.html:106
|
||||
msgid "Your Books"
|
||||
msgstr "Tus libros"
|
||||
|
||||
#: bookwyrm/templates/layout.html:114
|
||||
#: bookwyrm/templates/layout.html:116
|
||||
msgid "Settings"
|
||||
msgstr "Configuración"
|
||||
|
||||
#: bookwyrm/templates/layout.html:123
|
||||
#: bookwyrm/templates/layout.html:125
|
||||
#: bookwyrm/templates/settings/layout.html:40
|
||||
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||
|
@ -1439,69 +1446,69 @@ msgstr "Configuración"
|
|||
msgid "Invites"
|
||||
msgstr "Invitaciones"
|
||||
|
||||
#: bookwyrm/templates/layout.html:130
|
||||
#: bookwyrm/templates/layout.html:132
|
||||
msgid "Admin"
|
||||
msgstr "Admin"
|
||||
|
||||
#: bookwyrm/templates/layout.html:137
|
||||
#: bookwyrm/templates/layout.html:139
|
||||
msgid "Log out"
|
||||
msgstr "Cerrar sesión"
|
||||
|
||||
#: bookwyrm/templates/layout.html:145 bookwyrm/templates/layout.html:146
|
||||
#: bookwyrm/templates/layout.html:147 bookwyrm/templates/layout.html:148
|
||||
#: bookwyrm/templates/notifications.html:6
|
||||
#: bookwyrm/templates/notifications.html:11
|
||||
msgid "Notifications"
|
||||
msgstr "Notificaciones"
|
||||
|
||||
#: bookwyrm/templates/layout.html:168 bookwyrm/templates/layout.html:172
|
||||
#: bookwyrm/templates/layout.html:170 bookwyrm/templates/layout.html:174
|
||||
#: bookwyrm/templates/login.html:21
|
||||
#: bookwyrm/templates/snippets/register_form.html:4
|
||||
msgid "Username:"
|
||||
msgstr "Nombre de usuario:"
|
||||
|
||||
#: bookwyrm/templates/layout.html:173
|
||||
#: bookwyrm/templates/layout.html:175
|
||||
msgid "password"
|
||||
msgstr "contraseña"
|
||||
|
||||
#: bookwyrm/templates/layout.html:174 bookwyrm/templates/login.html:40
|
||||
#: bookwyrm/templates/layout.html:176 bookwyrm/templates/login.html:40
|
||||
msgid "Forgot your password?"
|
||||
msgstr "¿Olvidaste tu contraseña?"
|
||||
|
||||
#: bookwyrm/templates/layout.html:177 bookwyrm/templates/login.html:7
|
||||
#: bookwyrm/templates/layout.html:179 bookwyrm/templates/login.html:7
|
||||
#: bookwyrm/templates/login.html:37
|
||||
msgid "Log in"
|
||||
msgstr "Iniciar sesión"
|
||||
|
||||
#: bookwyrm/templates/layout.html:185
|
||||
#: bookwyrm/templates/layout.html:187
|
||||
msgid "Join"
|
||||
msgstr "Unirse"
|
||||
|
||||
#: bookwyrm/templates/layout.html:219
|
||||
#: bookwyrm/templates/layout.html:221
|
||||
msgid "Successfully posted status"
|
||||
msgstr "Status publicado exitosamente"
|
||||
|
||||
#: bookwyrm/templates/layout.html:220
|
||||
#: bookwyrm/templates/layout.html:222
|
||||
msgid "Error posting status"
|
||||
msgstr "Error en publicar status"
|
||||
|
||||
#: bookwyrm/templates/layout.html:228
|
||||
#: bookwyrm/templates/layout.html:230
|
||||
msgid "About this instance"
|
||||
msgstr "Sobre esta instancia"
|
||||
|
||||
#: bookwyrm/templates/layout.html:232
|
||||
#: bookwyrm/templates/layout.html:234
|
||||
msgid "Contact site admin"
|
||||
msgstr "Contactarse con administradores del sitio"
|
||||
|
||||
#: bookwyrm/templates/layout.html:236
|
||||
#: bookwyrm/templates/layout.html:238
|
||||
msgid "Documentation"
|
||||
msgstr "Documentación de Django"
|
||||
|
||||
#: bookwyrm/templates/layout.html:243
|
||||
#: bookwyrm/templates/layout.html:245
|
||||
#, python-format
|
||||
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||
msgstr "Apoyar %(site_name)s en <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||
|
||||
#: bookwyrm/templates/layout.html:247
|
||||
#: bookwyrm/templates/layout.html:249
|
||||
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||
msgstr "BookWyrm es software de código abierto. Puedes contribuir o reportar problemas en <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||
|
||||
|
@ -1601,7 +1608,7 @@ msgstr "Abierto"
|
|||
msgid "Anyone can add books to this list"
|
||||
msgstr "Cualquer usuario puede agregar libros a esta lista"
|
||||
|
||||
#: bookwyrm/templates/lists/form.html:49
|
||||
#: bookwyrm/templates/lists/form.html:50
|
||||
msgid "Delete list"
|
||||
msgstr "Eliminar lista"
|
||||
|
||||
|
@ -1622,7 +1629,7 @@ msgstr "Esta lista está vacia"
|
|||
msgid "Added by <a href=\"%(user_path)s\">%(username)s</a>"
|
||||
msgstr "Agregado por <a href=\"%(user_path)s\">%(username)s</a>"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:74
|
||||
#: bookwyrm/templates/lists/list.html:75
|
||||
msgid "List position"
|
||||
msgstr "Posición"
|
||||
|
||||
|
@ -1630,42 +1637,42 @@ msgstr "Posición"
|
|||
msgid "Set"
|
||||
msgstr "Establecido"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:89
|
||||
#: bookwyrm/templates/lists/list.html:91
|
||||
#: bookwyrm/templates/snippets/shelf_selector.html:26
|
||||
msgid "Remove"
|
||||
msgstr "Quitar"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:103
|
||||
#: bookwyrm/templates/lists/list.html:120
|
||||
#: bookwyrm/templates/lists/list.html:105
|
||||
#: bookwyrm/templates/lists/list.html:122
|
||||
msgid "Sort List"
|
||||
msgstr "Ordena la lista"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:113
|
||||
#: bookwyrm/templates/lists/list.html:115
|
||||
msgid "Direction"
|
||||
msgstr "Dirección"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:127
|
||||
#: bookwyrm/templates/lists/list.html:129
|
||||
msgid "Add Books"
|
||||
msgstr "Agregar libros"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:129
|
||||
#: bookwyrm/templates/lists/list.html:131
|
||||
msgid "Suggest Books"
|
||||
msgstr "Sugerir libros"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:140
|
||||
#: bookwyrm/templates/lists/list.html:142
|
||||
msgid "search"
|
||||
msgstr "buscar"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:146
|
||||
#: bookwyrm/templates/lists/list.html:148
|
||||
msgid "Clear search"
|
||||
msgstr "Borrar búsqueda"
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:151
|
||||
#: bookwyrm/templates/lists/list.html:153
|
||||
#, python-format
|
||||
msgid "No books found matching the query \"%(query)s\""
|
||||
msgstr "No se encontró ningún libro correspondiente a la búsqueda: \"%(query)s\""
|
||||
|
||||
#: bookwyrm/templates/lists/list.html:179
|
||||
#: bookwyrm/templates/lists/list.html:181
|
||||
msgid "Suggest"
|
||||
msgstr "Sugerir"
|
||||
|
||||
|
@ -1929,7 +1936,7 @@ msgstr "Restablecer contraseña"
|
|||
|
||||
#: bookwyrm/templates/preferences/blocks.html:4
|
||||
#: bookwyrm/templates/preferences/blocks.html:7
|
||||
#: bookwyrm/templates/preferences/layout.html:30
|
||||
#: bookwyrm/templates/preferences/layout.html:31
|
||||
msgid "Blocked Users"
|
||||
msgstr "Usuarios bloqueados"
|
||||
|
||||
|
@ -1940,7 +1947,7 @@ msgstr "No hay ningún usuario bloqueado actualmente."
|
|||
#: bookwyrm/templates/preferences/change_password.html:4
|
||||
#: bookwyrm/templates/preferences/change_password.html:7
|
||||
#: bookwyrm/templates/preferences/change_password.html:21
|
||||
#: bookwyrm/templates/preferences/layout.html:19
|
||||
#: bookwyrm/templates/preferences/layout.html:20
|
||||
msgid "Change Password"
|
||||
msgstr "Cambiar contraseña"
|
||||
|
||||
|
@ -1951,7 +1958,7 @@ msgstr "Nueva contraseña:"
|
|||
#: bookwyrm/templates/preferences/delete_user.html:4
|
||||
#: bookwyrm/templates/preferences/delete_user.html:7
|
||||
#: bookwyrm/templates/preferences/delete_user.html:26
|
||||
#: bookwyrm/templates/preferences/layout.html:23
|
||||
#: bookwyrm/templates/preferences/layout.html:24
|
||||
#: bookwyrm/templates/user_admin/delete_user_form.html:23
|
||||
msgid "Delete Account"
|
||||
msgstr "Quitar cuenta"
|
||||
|
@ -1966,40 +1973,56 @@ msgstr "Eliminar tu cuenta no puede ser deshecho. El nombre de usuario no será
|
|||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:4
|
||||
#: bookwyrm/templates/preferences/edit_user.html:7
|
||||
#: bookwyrm/templates/preferences/layout.html:15
|
||||
msgid "Edit Profile"
|
||||
msgstr "Editar perfil"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:46
|
||||
#: bookwyrm/templates/preferences/edit_user.html:12
|
||||
#: bookwyrm/templates/preferences/edit_user.html:25
|
||||
#: bookwyrm/templates/user_admin/user_info.html:7
|
||||
msgid "Profile"
|
||||
msgstr "Perfil"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:13
|
||||
#: bookwyrm/templates/preferences/edit_user.html:68
|
||||
#, fuzzy
|
||||
#| msgid "Email preference"
|
||||
msgid "Display preferences"
|
||||
msgstr "Preferencia de correo electrónico"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:14
|
||||
#: bookwyrm/templates/preferences/edit_user.html:100
|
||||
#, fuzzy
|
||||
#| msgid "Post privacy"
|
||||
msgid "Privacy"
|
||||
msgstr "Privacidad de publicación"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:72
|
||||
msgid "Show reading goal prompt in feed:"
|
||||
msgstr "Mostrar sugerencia de meta de lectura en el feed:"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:50
|
||||
#: bookwyrm/templates/preferences/edit_user.html:76
|
||||
msgid "Show suggested users:"
|
||||
msgstr "Mostrar usuarios sugeridos:"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:58
|
||||
#: bookwyrm/templates/preferences/edit_user.html:85
|
||||
#, python-format
|
||||
msgid "Your account will show up in the <a href=\"%(path)s\">directory</a>, and may be recommended to other BookWyrm users."
|
||||
msgstr "Tu cuenta se aparecerá en el <a href=\"%(path)s\">directorio</a>, y puede ser recomendado a otros usuarios de BookWyrm."
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:68
|
||||
msgid "Default post privacy:"
|
||||
msgstr "Privacidad de publicación por defecto:"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:75
|
||||
#: bookwyrm/templates/preferences/edit_user.html:89
|
||||
msgid "Preferred Timezone: "
|
||||
msgstr "Huso horario preferido"
|
||||
|
||||
#: bookwyrm/templates/preferences/edit_user.html:110
|
||||
msgid "Default post privacy:"
|
||||
msgstr "Privacidad de publicación por defecto:"
|
||||
|
||||
#: bookwyrm/templates/preferences/layout.html:11
|
||||
msgid "Account"
|
||||
msgstr "Cuenta"
|
||||
|
||||
#: bookwyrm/templates/preferences/layout.html:15
|
||||
#: bookwyrm/templates/user_admin/user_info.html:7
|
||||
msgid "Profile"
|
||||
msgstr "Perfil"
|
||||
|
||||
#: bookwyrm/templates/preferences/layout.html:26
|
||||
#: bookwyrm/templates/preferences/layout.html:27
|
||||
msgid "Relationships"
|
||||
msgstr "Relaciones"
|
||||
|
||||
|
@ -3232,7 +3255,7 @@ msgstr "En orden descendente"
|
|||
msgid "Show more"
|
||||
msgstr "Mostrar más"
|
||||
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:35
|
||||
msgid "Show less"
|
||||
msgstr "Mostrar menos"
|
||||
|
||||
|
@ -3526,7 +3549,7 @@ msgstr "%(title)s: %(subtitle)s"
|
|||
msgid "Not a valid csv file"
|
||||
msgstr "No un archivo csv válido"
|
||||
|
||||
#: bookwyrm/views/login.py:70
|
||||
#: bookwyrm/views/login.py:68
|
||||
msgid "Username or password are incorrect"
|
||||
msgstr "Nombre de usuario o contraseña es incorrecta"
|
||||
|
||||
|
@ -3535,8 +3558,9 @@ msgid "No user with that email address was found."
|
|||
msgstr "No se pudo encontrar un usuario con esa dirección de correo electrónico."
|
||||
|
||||
#: bookwyrm/views/password.py:41
|
||||
#, python-format
|
||||
msgid "A password reset link sent to %s"
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "A password reset link sent to %s"
|
||||
msgid "A password reset link sent to {email}"
|
||||
msgstr "Un enlace para reestablecer tu contraseña se enviará a %s"
|
||||
|
||||
#: bookwyrm/views/rss_feed.py:34
|
||||
|
@ -3544,6 +3568,9 @@ msgstr "Un enlace para reestablecer tu contraseña se enviará a %s"
|
|||
msgid "Status updates from {obj.display_name}"
|
||||
msgstr "Actualizaciones de status de {obj.display_name}"
|
||||
|
||||
#~ msgid "%(count)d uses"
|
||||
#~ msgstr "%(count)d usos"
|
||||
|
||||
#~ msgid "This instance is closed"
|
||||
#~ msgstr "Esta instancia está cerrada."
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue