Merge pull request #354 from cincodenada/progress_update

Keep track of progress through books over time
This commit is contained in:
Mouse Reeve 2021-01-21 16:57:16 -08:00 committed by GitHub
commit 6c52afeae0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 423 additions and 26 deletions

View file

@ -65,4 +65,4 @@ jobs:
EMAIL_HOST_PASSWORD: "" EMAIL_HOST_PASSWORD: ""
EMAIL_USE_TLS: true EMAIL_USE_TLS: true
run: | run: |
python manage.py test python manage.py test -v 3

View file

@ -0,0 +1,31 @@
# Generated by Django 3.0.7 on 2020-11-17 07:36
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0011_auto_20201113_1727'),
]
operations = [
migrations.CreateModel(
name='ProgressUpdate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_date', models.DateTimeField(auto_now_add=True)),
('updated_date', models.DateTimeField(auto_now=True)),
('remote_id', models.CharField(max_length=255, null=True)),
('progress', models.IntegerField()),
('mode', models.CharField(choices=[('PG', 'page'), ('PCT', 'percent')], default='PG', max_length=3)),
('readthrough', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='bookwyrm.ReadThrough')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
]

View file

@ -0,0 +1,14 @@
# Generated by Django 3.0.7 on 2020-11-28 00:07
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0013_book_origin_id'),
('bookwyrm', '0012_progressupdate'),
]
operations = [
]

View file

@ -0,0 +1,23 @@
# Generated by Django 3.0.7 on 2020-11-28 07:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0014_merge_20201128_0007'),
]
operations = [
migrations.RenameField(
model_name='readthrough',
old_name='pages_read',
new_name='progress',
),
migrations.AddField(
model_name='readthrough',
name='progress_mode',
field=models.CharField(choices=[('PG', 'page'), ('PCT', 'percent')], default='PG', max_length=3),
),
]

View file

@ -0,0 +1,14 @@
# Generated by Django 3.0.7 on 2021-01-20 07:53
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0038_auto_20210119_1534'),
('bookwyrm', '0015_auto_20201128_0734'),
]
operations = [
]

View file

@ -13,7 +13,7 @@ from .status import Boost
from .attachment import Image from .attachment import Image
from .favorite import Favorite from .favorite import Favorite
from .notification import Notification from .notification import Notification
from .readthrough import ReadThrough from .readthrough import ReadThrough, ProgressUpdate, ProgressMode
from .tag import Tag, UserTag from .tag import Tag, UserTag

View file

@ -72,6 +72,10 @@ class Book(BookDataModel):
''' format a list of authors ''' ''' format a list of authors '''
return ', '.join(a.name for a in self.authors.all()) return ', '.join(a.name for a in self.authors.all())
@property
def latest_readthrough(self):
return self.readthrough_set.order_by('-updated_date').first()
@property @property
def edition_info(self): def edition_info(self):
''' properties of this edition, as a string ''' ''' properties of this edition, as a string '''

View file

@ -1,17 +1,26 @@
''' progress in a book ''' ''' progress in a book '''
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from django.core import validators
from .base_model import BookWyrmModel from .base_model import BookWyrmModel
class ProgressMode(models.TextChoices):
PAGE = 'PG', 'page'
PERCENT = 'PCT', 'percent'
class ReadThrough(BookWyrmModel): class ReadThrough(BookWyrmModel):
''' Store progress through a book in the database. ''' ''' Store a read through a book in the database. '''
user = models.ForeignKey('User', on_delete=models.PROTECT) user = models.ForeignKey('User', on_delete=models.PROTECT)
book = models.ForeignKey('Edition', on_delete=models.PROTECT) book = models.ForeignKey('Edition', on_delete=models.PROTECT)
pages_read = models.IntegerField( progress = models.IntegerField(
validators=[validators.MinValueValidator(0)],
null=True, null=True,
blank=True) blank=True)
progress_mode = models.CharField(
max_length=3,
choices=ProgressMode.choices,
default=ProgressMode.PAGE)
start_date = models.DateTimeField( start_date = models.DateTimeField(
blank=True, blank=True,
null=True) null=True)
@ -24,3 +33,26 @@ class ReadThrough(BookWyrmModel):
self.user.last_active_date = timezone.now() self.user.last_active_date = timezone.now()
self.user.save() self.user.save()
super().save(*args, **kwargs) super().save(*args, **kwargs)
def create_update(self):
if self.progress:
return self.progressupdate_set.create(
user=self.user,
progress=self.progress,
mode=self.progress_mode)
class ProgressUpdate(BookWyrmModel):
''' Store progress through a book in the database. '''
user = models.ForeignKey('User', on_delete=models.PROTECT)
readthrough = models.ForeignKey('ReadThrough', on_delete=models.CASCADE)
progress = models.IntegerField(validators=[validators.MinValueValidator(0)])
mode = models.CharField(
max_length=3,
choices=ProgressMode.choices,
default=ProgressMode.PAGE)
def save(self, *args, **kwargs):
''' update user active time '''
self.user.last_active_date = timezone.now()
self.user.save()
super().save(*args, **kwargs)

