Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import logging
- import os
- from bakery.views import BuildableMixin
- from django.conf import settings
- from django.contrib.contenttypes.models import ContentType
- from wagtail.wagtailcore.models import Page, Site
- from wagtail.api.v2.endpoints import PagesAPIEndpoint
- from wagtail.api.v2.router import WagtailAPIRouter
- from wagtail.api.v2.pagination import WagtailPagination
- logger = logging.getLogger(__name__)
- class AllResultsWagtailPagination(WagtailPagination):
- """
- A pagination class that returns all results on a single page
- """
- def paginate_queryset(self, queryset, request, view=None):
- self.view = view
- self.total_count = queryset.count()
- return queryset
- class APIListingView(BuildableMixin):
- @property
- def build_method(self):
- return self.build_queryset
- def get_build_path(self):
- target_path = os.path.join(settings.BUILD_DIR, self.build_path.lstrip('/'))
- if not self.fs.exists(os.path.dirname(target_path)):
- logger.debug("Creating {}".format(os.path.dirname(target_path)))
- self.fs.makedirs(os.path.dirname(target_path))
- return target_path
- def build_queryset(self):
- logger.debug("Building %s" % self.build_path)
- self.request = self.create_request(self.build_path)
- target_path = os.path.join(settings.BUILD_DIR, self.get_build_path())
- self.build_file(target_path, self.get_content())
- class APIDetailView(BuildableMixin):
- """
- Render and build a "detail" view of an object.
- Required attributes:
- queryset:
- the model instance the objects are looked up from.
- """
- @property
- def build_method(self):
- return self.build_queryset
- def get_url(self, obj):
- """
- The URL at which the detail page should appear.
- """
- if not hasattr(obj, 'get_absolute_url') or not obj.get_absolute_url():
- raise ImproperlyConfigured("No URL configured. You must either \
- set a ``get_absolute_url`` method on the %s model or override the %s view's \
- ``get_url`` method" % (obj.__class__.__name__, self.__class__.__name__))
- return obj.get_absolute_url()
- def get_build_path(self, obj):
- """
- Used to determine where to build the detail page. Override this if you
- would like your detail page at a different location. By default it
- will be built at get_url()
- """
- target_path = os.path.join(settings.BUILD_DIR, self.get_url(obj).lstrip('/'))
- if not self.fs.exists(os.path.dirname(target_path)):
- logger.debug("Creating {}".format(os.path.dirname(target_path)))
- self.fs.makedirs(os.path.dirname(target_path))
- return target_path
- def set_kwargs(self, obj):
- self.kwargs = {
- 'pk': getattr(obj, 'pk', None),
- }
- def build_object(self, obj):
- logger.debug("Building %s" % obj)
- self.request = self.create_request(self.get_url(obj))
- self.set_kwargs(obj)
- target_path = self.get_build_path(obj)
- self.build_file(target_path, self.get_content())
- def build_queryset(self):
- [self.build_object(o) for o in self.get_queryset().all()]
- def unbuild_object(self, obj):
- """
- Deletes the file at self.get_build_path.
- """
- logger.debug("Unbuilding %s" % obj)
- target_path = os.path.split(self.get_build_path(obj))[0]
- if self.fs.exists(target_path):
- logger.debug("Removing {}".format(target_path))
- self.fs.removetree(target_path)
- def get_content(self):
- # Create a dummy request
- request = self.create_request('/?format=json&fields=*')
- request.site = Site.objects.get(is_default_site=True)
- request.wagtailapi_router = WagtailAPIRouter('')
- response = PagesAPIEndpointWithoutPagination.as_view({'get': 'detail_view'})(request, pk=self.kwargs['pk'])
- return response.render().content
- class PagesAPIEndpointWithoutPagination(PagesAPIEndpoint):
- pagination_class = AllResultsWagtailPagination
- class PagesAPIDetailView(APIDetailView):
- """
- Builds detail documents for every published page.
- URL example: /api/pages/detail/1.json
- """
- endpoint_class = PagesAPIEndpointWithoutPagination
- def get_url(self, page):
- return '/api/pages/detail/{}.json'.format(page.id)
- def get_queryset(self):
- if getattr(settings, 'BAKERY_MULTISITE', False):
- return Page.objects.all().public().live()
- else:
- site = Site.objects.get(is_default_site=True)
- return site.root_page.get_descendants(inclusive=True).public().live()
- class PagesAPIListingView(APIListingView):
- """
- Builds a single listing that lists every published page.
- URL example: /api/pages/all.json
- """
- build_path = '/api/pages/all.json'
- def get_url(self):
- return self.build_path
- def fetch_page_listing(self, page_model=None):
- if page_model:
- url = '/?format=json&fields=*&type={}.{}'.format(page_model._meta.app_label, page_model.__name__)
- else:
- url = '/?format=json&fields=*'
- request = self.create_request(url)
- request.site = Site.objects.get(is_default_site=True)
- request.wagtailapi_router = WagtailAPIRouter('')
- response = PagesAPIEndpointWithoutPagination.as_view({'get': 'listing_view'})(request)
- return response.render().content
- def get_content(self):
- return self.fetch_page_listing()
- class TypedPagesAPIListingView(PagesAPIListingView):
- """
- Builds a listing for each page type. Containing all published
- pages of that type.
- URL example: /api/pages/blog_BlogPage.json
- """
- build_path = '/api/pages/{app_label}_{class_name}.json'
- def get_url(self, cls):
- return self.build_path.format(
- app_label=cls._meta.app_label,
- class_name=cls.__name__,
- )
- def get_content(self):
- return self.fetch_page_listing(self.kwargs['cls'])
- def set_kwargs(self, cls):
- self.kwargs = {
- 'cls': cls,
- }
- def get_build_path(self, cls):
- target_path = os.path.join(settings.BUILD_DIR, self.get_url(cls).lstrip('/'))
- if not self.fs.exists(os.path.dirname(target_path)):
- logger.debug("Creating {}".format(os.path.dirname(target_path)))
- self.fs.makedirs(os.path.dirname(target_path))
- return target_path
- def build_page_type(self, cls):
- logger.debug("Building %s" % cls)
- self.request = self.create_request(self.get_url(cls))
- self.set_kwargs(cls)
- target_path = self.get_build_path(cls)
- self.build_file(target_path, self.get_content())
- def get_page_types(self):
- return [
- content_type.model_class()
- for content_type in ContentType.objects.filter(id__in=Page.objects.values_list('content_type_id', flat=True))
- ]
- def build(self):
- for page_type in self.get_page_types():
- self.build_page_type(page_type)
- @property
- def build_method(self):
- return self.build
Add Comment
Please, Sign In to add comment