mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-15 04:36:34 +00:00
Merge branch 'jim/cli-tooling' of https://github.com/jimfingal/bookwyrm into main
This commit is contained in:
commit
00752232ff
12 changed files with 182 additions and 112 deletions
2
.coveragerc
Normal file
2
.coveragerc
Normal file
|
@ -0,0 +1,2 @@
|
|||
[run]
|
||||
omit = */test*,celerywyrm*,bookwyrm/migrations/*
|
7
.dockerignore
Normal file
7
.dockerignore
Normal file
|
@ -0,0 +1,7 @@
|
|||
__pycache__
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
.git
|
||||
.github
|
||||
.pytest*
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -13,3 +13,6 @@
|
|||
# BookWyrm
|
||||
.env
|
||||
/images/
|
||||
|
||||
# Testing
|
||||
.coverage
|
|
@ -65,9 +65,8 @@ You'll have to install the Docker and docker-compose. When you're ready, run:
|
|||
|
||||
```bash
|
||||
docker-compose build
|
||||
docker-compose up
|
||||
docker-compose exec web python manage.py migrate
|
||||
docker-compose exec web python manage.py shell -c 'import init_db'
|
||||
docker-compose run --rm web python manage.py migrate
|
||||
docker-compose run --rm web python manage.py initdb
|
||||
```
|
||||
|
||||
### Without Docker
|
||||
|
|
100
bookwyrm/management/commands/initdb.py
Normal file
100
bookwyrm/management/commands/initdb.py
Normal file
|
@ -0,0 +1,100 @@
|
|||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from bookwyrm.models import Connector, User
|
||||
from bookwyrm.settings import DOMAIN
|
||||
|
||||
def init_groups():
|
||||
groups = ['admin', 'moderator', 'editor']
|
||||
for group in groups:
|
||||
Group.objects.create(name=group)
|
||||
|
||||
def init_permissions():
|
||||
permissions = [{
|
||||
'codename': 'edit_instance_settings',
|
||||
'name': 'change the instance info',
|
||||
'groups': ['admin',]
|
||||
}, {
|
||||
'codename': 'set_user_group',
|
||||
'name': 'change what group a user is in',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'control_federation',
|
||||
'name': 'control who to federate with',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'create_invites',
|
||||
'name': 'issue invitations to join',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'moderate_user',
|
||||
'name': 'deactivate or silence a user',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'moderate_post',
|
||||
'name': 'delete other users\' posts',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'edit_book',
|
||||
'name': 'edit book info',
|
||||
'groups': ['admin', 'moderator', 'editor']
|
||||
}]
|
||||
|
||||
content_type = ContentType.objects.get_for_model(User)
|
||||
for permission in permissions:
|
||||
permission_obj = Permission.objects.create(
|
||||
codename=permission['codename'],
|
||||
name=permission['name'],
|
||||
content_type=content_type,
|
||||
)
|
||||
# add the permission to the appropriate groups
|
||||
for group_name in permission['groups']:
|
||||
Group.objects.get(name=group_name).permissions.add(permission_obj)
|
||||
|
||||
# while the groups and permissions shouldn't be changed because the code
|
||||
# depends on them, what permissions go with what groups should be editable
|
||||
|
||||
|
||||
def init_connectors():
|
||||
Connector.objects.create(
|
||||
identifier=DOMAIN,
|
||||
name='Local',
|
||||
local=True,
|
||||
connector_file='self_connector',
|
||||
base_url='https://%s' % DOMAIN,
|
||||
books_url='https://%s/book' % DOMAIN,
|
||||
covers_url='https://%s/images/covers' % DOMAIN,
|
||||
search_url='https://%s/search?q=' % DOMAIN,
|
||||
priority=1,
|
||||
)
|
||||
|
||||
Connector.objects.create(
|
||||
identifier='bookwyrm.social',
|
||||
name='BookWyrm dot Social',
|
||||
connector_file='bookwyrm_connector',
|
||||
base_url='https://bookwyrm.social' ,
|
||||
books_url='https://bookwyrm.social/book',
|
||||
covers_url='https://bookwyrm.social/images/covers',
|
||||
search_url='https://bookwyrm.social/search?q=',
|
||||
priority=2,
|
||||
)
|
||||
|
||||
Connector.objects.create(
|
||||
identifier='openlibrary.org',
|
||||
name='OpenLibrary',
|
||||
connector_file='openlibrary',
|
||||
base_url='https://openlibrary.org',
|
||||
books_url='https://openlibrary.org',
|
||||
covers_url='https://covers.openlibrary.org',
|
||||
search_url='https://openlibrary.org/search?q=',
|
||||
priority=3,
|
||||
)
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Initializes the database with starter data'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
init_groups()
|
||||
init_permissions()
|
||||
init_connectors()
|
|
@ -6,6 +6,8 @@ import pathlib
|
|||
import json
|
||||
import responses
|
||||
|
||||
import pytest
|
||||
|
||||
from django.test import TestCase, Client
|
||||
from django.utils.http import http_date
|
||||
|
||||
|
@ -167,6 +169,7 @@ class Signature(TestCase):
|
|||
response = self.send_test_request(sender=self.fake_remote)
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_changed_data(self):
|
||||
'''Message data must match the digest header.'''
|
||||
response = self.send_test_request(
|
||||
|
@ -174,12 +177,14 @@ class Signature(TestCase):
|
|||
send_data=get_follow_data(self.mouse, self.cat))
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_invalid_digest(self):
|
||||
response = self.send_test_request(
|
||||
self.mouse,
|
||||
digest='SHA-256=AAAAAAAAAAAAAAAAAA')
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_old_message(self):
|
||||
'''Old messages should be rejected to prevent replay attacks.'''
|
||||
response = self.send_test_request(
|
||||
|
|
|
@ -22,6 +22,7 @@ services:
|
|||
- main
|
||||
web:
|
||||
build: .
|
||||
env_file: .env
|
||||
command: python manage.py runserver 0.0.0.0:8000
|
||||
volumes:
|
||||
- .:/app
|
||||
|
|
69
fr-dev
69
fr-dev
|
@ -3,51 +3,86 @@
|
|||
set -e
|
||||
set -x
|
||||
|
||||
function clean {
|
||||
docker-compose stop
|
||||
docker-compose rm -f
|
||||
}
|
||||
|
||||
function runweb {
|
||||
docker-compose run --rm web "$@"
|
||||
clean
|
||||
}
|
||||
|
||||
function execdb {
|
||||
docker-compose exec db $@
|
||||
}
|
||||
|
||||
function execweb {
|
||||
docker-compose exec web "$@"
|
||||
}
|
||||
|
||||
function initdb {
|
||||
execweb python manage.py migrate
|
||||
execweb python manage.py initdb
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
up)
|
||||
docker-compose up --build
|
||||
;;
|
||||
run)
|
||||
docker-compose run --service-ports web
|
||||
docker-compose run --rm --service-ports web
|
||||
;;
|
||||
initdb)
|
||||
docker-compose exec web python manage.py migrate
|
||||
docker-compose exec web python manage.py shell -c 'import init_db'
|
||||
initdb
|
||||
;;
|
||||
resetdb)
|
||||
docker-compose stop web
|
||||
docker-compose exec db dropdb -U fedireads fedireads
|
||||
docker-compose exec db createdb -U fedireads fedireads
|
||||
docker-compose start web
|
||||
docker-compose exec web python manage.py migrate
|
||||
docker-compose exec web python manage.py shell -c 'import init_db'
|
||||
clean
|
||||
docker-compose up --build -d
|
||||
execdb dropdb -U fedireads fedireads
|
||||
execdb createdb -U fedireads fedireads
|
||||
initdb
|
||||
clean
|
||||
;;
|
||||
makemigrations)
|
||||
docker-compose exec web python manage.py makemigrations
|
||||
execweb python manage.py makemigrations
|
||||
;;
|
||||
migrate)
|
||||
docker-compose exec web python manage.py migrate
|
||||
execweb python manage.py migrate
|
||||
;;
|
||||
bash)
|
||||
execweb bash
|
||||
;;
|
||||
shell)
|
||||
docker-compose exec web python manage.py shell
|
||||
execweb python manage.py shell
|
||||
;;
|
||||
dbshell)
|
||||
docker-compose exec db psql -U fedireads fedireads
|
||||
execdb psql -U fedireads fedireads
|
||||
;;
|
||||
restart_celery)
|
||||
docker-compose restart celery_worker
|
||||
;;
|
||||
test)
|
||||
shift 1
|
||||
docker-compose exec web coverage run --source='.' --omit="*/test*,celerywyrm*,bookwyrm/migrations/*" manage.py test "$@"
|
||||
execweb coverage run --source='.' --omit="*/test*,celerywyrm*,bookwyrm/migrations/*" manage.py test "$@"
|
||||
;;
|
||||
pytest)
|
||||
shift 1
|
||||
execweb pytest "$@"
|
||||
;;
|
||||
test_report)
|
||||
docker-compose exec web coverage report
|
||||
execweb coverage report
|
||||
;;
|
||||
collectstatic)
|
||||
docker-compose exec web python manage.py collectstatic --no-input
|
||||
execweb python manage.py collectstatic --no-input
|
||||
;;
|
||||
build)
|
||||
docker-compose build
|
||||
;;
|
||||
clean)
|
||||
clean
|
||||
;;
|
||||
*)
|
||||
echo "Unrecognised command. Try: up, initdb, resetdb, makemigrations, migrate, shell, dbshell, restart_celery, test, test_report"
|
||||
echo "Unrecognised command. Try: build, clean, up, initdb, resetdb, makemigrations, migrate, bash, shell, dbshell, restart_celery, test, pytest, test_report"
|
||||
;;
|
||||
esac
|
||||
|
|
91
init_db.py
91
init_db.py
|
@ -1,91 +0,0 @@
|
|||
''' starter data '''
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from bookwyrm.models import Connector, User
|
||||
from bookwyrm.settings import DOMAIN
|
||||
|
||||
|
||||
groups = ['admin', 'moderator', 'editor']
|
||||
for group in groups:
|
||||
Group.objects.create(name=group)
|
||||
|
||||
permissions = [{
|
||||
'codename': 'edit_instance_settings',
|
||||
'name': 'change the instance info',
|
||||
'groups': ['admin',]
|
||||
}, {
|
||||
'codename': 'set_user_group',
|
||||
'name': 'change what group a user is in',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'control_federation',
|
||||
'name': 'control who to federate with',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'create_invites',
|
||||
'name': 'issue invitations to join',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'moderate_user',
|
||||
'name': 'deactivate or silence a user',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'moderate_post',
|
||||
'name': 'delete other users\' posts',
|
||||
'groups': ['admin', 'moderator']
|
||||
}, {
|
||||
'codename': 'edit_book',
|
||||
'name': 'edit book info',
|
||||
'groups': ['admin', 'moderator', 'editor']
|
||||
}]
|
||||
|
||||
content_type = ContentType.objects.get_for_model(User)
|
||||
for permission in permissions:
|
||||
permission_obj = Permission.objects.create(
|
||||
codename=permission['codename'],
|
||||
name=permission['name'],
|
||||
content_type=content_type,
|
||||
)
|
||||
# add the permission to the appropriate groups
|
||||
for group_name in permission['groups']:
|
||||
Group.objects.get(name=group_name).permissions.add(permission_obj)
|
||||
|
||||
# while the groups and permissions shouldn't be changed because the code
|
||||
# depends on them, what permissions go with what groups should be editable
|
||||
|
||||
|
||||
|
||||
Connector.objects.create(
|
||||
identifier=DOMAIN,
|
||||
name='Local',
|
||||
local=True,
|
||||
connector_file='self_connector',
|
||||
base_url='https://%s' % DOMAIN,
|
||||
books_url='https://%s/book' % DOMAIN,
|
||||
covers_url='https://%s/images/covers' % DOMAIN,
|
||||
search_url='https://%s/search?q=' % DOMAIN,
|
||||
priority=1,
|
||||
)
|
||||
|
||||
Connector.objects.create(
|
||||
identifier='bookwyrm.social',
|
||||
name='BookWyrm dot Social',
|
||||
connector_file='bookwyrm_connector',
|
||||
base_url='https://bookwyrm.social' ,
|
||||
books_url='https://bookwyrm.social/book',
|
||||
covers_url='https://bookwyrm.social/images/covers',
|
||||
search_url='https://bookwyrm.social/search?q=',
|
||||
priority=2,
|
||||
)
|
||||
|
||||
Connector.objects.create(
|
||||
identifier='openlibrary.org',
|
||||
name='OpenLibrary',
|
||||
connector_file='openlibrary',
|
||||
base_url='https://openlibrary.org',
|
||||
books_url='https://openlibrary.org',
|
||||
covers_url='https://covers.openlibrary.org',
|
||||
search_url='https://openlibrary.org/search?q=',
|
||||
priority=3,
|
||||
)
|
6
pytest.ini
Normal file
6
pytest.ini
Normal file
|
@ -0,0 +1,6 @@
|
|||
[pytest]
|
||||
DJANGO_SETTINGS_MODULE = bookwyrm.settings
|
||||
python_files = tests.py test_*.py *_tests.py
|
||||
addopts = --cov=bookwyrm --cov-config=.coveragerc
|
||||
markers =
|
||||
integration: marks tests as requiring external resources (deselect with '-m "not integration"')
|
|
@ -21,5 +21,5 @@ fi
|
|||
python manage.py makemigrations fedireads
|
||||
python manage.py migrate
|
||||
|
||||
python manage.py shell < init_db.py
|
||||
python manage.py initdb
|
||||
python manage.py runserver
|
||||
|
|
|
@ -7,6 +7,9 @@ flower==0.9.4
|
|||
Pillow>=7.1.0
|
||||
psycopg2==2.8.4
|
||||
pycryptodome==3.9.4
|
||||
pytest-django==4.1.0
|
||||
pytest==6.1.2
|
||||
pytest-cov==2.10.1
|
||||
python-dateutil==2.8.1
|
||||
redis==3.4.1
|
||||
requests==2.22.0
|
||||
|
|
Loading…
Reference in a new issue