View file

@ -48,6 +48,10 @@
</div> </div>
<div class="card-content"> <div class="card-content">
{% include 'snippets/shelve_button.html' with book=book %} {% include 'snippets/shelve_button.html' with book=book %}
{% active_shelf book as active_shelf %}
{% if active_shelf.shelf.identifier == 'reading' and book.latest_readthrough %}
{% include 'snippets/progress_update.html' with readthrough=book.latest_readthrough %}
{% endif %}
{% include 'snippets/create_status.html' with book=book %} {% include 'snippets/create_status.html' with book=book %}
</div> </div>
</div> </div>

View file

@ -7,11 +7,10 @@
</h2> </h2>
{% include 'snippets/toggle/toggle_button.html' with label="close" class="delete" nonbutton=True %} {% include 'snippets/toggle/toggle_button.html' with label="close" class="delete" nonbutton=True %}
</header> </header>
{% block modal-form-open %}{% endblock %} {% block modal-form-open %}{% endblock %}
<section class="modal-card-body">
{% block modal-body %}{% endblock %} {% block modal-body %}{% endblock %}
</section>
<footer class="modal-card-foot"> <footer class="modal-card-foot">
{% block modal-footer %}{% endblock %} {% block modal-footer %}{% endblock %}
</footer> </footer>

View file

@ -1,6 +1,10 @@
{% extends 'snippets/components/modal.html' %} {% extends 'snippets/components/modal.html' %}
{% block modal-title %}Delete these read dates?{% endblock %} {% block modal-title %}Delete these read dates?{% endblock %}
{% block modal-body %}
{% if readthrough.progress_updates|length > 0 %}
You are deleting this readthrough and its {{ readthrough.progress_updates|length }} associated progress updates.
{% endif %}
{% endblock %}
{% block modal-footer %} {% block modal-footer %}
<form name="delete-readthrough-{{ readthrough.id }}" action="/delete-readthrough" method="POST"> <form name="delete-readthrough-{{ readthrough.id }}" action="/delete-readthrough" method="POST">
{% csrf_token %} {% csrf_token %}

View file

@ -0,0 +1,27 @@
<form class="field is-grouped is-small" action="/edit-readthrough" method="POST">
{% csrf_token %}
<input type="hidden" name="id" value="{{ readthrough.id }}"/>
<label class="label is-align-self-center mb-0 pr-2" for="progress">Currently at</label>
<div class="control">
<div class="field has-addons">
<div class="control">
<input
aria-label="{% if readthrough.progress_mode == 'PG' %}Current page{% else %}Percent read{% endif %}"
class="input is-small" type="number"
name="progress" size="3" value="{{ readthrough.progress|default:'' }}">
</div>
<div class="control">
<a class="button is-small is-static">
{% if readthrough.progress_mode == 'PG' %}
pages
{% else %}
%
{% endif %}
</a>
</div>
</div>
</div>
<div class="control">
<button class="button is-small px-2" type="submit">Save</button>
</div>
</form>

View file

