Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop to master - prep for 2.1.0 #20

Merged
merged 34 commits into from
Mar 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8c3428a
IonImage - support to define rendition type
Nov 19, 2020
76059af
IonMedia - add audio support
Nov 19, 2020
ed4bb9a
Extend .gitignore
Nov 19, 2020
25e019f
Merge branch 'master' into ion-media-add-audio-support
Feb 15, 2021
0b244f8
Use configured model to create renditions & drop migration
Feb 15, 2021
7c37154
Merge pull request #3 from anfema/ion-media-add-audio-support
Feb 16, 2021
2ea2483
Temporarily disable parsing of choice fields
Feb 16, 2021
e133d3f
Merge pull request #8 from anfema/temporarily-disable-choice-field-pa…
Feb 16, 2021
c9224a9
Hotfix field type detection for non-model fields
Feb 17, 2021
9ffa151
Allow replacing build_url function via new `ION_ARCHIVE_BUILD_URL_FUN…
Feb 22, 2021
648d929
Merge pull request #9 from anfema/allow-build-url-override
Feb 22, 2021
f40f0e9
Improve compatibility with wagtail v2.12
Mar 1, 2021
05311a6
Automatically set page title & slug on page creation
Mar 1, 2021
f409cb1
Replace auto-generated page title & slug on page copy
Mar 1, 2021
d37bd4c
Implement custom copy view & form for pages with auto-generated title
Mar 2, 2021
072df92
Backport fix for crash when copying an alias page
Mar 2, 2021
e2a1553
Require wagtail v2.12 or higher
Mar 2, 2021
d2a71a1
Fix support for create alias operation of pages with auto-generated t…
Mar 2, 2021
6ca0b2f
Merge pull request #13 from anfema/implement-page-title-and-slug-hand…
Mar 2, 2021
51de278
Implement get_object_block_usage
Mar 9, 2021
63115d5
Handle media file deletion in post_delete signal handler
Mar 9, 2021
dac2cff
Extend get_usage() of file based models to include get_object_block_u…
Mar 9, 2021
df6ba1c
Intercept delete views of file based models to prevent deletion if re…
Mar 9, 2021
6419152
Extend django admin of file based models to prevent deletion if refer…
Mar 9, 2021
2254627
Refactor: move IonMediaBlock to blocks module
Mar 9, 2021
c1dd485
Refactor: move block types to check on get_usage() to dedicated attri…
Mar 9, 2021
95fb373
Prevent deletion of file based models if referenced in blocks
Mar 9, 2021
9801c56
Update publish-with-children view
Mar 11, 2021
52bc0da
Prevent recursive publish if any alias subpage exists
Mar 11, 2021
af3430c
Merge pull request #18 from anfema/fix-publish-with-children-on-alias…
dunkelstern Mar 15, 2021
f7a37a9
Return bound block in get_stream_value_blocks() instead of block & value
Mar 16, 2021
a5f94fc
Merge pull request #14 from anfema/prevent-deletion-if-object-in-use
rollacting Mar 19, 2021
4a85a36
Bugfix: Handle wagtail.core.page in addition to abstractpage
dunkelstern Mar 19, 2021
d5038b7
Merge pull request #22 from anfema/j.schriewer/21-page-links
rollacting Mar 19, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.idea/
*.pyc
__pycache__
.vscode/*
**/.mypy_cache
build/
dist/
*.egg-info/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Content:

## 1. Requirements

- Wagtail > 2.0 and WagtailMedia
- Wagtail >= 2.12 and WagtailMedia
- Django > 2.2
- Celery
- RestFramework
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def package_data_with_recursive_dirs(package_data_spec):
keywords="ION Wagtail API Adapter",
install_requires=[
"django>=2.2",
"wagtail>2.0",
"wagtail>=2.12",
"celery[redis]>=4.3",
"djangorestframework>=3.9",
"beautifulsoup4>=4.6",
Expand Down
23 changes: 20 additions & 3 deletions wagtail_to_ion/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,30 @@
from wagtail_to_ion.models import get_ion_media_rendition_model


class AbstractIonImageAdmin(admin.ModelAdmin):
class ProtectInUseModelAdmin(admin.ModelAdmin):
protect_objects_in_use: bool = True

def get_deleted_objects(self, objs, request):
if self.protect_objects_in_use:
protected = []

for obj in objs:
usage = obj.get_usage()
if usage:
protected += list(usage)
if protected:
return [], {}, set(), protected

return super().get_deleted_objects(objs, request)


class AbstractIonImageAdmin(ProtectInUseModelAdmin):
list_display = ('title', 'collection', 'include_in_archive')
list_filter = ('collection', 'include_in_archive')
search_fields = ('title',)


class AbstractIonDocumentAdmin(admin.ModelAdmin):
class AbstractIonDocumentAdmin(ProtectInUseModelAdmin):
list_display = ('title', 'collection', 'include_in_archive')
list_filter = ('collection', 'include_in_archive')
search_fields = ('title',)
Expand All @@ -21,7 +38,7 @@ class IonMediaRenditionInlineAdmin(admin.TabularInline):
extra = 0


class AbstractIonMediaAdmin(admin.ModelAdmin):
class AbstractIonMediaAdmin(ProtectInUseModelAdmin):
list_display = ('title', 'collection', 'include_in_archive')
list_filter = ('collection', 'include_in_archive')
search_fields = ('title',)
Expand Down
17 changes: 17 additions & 0 deletions wagtail_to_ion/blocks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.utils.functional import cached_property
from wagtailmedia.blocks import AbstractMediaChooserBlock


class IonMediaBlock(AbstractMediaChooserBlock):
@cached_property
def target_model(self):
from wagtailmedia.models import get_media_model
return get_media_model()

@cached_property
def widget(self):
from wagtailmedia.widgets import AdminMediaChooser
return AdminMediaChooser

def render_basic(self, value, context=None):
raise NotImplementedError('You need to implement %s.render_basic' % self.__class__.__name__)
6 changes: 6 additions & 0 deletions wagtail_to_ion/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@
False

)

settings.ION_ARCHIVE_BUILD_URL_FUNCTION = getattr(
settings,
'ION_ARCHIVE_BUILD_URL_FUNCTION',
None
)
185 changes: 109 additions & 76 deletions wagtail_to_ion/models/abstract.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,109 @@
# Copyright © 2017 anfema GmbH. All rights reserved.
from typing import Optional

from django.conf import settings
from django.utils.text import slugify

from wagtail.core.models import Page, Site


class AbstractIonPage(Page):

@classmethod
def ion_metadata(cls):
"""
Returns additional metadata for the page.

See `DynamicPageSerializer.get_meta()`
"""
return ()

@classmethod
def ion_extra_fields(cls):
"""
Add extra fields (not part of `content_panels`) for serialization with ION.

Returns an iterable of tuples containing two strings:
- the outlet name
- the path to the extra field

Example: to add the value of `self.some_related_model.some_field` use:
return (
('outlet_name', 'some_related_model.some_field'),
)
"""
return ()

@classmethod
def get_layout_name(cls, api_version: Optional[int] = None): # TODO: rename to `get_ion_layout_name`?
return cls.__name__.lower() # TODO: use `cls._meta.model_name`?

#
# wagtail attributes/methods
#

# ion pages have no preview currently; clear wagtail preview modes
preview_modes = ()

# ion pages have no public url (disables wagtail "live view" buttons too)
def get_url_parts(self, request=None):
site = Site.find_for_request(request)
return site, None, None # return only the site to silence the "no site configured" warning

#
# django model setup
#

class Meta:
abstract = True

def __str__(self):
return self.title

def save(self, *args, **kwargs):
if self.slug.startswith('to-be-filled'):
self.slug = slugify(self.title)
super().save(*args, **kwargs)


class AbstractIonCollection(AbstractIonPage):
ion_api_object_name = 'collection'

parent_page_types = ['wagtailcore.Page']
subpage_types = [settings.ION_LANGUAGE_MODEL]

class Meta:
abstract = True
# Copyright © 2017 anfema GmbH. All rights reserved.
from typing import Optional
from uuid import uuid4

from django.conf import settings
from django.utils.text import slugify

from wagtail.core.models import Page, Site


class AbstractIonPage(Page):
ion_generate_page_title = True

@classmethod
def generate_page_title(cls):
"""Generate ION specific page title"""
return '{class_name}{uuid}'.format(class_name=cls.__name__, uuid=uuid4())

@classmethod
def ion_metadata(cls):
"""
Returns additional metadata for the page.

See `DynamicPageSerializer.get_meta()`
"""
return ()

@classmethod
def ion_extra_fields(cls):
"""
Add extra fields (not part of `content_panels`) for serialization with ION.

Returns an iterable of tuples containing two strings:
- the outlet name
- the path to the extra field

Example: to add the value of `self.some_related_model.some_field` use:
return (
('outlet_name', 'some_related_model.some_field'),
)
"""
return ()

@classmethod
def get_layout_name(cls, api_version: Optional[int] = None): # TODO: rename to `get_ion_layout_name`?
return cls.__name__.lower() # TODO: use `cls._meta.model_name`?

#
# wagtail attributes/methods
#

# ion pages have no preview currently; clear wagtail preview modes
preview_modes = ()

# ion pages have no public url (disables wagtail "live view" buttons too)
def get_url_parts(self, request=None):
site = Site.find_for_request(request)
return site, None, None # return only the site to silence the "no site configured" warning

# overwrite Page.copy() to automatically replace the page title & slug if `ion_generate_page_title` flag is set.
# this method is called for every child page too (on recursive copy).
def copy(self, *args, **kwargs):
new_update_attrs = kwargs.get('update_attrs', None) or {}

if self.ion_generate_page_title:
new_page_title = self.generate_page_title()
new_update_attrs.update({
'title': new_page_title,
'slug': slugify(new_page_title),
})

# Backport: Fix crash when copying an alias page
# TODO: remove once https://github.com/wagtail/wagtail/pull/6854 is merged & released
new_update_attrs.update({
'alias_of': None,
})
kwargs['update_attrs'] = new_update_attrs

return super().copy(*args, **kwargs)

#
# django model setup
#

class Meta:
abstract = True

def __str__(self):
return self.title

# overwrite Page.full_clean() to implement ION specific title & slug handling
def full_clean(self, *args, **kwargs):
# most ION pages have an auto-generated title (indicated by the `ion_generate_page_title` flag)
if not self.title and self.ion_generate_page_title:
self.title = self.generate_page_title()
self.slug = slugify(self.title)

super().full_clean(*args, **kwargs)


class AbstractIonCollection(AbstractIonPage):
ion_api_object_name = 'collection'
ion_generate_page_title = False

parent_page_types = ['wagtailcore.Page']
subpage_types = [settings.ION_LANGUAGE_MODEL]

class Meta:
abstract = True
Loading