Skip to content

Commit

Permalink
Merge pull request #4 from cfpb/readme-migrations-tests
Browse files Browse the repository at this point in the history
Add README, migrations, more tests, better logic
  • Loading branch information
chosak authored Sep 8, 2017
2 parents e7c236a + e370046 commit 2eb4223
Show file tree
Hide file tree
Showing 17 changed files with 383 additions and 52 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Thumbs.db
__pycache__/
*.py[cod]
.env
.eggs

# Django #
#################
Expand Down
5 changes: 1 addition & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ matrix:
python: 3.5

install:
pip install tox coveralls
pip install tox

script:
tox

after_success:
coveralls
1 change: 0 additions & 1 deletion README.md

This file was deleted.

65 changes: 65 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
.. image:: https://travis-ci.org/cfpb/wagtail-inventory.svg?branch=master
:alt: Build Status
:target: https://travis-ci.org/cfpb/wagtail-inventory

wagtail-inventory
=================

Search Wagtail pages by block type.

Wagtail Inventory adds the ability to search pages in your Wagtail site by the StreamField block types they contain. It adds a new Settings menu to the Wagtail admin site that allows you to search for pages that do or do not contain certain blocks. It supports searching both by Wagtail built-in blocks (like ``CharBlock``) as well as any custom blocks you might define.

Setup
-----

Install the package using pip:

.. code-block:: bash
$ pip install wagtail-inventory
Add ``wagtailinventory`` as an installed app in your Django settings:

.. code-block:: python
# in settings.py
INSTALLED_APPS = (
...
'wagtailinventory',
...
)
Run migrations to create required database tables:

.. code-block:: bash
$ manage.py migrate wagtailinventory
Run a management command to initialize database tables with current pages:

.. code-block:: bash
$ manage.py block_inventory
You should now be able to search your pages in the Wagtail admin site, under Settings > Block Inventory.

Compatibility
-------------

This code has been tested for compatibility with:

* Python 2.7, 3.5, 3.6
* Django 1.8, 1.11
* Wagtail 1.8, 1.10, 1.12

Testing
-------

Run unit tests with ``tox`` to test against all supported package combinations.

Open source licensing info
--------------------------

#. `TERMS <https://github.com/cfpb/wagtail-inventory/blob/master/TERMS.md>`_
#. `LICENSE <https://github.com/cfpb/wagtail-inventory/blob/master/LICENSE>`_
#. `CFPB Source Code Policy <https://github.com/cfpb/source-code-policy>`_
13 changes: 10 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@


install_requires = [
'Django>=1.8,<1.11',
'wagtail>=1.6,<1.9',
'Django>=1.8,<1.12',
'tqdm==4.15.0',
'wagtail>=1.8,<1.13',
]


setup_requires = [
'setuptools-git-version==1.0.3',
]


Expand All @@ -23,10 +29,11 @@
author='CFPB',
author_email='[email protected]',
license='CCO',
version='0.1',
version_format='{tag}.dev{commitcount}+{gitsha}',
include_package_data=True,
packages=find_packages(),
install_requires=install_requires,
setup_requires=setup_requires,
extras_require={
'testing': testing_extras,
},
Expand Down
5 changes: 5 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ deps=
wag110: wagtail>=1.10,<1.11
wag112: wagtail>=1.12,<1.13

[flake8]
exclude=
wagtailinventory/migrations/*.py,
wagtailinventory/tests/testapp/migrations/*.py

[testenv:flake8]
basepython=python3.5
deps=flake8>=2.2.0
Expand Down
75 changes: 36 additions & 39 deletions wagtailinventory/helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from wagtail.wagtailcore.blocks import StreamValue, StructValue
from itertools import chain

from wagtail.wagtailcore.blocks import ListBlock, StructBlock
from wagtail.wagtailcore.fields import StreamField

from wagtailinventory.models import PageBlock
Expand All @@ -8,52 +10,38 @@ def get_block_name(block):
return block.__module__ + '.' + block.__class__.__name__


def create_page_block(page, block, value):
page_block, _ = PageBlock.objects.get_or_create(
page=page,
block=get_block_name(block)
)
def get_page_blocks(page):
blocks = []

page_blocks = [page_block]
for field in page.specific._meta.fields:
if not isinstance(field, StreamField):
continue

if isinstance(value, list):
for subvalue in value:
page_blocks.extend(create_page_block(
page,
block.child_block,
subvalue
))
elif isinstance(value, StructValue):
for key, subvalue in value.bound_blocks.items():
page_blocks.extend(create_page_block(
page,
block.child_blocks[key],
subvalue
))
elif isinstance(value, StreamValue):
for subvalue in value:
page_blocks.extend(create_page_block(
page,
subvalue.block,
subvalue.value
))

return page_blocks
for stream_child in getattr(page.specific, field.name):
blocks.extend(get_field_blocks(stream_child))

return sorted(set(map(get_block_name, blocks)))

def create_page_inventory(page):
page_blocks = []

for field in page.specific._meta.fields:
if not isinstance(field, StreamField):
continue
def get_field_blocks(value):
block = getattr(value, 'block', None)
blocks = [block] if block else []

value = getattr(page.specific, field.name)
if isinstance(value, list):
child_blocks = value
if isinstance(block, StructBlock):
if hasattr(value, 'bound_blocks'):
child_blocks = value.bound_blocks.values()
else:
child_blocks = [value.value]
elif isinstance(block, ListBlock):
child_blocks = value.value
else:
child_blocks = []

for item in value:
page_blocks.extend(create_page_block(page, item.block, item.value))
blocks.extend(chain(*map(get_field_blocks, child_blocks)))

return page_blocks
return blocks


def get_page_inventory(page=None):
Expand All @@ -65,6 +53,15 @@ def get_page_inventory(page=None):
return inventory


def create_page_inventory(page):
page_blocks = get_page_blocks(page)

return [
PageBlock.objects.get_or_create(page=page, block=block)[0]
for block in page_blocks
]


def delete_page_inventory(page=None):
get_page_inventory(page).delete()

Expand Down
5 changes: 2 additions & 3 deletions wagtailinventory/management/commands/block_inventory.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import print_function

from django.core.management import BaseCommand
from tqdm import tqdm
from wagtail.wagtailcore.models import Page

from wagtailinventory.helpers import (
Expand All @@ -12,7 +13,5 @@ class Command(BaseCommand):
def handle(self, *args, **options):
delete_page_inventory()

count = Page.objects.count()
for i, page in enumerate(Page.objects.all()):
print(i + 1, '/', count, page)
for page in tqdm(Page.objects.all()):
create_page_inventory(page)
25 changes: 25 additions & 0 deletions wagtailinventory/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
('wagtailcore', '0032_add_bulk_delete_page_permission'),
]

operations = [
migrations.CreateModel(
name='PageBlock',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('block', models.CharField(db_index=True, max_length=255)),
('page', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='page_blocks', to='wagtailcore.Page')),
],
),
]
Empty file.
4 changes: 2 additions & 2 deletions wagtailinventory/tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'wagtailinventory',
'NAME': 'wagtailinventory.sqlite',
},
}

Expand All @@ -25,7 +25,6 @@

'wagtail.contrib.modeladmin',
'wagtail.contrib.settings',
'wagtail.tests.testapp',
'wagtail.wagtailadmin',
'wagtail.wagtaildocs',
'wagtail.wagtailcore',
Expand All @@ -35,6 +34,7 @@
'wagtail.wagtailusers',

'wagtailinventory',
'wagtailinventory.tests.testapp',
)


Expand Down
Loading

0 comments on commit 2eb4223

Please sign in to comment.