@ -13,6 +13,15 @@
<dt>Finished reading:</dt> <dt>Finished reading:</dt>
<dd>{{ readthrough.finish_date | naturalday }}</dd> <dd>{{ readthrough.finish_date | naturalday }}</dd>
</div> </div>
{% elif readthrough.progress %}
<div class="is-flex">
<dt>Progress:</dt>
{% if readthrough.progress_mode == 'PG' %}
<dd>on page {{ readthrough.progress }} of {{ book.pages }}</dd>
{% else %}
<dd>{{ readthrough.progress }}%</dd>
{% endif %}
</div>
{% endif %} {% endif %}
</dl> </dl>
<div class="field has-addons"> <div class="field has-addons">
@ -23,6 +32,36 @@
{% include 'snippets/toggle/toggle_button.html' with class="is-small" text="Delete these read dates" icon="x" controls_text="delete-readthrough" controls_uid=readthrough.id focus="modal-title-delete-readthrough" %} {% include 'snippets/toggle/toggle_button.html' with class="is-small" text="Delete these read dates" icon="x" controls_text="delete-readthrough" controls_uid=readthrough.id focus="modal-title-delete-readthrough" %}
</div> </div>
</div> </div>
{% if show_progress %}
Progress Updates:
<ul>
{% if readthrough.finish_date %}
<li>{{ readthrough.start_date | naturalday }}: finished</li>
{% endif %}
{% for progress_update in readthrough.progress_updates %}
<li>
<form name="delete-update" action="/delete-progressupdate" method="POST">
{% csrf_token %}
{{ progress_update.created_date | naturalday }}:
{% if progress_update.mode == 'PG' %}
page {{ progress_update.progress }} of {{ book.pages }}
{% else %}
{{ progress_update.progress }}%
{% endif %}
<input type="hidden" name="id" value="{{ progress_update.id }}"/>
<button type="submit" class="button is-small" for="delete-progressupdate-{{ progress_update.id }}" role="button" tabindex="0">
<span class="icon icon-x">
<span class="is-sr-only">Delete this progress update</span>
</span>
</button>
</form>
</li>
{% endfor %}
<li>{{ readthrough.start_date | naturalday }}: started</li>
</ul>
{% elif readthrough.progress_updates|length %}
<a href="?showprogress">Show {{ readthrough.progress_updates|length }} Progress Updates</a>
{% endif %}
</div> </div>
</div> </div>

View file

