Merge branch 'main' into import-field-names
This commit is contained in:
commit
915c41f59f
|
@ -36,7 +36,7 @@ FLOWER_PORT=8888
|
||||||
#FLOWER_USER=mouse
|
#FLOWER_USER=mouse
|
||||||
#FLOWER_PASSWORD=changeme
|
#FLOWER_PASSWORD=changeme
|
||||||
|
|
||||||
EMAIL_HOST="smtp.mailgun.org"
|
EMAIL_HOST=smtp.mailgun.org
|
||||||
EMAIL_PORT=587
|
EMAIL_PORT=587
|
||||||
EMAIL_HOST_USER=mail@your.domain.here
|
EMAIL_HOST_USER=mail@your.domain.here
|
||||||
EMAIL_HOST_PASSWORD=emailpassword123
|
EMAIL_HOST_PASSWORD=emailpassword123
|
||||||
|
|
|
@ -36,7 +36,7 @@ FLOWER_PORT=8888
|
||||||
FLOWER_USER=mouse
|
FLOWER_USER=mouse
|
||||||
FLOWER_PASSWORD=changeme
|
FLOWER_PASSWORD=changeme
|
||||||
|
|
||||||
EMAIL_HOST="smtp.mailgun.org"
|
EMAIL_HOST=smtp.mailgun.org
|
||||||
EMAIL_PORT=587
|
EMAIL_PORT=587
|
||||||
EMAIL_HOST_USER=mail@your.domain.here
|
EMAIL_HOST_USER=mail@your.domain.here
|
||||||
EMAIL_HOST_PASSWORD=emailpassword123
|
EMAIL_HOST_PASSWORD=emailpassword123
|
||||||
|
|
|
@ -3,6 +3,7 @@ from dataclasses import MISSING
|
||||||
import imghdr
|
import imghdr
|
||||||
import re
|
import re
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
from dateutil.parser import ParserError
|
from dateutil.parser import ParserError
|
||||||
|
@ -13,11 +14,12 @@ from django.db import models
|
||||||
from django.forms import ClearableFileInput, ImageField as DjangoImageField
|
from django.forms import ClearableFileInput, ImageField as DjangoImageField
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.utils.encoding import filepath_to_uri
|
||||||
|
|
||||||
from bookwyrm import activitypub
|
from bookwyrm import activitypub
|
||||||
from bookwyrm.connectors import get_image
|
from bookwyrm.connectors import get_image
|
||||||
from bookwyrm.sanitize_html import InputHtmlParser
|
from bookwyrm.sanitize_html import InputHtmlParser
|
||||||
from bookwyrm.settings import DOMAIN
|
from bookwyrm.settings import MEDIA_FULL_URL
|
||||||
|
|
||||||
|
|
||||||
def validate_remote_id(value):
|
def validate_remote_id(value):
|
||||||
|
@ -381,17 +383,6 @@ class CustomImageField(DjangoImageField):
|
||||||
widget = ClearableFileInputWithWarning
|
widget = ClearableFileInputWithWarning
|
||||||
|
|
||||||
|
|
||||||
def image_serializer(value, alt):
|
|
||||||
"""helper for serializing images"""
|
|
||||||
if value and hasattr(value, "url"):
|
|
||||||
url = value.url
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
if not url[:4] == "http":
|
|
||||||
url = f"https://{DOMAIN}{url}"
|
|
||||||
return activitypub.Document(url=url, name=alt)
|
|
||||||
|
|
||||||
|
|
||||||
class ImageField(ActivitypubFieldMixin, models.ImageField):
|
class ImageField(ActivitypubFieldMixin, models.ImageField):
|
||||||
"""activitypub-aware image field"""
|
"""activitypub-aware image field"""
|
||||||
|
|
||||||
|
@ -424,7 +415,12 @@ class ImageField(ActivitypubFieldMixin, models.ImageField):
|
||||||
activity[key] = formatted
|
activity[key] = formatted
|
||||||
|
|
||||||
def field_to_activity(self, value, alt=None):
|
def field_to_activity(self, value, alt=None):
|
||||||
return image_serializer(value, alt)
|
url = get_absolute_url(value)
|
||||||
|
|
||||||
|
if not url:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return activitypub.Document(url=url, name=alt)
|
||||||
|
|
||||||
def field_from_activity(self, value):
|
def field_from_activity(self, value):
|
||||||
image_slug = value
|
image_slug = value
|
||||||
|
@ -461,6 +457,20 @@ class ImageField(ActivitypubFieldMixin, models.ImageField):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_absolute_url(value):
|
||||||
|
"""returns an absolute URL for the image"""
|
||||||
|
name = getattr(value, "name")
|
||||||
|
if not name:
|
||||||
|
return None
|
||||||
|
|
||||||
|
url = filepath_to_uri(name)
|
||||||
|
if url is not None:
|
||||||
|
url = url.lstrip("/")
|
||||||
|
url = urljoin(MEDIA_FULL_URL, url)
|
||||||
|
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
class DateTimeField(ActivitypubFieldMixin, models.DateTimeField):
|
class DateTimeField(ActivitypubFieldMixin, models.DateTimeField):
|
||||||
"""activitypub-aware datetime field"""
|
"""activitypub-aware datetime field"""
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ from bookwyrm.settings import ENABLE_PREVIEW_IMAGES
|
||||||
from .activitypub_mixin import ActivitypubMixin, ActivityMixin
|
from .activitypub_mixin import ActivitypubMixin, ActivityMixin
|
||||||
from .activitypub_mixin import OrderedCollectionPageMixin
|
from .activitypub_mixin import OrderedCollectionPageMixin
|
||||||
from .base_model import BookWyrmModel
|
from .base_model import BookWyrmModel
|
||||||
from .fields import image_serializer
|
|
||||||
from .readthrough import ProgressMode
|
from .readthrough import ProgressMode
|
||||||
from . import fields
|
from . import fields
|
||||||
|
|
||||||
|
@ -190,15 +189,24 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
|
||||||
if hasattr(activity, "name"):
|
if hasattr(activity, "name"):
|
||||||
activity.name = self.pure_name
|
activity.name = self.pure_name
|
||||||
activity.type = self.pure_type
|
activity.type = self.pure_type
|
||||||
activity.attachment = [
|
books = [getattr(self, "book", None)] + list(self.mention_books.all())
|
||||||
image_serializer(b.cover, b.alt_text)
|
if len(books) == 1 and books[0].preview_image:
|
||||||
for b in self.mention_books.all()[:4]
|
covers = [
|
||||||
if b.cover
|
activitypub.Document(
|
||||||
]
|
url=fields.get_absolute_url(books[0].preview_image),
|
||||||
if hasattr(self, "book") and self.book.cover:
|
name=books[0].alt_text,
|
||||||
activity.attachment.append(
|
)
|
||||||
image_serializer(self.book.cover, self.book.alt_text)
|
]
|
||||||
)
|
else:
|
||||||
|
covers = [
|
||||||
|
activitypub.Document(
|
||||||
|
url=fields.get_absolute_url(b.cover),
|
||||||
|
name=b.alt_text,
|
||||||
|
)
|
||||||
|
for b in books
|
||||||
|
if b and b.cover
|
||||||
|
]
|
||||||
|
activity.attachment = covers
|
||||||
return activity
|
return activity
|
||||||
|
|
||||||
def to_activity(self, pure=False): # pylint: disable=arguments-differ
|
def to_activity(self, pure=False): # pylint: disable=arguments-differ
|
||||||
|
|
|
@ -1,10 +1,24 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load utilities %}
|
{% load utilities %}
|
||||||
|
|
||||||
{% with user_path=status.user.local_path username=status.user.display_name book_path=status.book.local_poth book_title=book|book_title %}
|
{% with user_path=status.user.local_path username=status.user.display_name book_path=book.local_path book_title=book|book_title %}
|
||||||
|
|
||||||
{% if status.status_type == 'GeneratedNote' %}
|
{% if status.status_type == 'GeneratedNote' %}
|
||||||
{{ status.content|safe }}
|
{% if status.content == 'wants to read' %}
|
||||||
|
{% blocktrans trimmed %}
|
||||||
|
<a href="{{ user_path}}">{{ username }}</a> wants to read <a href="{{ book_path }}">{{ book_title }}</a>
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% endif %}
|
||||||
|
{% if status.content == 'finished reading' %}
|
||||||
|
{% blocktrans trimmed %}
|
||||||
|
<a href="{{ user_path}}">{{ username }}</a> finished reading <a href="{{ book_path }}">{{ book_title }}</a>
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% endif %}
|
||||||
|
{% if status.content == 'started reading' %}
|
||||||
|
{% blocktrans trimmed %}
|
||||||
|
<a href="{{ user_path}}">{{ username }}</a> started reading <a href="{{ book_path }}">{{ book_title }}</a>
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% endif %}
|
||||||
{% elif status.status_type == 'Rating' %}
|
{% elif status.status_type == 'Rating' %}
|
||||||
{% blocktrans trimmed %}
|
{% blocktrans trimmed %}
|
||||||
<a href="{{ user_path}}">{{ username }}</a> rated <a href="{{ book_path }}">{{ book_title }}</a>
|
<a href="{{ user_path}}">{{ username }}</a> rated <a href="{{ book_path }}">{{ book_title }}</a>
|
||||||
|
|
|
@ -46,10 +46,10 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>
|
<label class="label" for="privacy_import">
|
||||||
<span class="label">{% trans "Privacy setting for imported reviews:" %}</span>
|
{% trans "Privacy setting for imported reviews:" %}
|
||||||
{% include 'snippets/privacy_select.html' with no_label=True %}
|
|
||||||
</label>
|
</label>
|
||||||
|
{% include 'snippets/privacy_select.html' with no_label=True privacy_uuid="import" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,18 +10,17 @@
|
||||||
<h1 class="title">{% trans "Import Status" %}</h1>
|
<h1 class="title">{% trans "Import Status" %}</h1>
|
||||||
<a href="{% url 'import' %}" class="has-text-weight-normal help subtitle is-link">{% trans "Back to imports" %}</a>
|
<a href="{% url 'import' %}" class="has-text-weight-normal help subtitle is-link">{% trans "Back to imports" %}</a>
|
||||||
|
|
||||||
|
{% if task.failed %}
|
||||||
|
<div class="notification is-danger">{% trans "TASK FAILED" %}</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<div class="is-flex">
|
<dt class="is-pulled-left mr-5">{% trans "Import started:" %}</dt>
|
||||||
<dt class="has-text-weight-medium">{% trans "Import started:" %}</dt>
|
<dd>{{ job.created_date | naturaltime }}</dd>
|
||||||
<dd class="ml-2">{{ job.created_date | naturaltime }}</dd>
|
|
||||||
</div>
|
|
||||||
{% if job.complete %}
|
{% if job.complete %}
|
||||||
<div class="is-flex">
|
<dt class="is-pulled-left mr-5">{% trans "Import completed:" %}</dt>
|
||||||
<dt class="has-text-weight-medium">{% trans "Import completed:" %}</dt>
|
<dd>{{ task.date_done | naturaltime }}</dd>
|
||||||
<dd class="ml-2">{{ task.date_done | naturaltime }}</dd>
|
|
||||||
</div>
|
|
||||||
{% elif task.failed %}
|
|
||||||
<div class="notification is-danger">{% trans "TASK FAILED" %}</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,6 +22,7 @@ from bookwyrm.activitypub.base_activity import ActivityObject
|
||||||
from bookwyrm.models import fields, User, Status
|
from bookwyrm.models import fields, User, Status
|
||||||
from bookwyrm.models.base_model import BookWyrmModel
|
from bookwyrm.models.base_model import BookWyrmModel
|
||||||
from bookwyrm.models.activitypub_mixin import ActivitypubMixin
|
from bookwyrm.models.activitypub_mixin import ActivitypubMixin
|
||||||
|
from bookwyrm.settings import DOMAIN
|
||||||
|
|
||||||
# pylint: disable=too-many-public-methods
|
# pylint: disable=too-many-public-methods
|
||||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||||
|
@ -424,21 +425,18 @@ class ModelFields(TestCase):
|
||||||
image.save(output, format=image.format)
|
image.save(output, format=image.format)
|
||||||
user.avatar.save("test.jpg", ContentFile(output.getvalue()))
|
user.avatar.save("test.jpg", ContentFile(output.getvalue()))
|
||||||
|
|
||||||
output = fields.image_serializer(user.avatar, alt="alt text")
|
instance = fields.ImageField()
|
||||||
|
|
||||||
|
output = instance.field_to_activity(user.avatar)
|
||||||
self.assertIsNotNone(
|
self.assertIsNotNone(
|
||||||
re.match(
|
re.match(
|
||||||
r".*\.jpg",
|
fr"https:\/\/{DOMAIN}\/.*\.jpg",
|
||||||
output.url,
|
output.url,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(output.name, "alt text")
|
self.assertEqual(output.name, "")
|
||||||
self.assertEqual(output.type, "Document")
|
self.assertEqual(output.type, "Document")
|
||||||
|
|
||||||
instance = fields.ImageField()
|
|
||||||
|
|
||||||
output = fields.image_serializer(user.avatar, alt=None)
|
|
||||||
self.assertEqual(instance.field_to_activity(user.avatar), output)
|
|
||||||
|
|
||||||
responses.add(
|
responses.add(
|
||||||
responses.GET,
|
responses.GET,
|
||||||
"http://www.example.com/image.jpg",
|
"http://www.example.com/image.jpg",
|
||||||
|
@ -449,15 +447,6 @@ class ModelFields(TestCase):
|
||||||
self.assertIsInstance(loaded_image, list)
|
self.assertIsInstance(loaded_image, list)
|
||||||
self.assertIsInstance(loaded_image[1], ContentFile)
|
self.assertIsInstance(loaded_image[1], ContentFile)
|
||||||
|
|
||||||
def test_image_serialize(self, *_):
|
|
||||||
"""make sure we're creating sensible image paths"""
|
|
||||||
ValueMock = namedtuple("ValueMock", ("url"))
|
|
||||||
value_mock = ValueMock("/images/fish.jpg")
|
|
||||||
result = fields.image_serializer(value_mock, "hello")
|
|
||||||
self.assertEqual(result.type, "Document")
|
|
||||||
self.assertEqual(result.url, "https://your.domain.here/images/fish.jpg")
|
|
||||||
self.assertEqual(result.name, "hello")
|
|
||||||
|
|
||||||
def test_datetime_field(self, *_):
|
def test_datetime_field(self, *_):
|
||||||
"""this one is pretty simple, it just has to use isoformat"""
|
"""this one is pretty simple, it just has to use isoformat"""
|
||||||
instance = fields.DateTimeField()
|
instance = fields.DateTimeField()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import re
|
||||||
|
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
|
@ -190,9 +191,11 @@ class Status(TestCase):
|
||||||
self.assertEqual(activity["sensitive"], False)
|
self.assertEqual(activity["sensitive"], False)
|
||||||
self.assertIsInstance(activity["attachment"], list)
|
self.assertIsInstance(activity["attachment"], list)
|
||||||
self.assertEqual(activity["attachment"][0].type, "Document")
|
self.assertEqual(activity["attachment"][0].type, "Document")
|
||||||
self.assertEqual(
|
self.assertTrue(
|
||||||
activity["attachment"][0].url,
|
re.match(
|
||||||
f"https://{settings.DOMAIN}{self.book.cover.url}",
|
r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg",
|
||||||
|
activity["attachment"][0].url,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
||||||
|
|
||||||
|
@ -220,9 +223,11 @@ class Status(TestCase):
|
||||||
f'test content<p>(comment on <a href="{self.book.remote_id}">"Test Edition"</a>)</p>',
|
f'test content<p>(comment on <a href="{self.book.remote_id}">"Test Edition"</a>)</p>',
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["attachment"][0].type, "Document")
|
self.assertEqual(activity["attachment"][0].type, "Document")
|
||||||
self.assertEqual(
|
self.assertTrue(
|
||||||
activity["attachment"][0].url,
|
re.match(
|
||||||
f"https://{settings.DOMAIN}{self.book.cover.url}",
|
r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg",
|
||||||
|
activity["attachment"][0].url,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
||||||
|
|
||||||
|
@ -257,9 +262,11 @@ class Status(TestCase):
|
||||||
f'a sickening sense <p>-- <a href="{self.book.remote_id}">"Test Edition"</a></p>test content',
|
f'a sickening sense <p>-- <a href="{self.book.remote_id}">"Test Edition"</a></p>test content',
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["attachment"][0].type, "Document")
|
self.assertEqual(activity["attachment"][0].type, "Document")
|
||||||
self.assertEqual(
|
self.assertTrue(
|
||||||
activity["attachment"][0].url,
|
re.match(
|
||||||
f"https://{settings.DOMAIN}{self.book.cover.url}",
|
r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg",
|
||||||
|
activity["attachment"][0].url,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
||||||
|
|
||||||
|
@ -298,9 +305,11 @@ class Status(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["content"], "test content")
|
self.assertEqual(activity["content"], "test content")
|
||||||
self.assertEqual(activity["attachment"][0].type, "Document")
|
self.assertEqual(activity["attachment"][0].type, "Document")
|
||||||
self.assertEqual(
|
self.assertTrue(
|
||||||
activity["attachment"][0].url,
|
re.match(
|
||||||
f"https://{settings.DOMAIN}{self.book.cover.url}",
|
r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg",
|
||||||
|
activity["attachment"][0].url,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
||||||
|
|
||||||
|
@ -320,9 +329,11 @@ class Status(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["content"], "test content")
|
self.assertEqual(activity["content"], "test content")
|
||||||
self.assertEqual(activity["attachment"][0].type, "Document")
|
self.assertEqual(activity["attachment"][0].type, "Document")
|
||||||
self.assertEqual(
|
self.assertTrue(
|
||||||
activity["attachment"][0].url,
|
re.match(
|
||||||
f"https://{settings.DOMAIN}{self.book.cover.url}",
|
r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg",
|
||||||
|
activity["attachment"][0].url,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
||||||
|
|
||||||
|
@ -341,9 +352,11 @@ class Status(TestCase):
|
||||||
f'rated <em><a href="{self.book.remote_id}">{self.book.title}</a></em>: 3 stars',
|
f'rated <em><a href="{self.book.remote_id}">{self.book.title}</a></em>: 3 stars',
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["attachment"][0].type, "Document")
|
self.assertEqual(activity["attachment"][0].type, "Document")
|
||||||
self.assertEqual(
|
self.assertTrue(
|
||||||
activity["attachment"][0].url,
|
re.match(
|
||||||
f"https://{settings.DOMAIN}{self.book.cover.url}",
|
r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg",
|
||||||
|
activity["attachment"][0].url,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
self.assertEqual(activity["attachment"][0].name, "Test Edition")
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.template.response import TemplateResponse
|
from django.template.response import TemplateResponse
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
|
from bookwyrm.tests.validate_html import validate_html
|
||||||
|
|
||||||
from bookwyrm import forms, models, views
|
from bookwyrm import forms, models, views
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ class ImportViews(TestCase):
|
||||||
request.user = self.local_user
|
request.user = self.local_user
|
||||||
result = view(request)
|
result = view(request)
|
||||||
self.assertIsInstance(result, TemplateResponse)
|
self.assertIsInstance(result, TemplateResponse)
|
||||||
result.render()
|
validate_html(result.render())
|
||||||
self.assertEqual(result.status_code, 200)
|
self.assertEqual(result.status_code, 200)
|
||||||
|
|
||||||
def test_import_status(self):
|
def test_import_status(self):
|
||||||
|
@ -47,7 +48,7 @@ class ImportViews(TestCase):
|
||||||
async_result.return_value = []
|
async_result.return_value = []
|
||||||
result = view(request, import_job.id)
|
result = view(request, import_job.id)
|
||||||
self.assertIsInstance(result, TemplateResponse)
|
self.assertIsInstance(result, TemplateResponse)
|
||||||
result.render()
|
validate_html(result.render())
|
||||||
self.assertEqual(result.status_code, 200)
|
self.assertEqual(result.status_code, 200)
|
||||||
|
|
||||||
def test_start_import(self):
|
def test_start_import(self):
|
||||||
|
@ -59,7 +60,10 @@ class ImportViews(TestCase):
|
||||||
form.data["include_reviews"] = False
|
form.data["include_reviews"] = False
|
||||||
csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv")
|
csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv")
|
||||||
form.data["csv_file"] = SimpleUploadedFile(
|
form.data["csv_file"] = SimpleUploadedFile(
|
||||||
csv_file, open(csv_file, "rb").read(), content_type="text/csv"
|
# pylint: disable=consider-using-with
|
||||||
|
csv_file,
|
||||||
|
open(csv_file, "rb").read(),
|
||||||
|
content_type="text/csv",
|
||||||
)
|
)
|
||||||
|
|
||||||
request = self.factory.post("", form.data)
|
request = self.factory.post("", form.data)
|
||||||
|
|
13
bw-dev
13
bw-dev
|
@ -61,7 +61,7 @@ case "$CMD" in
|
||||||
up)
|
up)
|
||||||
docker-compose up --build "$@"
|
docker-compose up --build "$@"
|
||||||
;;
|
;;
|
||||||
run)
|
service_ports_web)
|
||||||
docker-compose run --rm --service-ports web
|
docker-compose run --rm --service-ports web
|
||||||
;;
|
;;
|
||||||
initdb)
|
initdb)
|
||||||
|
@ -96,9 +96,6 @@ case "$CMD" in
|
||||||
restart_celery)
|
restart_celery)
|
||||||
docker-compose restart celery_worker
|
docker-compose restart celery_worker
|
||||||
;;
|
;;
|
||||||
test)
|
|
||||||
runweb coverage run --source='.' --omit="*/test*,celerywyrm*,bookwyrm/migrations/*" manage.py test "$@"
|
|
||||||
;;
|
|
||||||
pytest)
|
pytest)
|
||||||
execweb pytest --no-cov-on-fail "$@"
|
execweb pytest --no-cov-on-fail "$@"
|
||||||
;;
|
;;
|
||||||
|
@ -148,14 +145,11 @@ case "$CMD" in
|
||||||
runweb)
|
runweb)
|
||||||
runweb "$@"
|
runweb "$@"
|
||||||
;;
|
;;
|
||||||
rundb)
|
|
||||||
rundb "$@"
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
set +x # No need to echo echo
|
set +x # No need to echo echo
|
||||||
echo "Unrecognised command. Try:"
|
echo "Unrecognised command. Try:"
|
||||||
echo " up [container]"
|
echo " up [container]"
|
||||||
echo " run"
|
echo " service_ports_web"
|
||||||
echo " initdb"
|
echo " initdb"
|
||||||
echo " resetdb"
|
echo " resetdb"
|
||||||
echo " makemigrations [migration]"
|
echo " makemigrations [migration]"
|
||||||
|
@ -164,10 +158,8 @@ case "$CMD" in
|
||||||
echo " shell"
|
echo " shell"
|
||||||
echo " dbshell"
|
echo " dbshell"
|
||||||
echo " restart_celery"
|
echo " restart_celery"
|
||||||
echo " test [path]"
|
|
||||||
echo " pytest [path]"
|
echo " pytest [path]"
|
||||||
echo " collectstatic"
|
echo " collectstatic"
|
||||||
echo " add_locale [locale]"
|
|
||||||
echo " makemessages"
|
echo " makemessages"
|
||||||
echo " compilemessages [locale]"
|
echo " compilemessages [locale]"
|
||||||
echo " build"
|
echo " build"
|
||||||
|
@ -180,6 +172,5 @@ case "$CMD" in
|
||||||
echo " copy_media_to_s3"
|
echo " copy_media_to_s3"
|
||||||
echo " set_cors_to_s3 [cors file]"
|
echo " set_cors_to_s3 [cors file]"
|
||||||
echo " runweb [command]"
|
echo " runweb [command]"
|
||||||
echo " rundb [command]"
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -27,7 +27,7 @@ server {
|
||||||
#
|
#
|
||||||
# client_max_body_size 3M;
|
# client_max_body_size 3M;
|
||||||
#
|
#
|
||||||
# if ($host != "you-domain.com") {
|
# if ($host != "your-domain.com") {
|
||||||
# return 301 $scheme://your-domain.com$request_uri;
|
# return 301 $scheme://your-domain.com$request_uri;
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
|
|
|
@ -20,7 +20,6 @@ django-storages==1.11.1
|
||||||
|
|
||||||
# Dev
|
# Dev
|
||||||
black==21.4b0
|
black==21.4b0
|
||||||
coverage==5.1
|
|
||||||
pytest-django==4.1.0
|
pytest-django==4.1.0
|
||||||
pytest==6.1.2
|
pytest==6.1.2
|
||||||
pytest-cov==2.10.1
|
pytest-cov==2.10.1
|
||||||
|
|
Loading…
Reference in New Issue