@ -7,6 +7,31 @@
<input type="date" name="start_date" class="input" id="id_start_date-{{ readthrough.id }}" value="{{ readthrough.start_date | date:"Y-m-d" }}"> <input type="date" name="start_date" class="input" id="id_start_date-{{ readthrough.id }}" value="{{ readthrough.start_date | date:"Y-m-d" }}">
</label> </label>
</div> </div>
{# Only show progress for editing existing readthroughs #}
{% if readthrough.id and not readthrough.finish_date %}
<div class="columns">
<div class="column">
<div class="field">
<label class="label">
Progress
<input type="number" name="progress" class="input" id="id_progress-{{ readthrough.id }}" value="{{ readthrough.progress }}">
</label>
</div>
</div>
<div class="column">
<div class="control mt-5">
<label class="radio">
<input type="radio" name="progress_mode" id="id_progress_mode-{{ readthrough.id }}" value="PG" {% if readthrough.progress_mode == 'PG' %}checked{% endif %}>
pages
</label>
<label class="radio">
<input type="radio" name="progress_mode" id="id_progress_mode-{{ readthrough.id }}" value="PCT" {% if readthrough.progress_mode == 'PCT' %}checked{% endif %}>
percent
</label>
</div>
</div>
</div>
{% endif %}
<div class="field"> <div class="field">
<label class="label"> <label class="label">
Finished reading Finished reading

View file

@ -0,0 +1 @@
from . import *

View file

@ -0,0 +1,88 @@
from unittest.mock import patch
from django.test import TestCase, Client
from django.utils import timezone
from datetime import datetime
from bookwyrm import models
@patch('bookwyrm.broadcast.broadcast_task.delay')
class ReadThrough(TestCase):
def setUp(self):
self.client = Client()
self.work = models.Work.objects.create(
title='Example Work'
)
self.edition = models.Edition.objects.create(
title='Example Edition',
parent_work=self.work
)
self.work.default_edition = self.edition
self.work.save()
self.user = models.User.objects.create_user(
'cinco', 'cinco@example.com', 'seissiete',
local=True, localname='cinco')
self.client.force_login(self.user)
def test_create_basic_readthrough(self, delay_mock):
"""A basic readthrough doesn't create a progress update"""
self.assertEqual(self.edition.readthrough_set.count(), 0)
self.client.post('/start-reading/{}'.format(self.edition.id), {
'start_date': '2020-11-27',
})
readthroughs = self.edition.readthrough_set.all()
self.assertEqual(len(readthroughs), 1)
self.assertEqual(readthroughs[0].progressupdate_set.count(), 0)
self.assertEqual(readthroughs[0].start_date,
datetime(2020, 11, 27, tzinfo=timezone.utc))
self.assertEqual(readthroughs[0].progress, None)
self.assertEqual(readthroughs[0].finish_date, None)
self.assertEqual(delay_mock.call_count, 1)
def test_create_progress_readthrough(self, delay_mock):
self.assertEqual(self.edition.readthrough_set.count(), 0)
self.client.post('/start-reading/{}'.format(self.edition.id), {
'start_date': '2020-11-27',
'progress': 50,
})
readthroughs = self.edition.readthrough_set.all()
self.assertEqual(len(readthroughs), 1)
self.assertEqual(readthroughs[0].start_date,
datetime(2020, 11, 27, tzinfo=timezone.utc))
self.assertEqual(readthroughs[0].progress, 50)
self.assertEqual(readthroughs[0].finish_date, None)
progress_updates = readthroughs[0].progressupdate_set.all()
self.assertEqual(len(progress_updates), 1)
self.assertEqual(progress_updates[0].mode, models.ProgressMode.PAGE)
self.assertEqual(progress_updates[0].progress, 50)
self.assertEqual(delay_mock.call_count, 1)
# Update progress
self.client.post('/edit-readthrough', {
'id': readthroughs[0].id,
'progress': 100,
})
progress_updates = readthroughs[0].progressupdate_set\
.order_by('updated_date').all()
self.assertEqual(len(progress_updates), 2)
self.assertEqual(progress_updates[1].mode, models.ProgressMode.PAGE)
self.assertEqual(progress_updates[1].progress, 100)
self.assertEqual(delay_mock.call_count, 1) # Edit doesn't publish anything
self.client.post('/delete-readthrough', {
'id': readthroughs[0].id,
})
readthroughs = self.edition.readthrough_set.all()
updates = self.user.progressupdate_set.all()
self.assertEqual(len(readthroughs), 0)
self.assertEqual(len(updates), 0)

View file

@ -23,9 +23,9 @@ class BookWyrmConnector(TestCase):
self.connector = Connector('example.com') self.connector = Connector('example.com')
work_file = pathlib.Path(__file__).parent.joinpath( work_file = pathlib.Path(__file__).parent.joinpath(
'../data/fr_work.json') '../data/bw_work.json')
edition_file = pathlib.Path(__file__).parent.joinpath( edition_file = pathlib.Path(__file__).parent.joinpath(
'../data/fr_edition.json') '../data/bw_edition.json')
self.work_data = json.loads(work_file.read_bytes()) self.work_data = json.loads(work_file.read_bytes())
self.edition_data = json.loads(edition_file.read_bytes()) self.edition_data = json.loads(edition_file.read_bytes())
@ -33,7 +33,7 @@ class BookWyrmConnector(TestCase):
def test_format_search_result(self): def test_format_search_result(self):
''' create a SearchResult object from search response json ''' ''' create a SearchResult object from search response json '''
datafile = pathlib.Path(__file__).parent.joinpath( datafile = pathlib.Path(__file__).parent.joinpath(
'../data/fr_search.json') '../data/bw_search.json')
search_data = json.loads(datafile.read_bytes()) search_data = json.loads(datafile.read_bytes())
results = self.connector.parse_search_data(search_data) results = self.connector.parse_search_data(search_data)
self.assertIsInstance(results, list) self.assertIsInstance(results, list)

View file

@ -0,0 +1,51 @@
''' testing models '''
from django.test import TestCase
from django.core.exceptions import ValidationError
from bookwyrm import models, settings
class ReadThrough(TestCase):
''' some activitypub oddness ahead '''
def setUp(self):
''' look, a shelf '''
self.user = models.User.objects.create_user(
'mouse', 'mouse@mouse.mouse', 'mouseword',
local=True, localname='mouse')
self.work = models.Work.objects.create(
title='Example Work'
)
self.edition = models.Edition.objects.create(
title='Example Edition',
parent_work=self.work
)
self.work.default_edition = self.edition
self.work.save()
self.readthrough = models.ReadThrough.objects.create(
user=self.user,
book=self.edition)
def test_progress_update(self):
''' Test progress updates '''
self.readthrough.create_update() # No-op, no progress yet
self.readthrough.progress = 10
self.readthrough.create_update()
self.readthrough.progress = 20
self.readthrough.progress_mode = models.ProgressMode.PERCENT
self.readthrough.create_update()
updates = self.readthrough.progressupdate_set \
.order_by('created_date').all()
self.assertEqual(len(updates), 2)
self.assertEqual(updates[0].progress, 10)
self.assertEqual(updates[0].mode, models.ProgressMode.PAGE)
self.assertEqual(updates[1].progress, 20)
self.assertEqual(updates[1].mode, models.ProgressMode.PERCENT)
self.readthrough.progress = -10
self.assertRaises(ValidationError, self.readthrough.clean_fields)
update = self.readthrough.create_update()
self.assertRaises(ValidationError, update.clean_fields)

View file

@ -32,14 +32,14 @@ class Book(TestCase):
inbox='http://example.com/u/2/inbox') inbox='http://example.com/u/2/inbox')
self.user.followers.add(no_inbox_follower) self.user.followers.add(no_inbox_follower)
non_fr_follower = models.User.objects.create_user( non_bw_follower = models.User.objects.create_user(
'gerbil', 'gerb@mouse.mouse', 'gerbword', 'gerbil', 'gerb@mouse.mouse', 'gerbword',
remote_id='http://example.com/u/3', remote_id='http://example.com/u/3',
outbox='http://example2.com/u/3/o', outbox='http://example2.com/u/3/o',
inbox='http://example2.com/u/3/inbox', inbox='http://example2.com/u/3/inbox',
shared_inbox='http://example2.com/inbox', shared_inbox='http://example2.com/inbox',
bookwyrm_user=False, local=False) bookwyrm_user=False, local=False)
self.user.followers.add(non_fr_follower) self.user.followers.add(non_bw_follower)
models.User.objects.create_user( models.User.objects.create_user(
'nutria', 'nutria@mouse.mouse', 'nuword', 'nutria', 'nutria@mouse.mouse', 'nuword',

View file

@ -506,7 +506,7 @@ class Incoming(TestCase):
def test_handle_update_edition(self): def test_handle_update_edition(self):
''' update an existing edition ''' ''' update an existing edition '''
datafile = pathlib.Path(__file__).parent.joinpath( datafile = pathlib.Path(__file__).parent.joinpath(
'data/fr_edition.json') 'data/bw_edition.json')
bookdata = json.loads(datafile.read_bytes()) bookdata = json.loads(datafile.read_bytes())
models.Work.objects.create( models.Work.objects.create(
@ -527,7 +527,7 @@ class Incoming(TestCase):
def test_handle_update_work(self): def test_handle_update_work(self):
''' update an existing edition ''' ''' update an existing edition '''
datafile = pathlib.Path(__file__).parent.joinpath( datafile = pathlib.Path(__file__).parent.joinpath(
'data/fr_work.json') 'data/bw_work.json')
bookdata = json.loads(datafile.read_bytes()) bookdata = json.loads(datafile.read_bytes())
book = models.Work.objects.create( book = models.Work.objects.create(

View file

@ -126,6 +126,7 @@ urlpatterns = [
re_path(r'^edit-readthrough/?$', views.edit_readthrough), re_path(r'^edit-readthrough/?$', views.edit_readthrough),
re_path(r'^delete-readthrough/?$', views.delete_readthrough), re_path(r'^delete-readthrough/?$', views.delete_readthrough),
re_path(r'^create-readthrough/?$', views.create_readthrough), re_path(r'^create-readthrough/?$', views.create_readthrough),
re_path(r'^delete-progressupdate/?$', views.delete_progressupdate),
re_path(r'^start-reading/(?P<book_id>\d+)/?$', views.start_reading), re_path(r'^start-reading/(?P<book_id>\d+)/?$', views.start_reading),
re_path(r'^finish-reading/(?P<book_id>\d+)/?$', views.finish_reading), re_path(r'^finish-reading/(?P<book_id>\d+)/?$', views.finish_reading),

View file

@ -15,7 +15,7 @@ from .landing import About, Home, Feed, Discover
from .notifications import Notifications from .notifications import Notifications
from .outbox import Outbox from .outbox import Outbox
from .reading import edit_readthrough, create_readthrough, delete_readthrough from .reading import edit_readthrough, create_readthrough, delete_readthrough
from .reading import start_reading, finish_reading from .reading import start_reading, finish_reading, delete_progressupdate
from .password import PasswordResetRequest, PasswordReset, ChangePassword from .password import PasswordResetRequest, PasswordReset, ChangePassword
from .tag import Tag, AddTag, RemoveTag from .tag import Tag, AddTag, RemoveTag
from .search import Search from .search import Search

View file

@ -72,6 +72,10 @@ class Book(View):
book=book, book=book,
).order_by('start_date') ).order_by('start_date')
for readthrough in readthroughs:
readthrough.progress_updates = \
readthrough.progressupdate_set.all().order_by('-updated_date')
user_shelves = models.ShelfBook.objects.filter( user_shelves = models.ShelfBook.objects.filter(
added_by=request.user, book=book added_by=request.user, book=book
) )
@ -94,6 +98,7 @@ class Book(View):
'user_shelves': user_shelves, 'user_shelves': user_shelves,
'other_edition_shelves': other_edition_shelves, 'other_edition_shelves': other_edition_shelves,
'readthroughs': readthroughs, 'readthroughs': readthroughs,
'show_progress': ('showprogress' in request.GET),
'path': '/book/%s' % book_id, 'path': '/book/%s' % book_id,
} }
return TemplateResponse(request, 'book.html', data) return TemplateResponse(request, 'book.html', data)

View file

@ -30,6 +30,9 @@ def start_reading(request, book_id):
if readthrough: if readthrough:
readthrough.save() readthrough.save()
# create a progress update if we have a page
readthrough.create_update()
# shelve the book # shelve the book
if request.POST.get('reshelve', True): if request.POST.get('reshelve', True):
try: try:
@ -104,6 +107,10 @@ def edit_readthrough(request):
return HttpResponseBadRequest() return HttpResponseBadRequest()
readthrough.save() readthrough.save()
# record the progress update individually
# use default now for date field
readthrough.create_update()
return redirect(request.headers.get('Referer', '/')) return redirect(request.headers.get('Referer', '/'))
@ -166,7 +173,36 @@ def update_readthrough(request, book=None, create=True):
except ParserError: except ParserError:
pass pass
progress = request.POST.get('progress')
if progress:
try:
progress = int(progress)
readthrough.progress = progress
except ValueError:
pass
progress_mode = request.POST.get('progress_mode')
if progress_mode:
try:
progress_mode = models.ProgressMode(progress_mode)
readthrough.progress_mode = progress_mode
except ValueError:
pass
if not readthrough.start_date and not readthrough.finish_date: if not readthrough.start_date and not readthrough.finish_date:
return None return None
return readthrough return readthrough
@login_required
@require_POST
def delete_progressupdate(request):
''' remove a progress update '''
update = get_object_or_404(models.ProgressUpdate, id=request.POST.get('id'))
# don't let people edit other people's data
if request.user != update.user:
return HttpResponseBadRequest()
update.delete()
return redirect(request.headers.get('Referer', '/'))

17
bw-dev
View file

@ -12,9 +12,6 @@ trap showerr EXIT
source .env source .env
trap - EXIT trap - EXIT
# show commands as they're executed
set -x
function clean { function clean {
docker-compose stop docker-compose stop
docker-compose rm -f docker-compose rm -f
@ -38,9 +35,15 @@ function initdb {
execweb python manage.py initdb execweb python manage.py initdb
} }
case "$1" in CMD=$1
shift
# show commands as they're executed
set -x
case "$CMD" in
up) up)
docker-compose up --build docker-compose up --build "$@"
;; ;;
run) run)
docker-compose run --rm --service-ports web docker-compose run --rm --service-ports web
@ -57,12 +60,10 @@ case "$1" in
clean clean
;; ;;
makemigrations) makemigrations)
shift 1
execweb python manage.py makemigrations "$@" execweb python manage.py makemigrations "$@"
;; ;;
migrate) migrate)
execweb python manage.py rename_app fedireads bookwyrm execweb python manage.py rename_app fedireads bookwyrm
shift 1
execweb python manage.py migrate "$@" execweb python manage.py migrate "$@"
;; ;;
bash) bash)
@ -78,11 +79,9 @@ case "$1" in
docker-compose restart celery_worker docker-compose restart celery_worker
;; ;;
test) test)
shift 1
execweb coverage run --source='.' --omit="*/test*,celerywyrm*,bookwyrm/migrations/*" manage.py test "$@" execweb coverage run --source='.' --omit="*/test*,celerywyrm*,bookwyrm/migrations/*" manage.py test "$@"
;; ;;
pytest) pytest)
shift 1
execweb pytest --no-cov-on-fail "$@" execweb pytest --no-cov-on-fail "$@"
;; ;;
test_report) test_report)