def _register_subclass_types(): """ See if any page type plugin uses the old registration system, and register that Previously django-polymorphic registered all subclasses internally. Nowadays, all subclasses should just be registered in the regular admin. """ RE_PLUGIN_MODULE = re.compile(r'\.page_type_plugins\b.*$') from fluent_pages.extensions import page_type_pool for plugin in page_type_pool.get_plugins(): if plugin.model in admin.site._registry: continue # First try to perform an admin file import, it may register itself. admin_path = RE_PLUGIN_MODULE.sub('.admin', plugin.__module__) try: import_module(admin_path) except ImportError: pass else: if plugin.model in admin.site._registry: continue # Register the admin, since the plugin didn't do this. if getattr(plugin, 'model_admin', None): admin.site.register(plugin.model, plugin.model_admin)
def fill_choices(filter=lambda x: True): for plugin in page_type_pool.get_plugins(): ct_id = ContentType.objects.get_for_model(plugin.model).id if not filter(ct_id): continue choices.append((ct_id, plugin.verbose_name)) priorities[ct_id] = plugin.sort_priority
def ready(self): try: if 'fluent_pages' in settings.INSTALLED_APPS: from fluent_pages.extensions import page_type_pool from fluent_contents.extensions import plugin_pool from .admin import SuitAdminMixin for p in page_type_pool.get_plugins(): class PageTypeAdmin(SuitAdminMixin, p.model_admin): pass p.model_admin = PageTypeAdmin for p in plugin_pool.get_plugins(): try: class PluginAdmin(SuitAdminMixin, p.model_admin): pass p.model_admin = PluginAdmin except AttributeError: pass except: pass # shit happens
def get_child_models(self): """ Provide the available models of the page type registration system to *django-polymorphic-tree*. """ from fluent_pages.extensions import page_type_pool child_models = [] for plugin in page_type_pool.get_plugins(): child_models.append((plugin.model, plugin.model_admin)) return child_models
def _find_plugin_reverse(viewname, args, kwargs): plugins = page_type_pool.get_url_pattern_plugins() for plugin in plugins: try: url_end = plugin.get_url_resolver().reverse(viewname, *args, **kwargs) return plugin, url_end except NoReverseMatch: pass else: raise NoReverseMatch( "Reverse for application URL '{0}' with arguments '{1}' and keyword arguments '{2}' not found.\n" "Searched in URLconf and installed page type plugins ({3}) for URLs.".format( viewname, args, kwargs, ', '.join(x.__class__.__name__ for x in page_type_pool.get_plugins()) or "none" ))
def get_child_type_choices(self): """ Return a list of polymorphic types which can be added. """ from fluent_pages.extensions import page_type_pool priorities = {} choices = [] for plugin in page_type_pool.get_plugins(): ct = ContentType.objects.get_for_model(plugin.model) choices.append((ct.id, plugin.verbose_name)) priorities[ct.id] = plugin.sort_priority choices.sort(key=lambda choice: (priorities[choice[0]], choice[1])) return choices
def _find_plugin_reverse(viewname, args, kwargs): from fluent_pages.extensions import page_type_pool plugins = page_type_pool.get_url_pattern_plugins() for plugin in plugins: try: url_end = plugin.get_url_resolver().reverse(viewname, *args, **kwargs) return plugin, url_end except NoReverseMatch: pass else: raise NoReverseMatch( "Reverse for application URL '{0}' with arguments '{1}' and keyword arguments '{2}' not found.\n" "Searched in URLconf and installed page type plugins ({3}) for URLs.".format( viewname, args, kwargs, ', '.join(x.__class__.__name__ for x in page_type_pool.get_plugins()) or "none" ))
def get_child_type_choices(self, request=None, action=None): """ Return a list of polymorphic types which can be added. """ # The arguments are made optional, to support both django-polymorphic 0.5 and 0.6 from fluent_pages.extensions import page_type_pool priorities = {} choices = [] for plugin in page_type_pool.get_plugins(): ct = ContentType.objects.get_for_model(plugin.model) choices.append((ct.id, plugin.verbose_name)) priorities[ct.id] = plugin.sort_priority choices.sort(key=lambda choice: (priorities[choice[0]], choice[1])) return choices
def get_child_type_choices(self, request=None, action=None): """ Return a list of polymorphic types which can be added. """ # The arguments are made optional, to support both django-polymorphic 0.5 and 0.6 from fluent_pages.extensions import page_type_pool can_have_children = None child_types = None base_plugins = page_type_pool.get_plugins() if request is not None: parent = request.GET.get(self.model._mptt_meta.parent_attr, None) if parent is None: # Already exclude plugins that can't be root. base_plugins = [p for p in base_plugins if p.can_be_root] else: # if we have a parent check to see if it exists and get can_have_children try: parent_instance = self.base_model.objects.get(pk=parent) can_have_children = parent_instance.can_have_children child_types = parent_instance.get_child_types() except self.base_model.DoesNotExist: pass priorities = {} choices = [] def fill_choices(filter=lambda x: True): for plugin in base_plugins: ct_id = ContentType.objects.get_for_model(plugin.model).id if not filter(ct_id): continue choices.append((ct_id, plugin.verbose_name)) priorities[ct_id] = plugin.sort_priority if can_have_children is not None: if can_have_children: if len(child_types) == 0: fill_choices() else: # filter the choices fill_choices(lambda ct_id: ct_id in child_types) else: # all choices fill_choices() choices.sort(key=lambda choice: (priorities[choice[0]], choice[1])) return choices
def handle_noargs(self, **options): is_dry_run = options.get('dry-run', False) mptt_only = options.get('mptt-only', False) slugs = {} overrides = {} parents = dict(UrlNode.objects.values_list('id', 'parent_id')) self.stdout.write("Updated MPTT columns") if is_dry_run and mptt_only: # Can't really do anything return if not is_dry_run: # Fix MPTT first, that is the basis for walking through all nodes. UrlNode.objects.rebuild() self.stdout.write("Updated MPTT columns") if mptt_only: return self.stdout.write("Updating cached URLs") self.stdout.write("Page tree nodes:\n\n") type_len = str(max(len(plugin.type_name) for plugin in page_type_pool.get_plugins())) col_style = u"| {0:6} | {1:6} | {2:" + type_len + "} | {3:6} | {4}" header = col_style.format("Site", "Page", "Type", "Locale", "URL") sep = '-' * (len(header) + 40) self.stdout.write(sep) self.stdout.write(header) self.stdout.write(sep) for translation in UrlNode_Translation.objects.select_related('master').order_by('master__parent_site__id', 'master__tree_id', 'master__lft', 'language_code'): slugs.setdefault(translation.language_code, {})[translation.master_id] = translation.slug overrides.setdefault(translation.language_code, {})[translation.master_id] = translation.override_url old_url = translation._cached_url try: new_url = self._construct_url(translation.language_code, translation.master_id, parents, slugs, overrides) except KeyError: if is_dry_run: # When the mptt tree is broken, some URLs can't be correctly generated yet. self.stderr.write("Failed to determine new URL for {0}, please run with --mptt-only first.".format(old_url)) return raise if old_url != new_url: translation._cached_url = new_url if not is_dry_run: translation.save() page = translation.master if old_url != new_url: self.stdout.write(smart_text(u"{0} {1} {2}\n".format( col_style.format( page.parent_site_id, page.pk, page.plugin.type_name, translation.language_code, translation._cached_url ), "WILL CHANGE from" if is_dry_run else "UPDATED from", old_url ))) else: self.stdout.write(smart_text(col_style.format( page.parent_site_id, page.pk, page.plugin.type_name, translation.language_code, translation._cached_url )))
def handle(self, *args, **options): if args: raise CommandError("Command doesn't accept any arguments") is_dry_run = options.get('dry-run', False) mptt_only = options.get('mptt-only', False) slugs = {} overrides = {} parents = dict(UrlNode.objects.values_list('id', 'parent_id')) self.stdout.write("Updated MPTT columns") if is_dry_run and mptt_only: # Can't really do anything return if not is_dry_run: # Fix MPTT first, that is the basis for walking through all nodes. UrlNode.objects.rebuild() self.stdout.write("Updated MPTT columns") if mptt_only: return self.stdout.write("Updating cached URLs") self.stdout.write("Page tree nodes:\n\n") type_len = str(max(len(plugin.type_name) for plugin in page_type_pool.get_plugins())) col_style = u"| {0:6} | {1:6} | {2:" + type_len + "} | {3:6} | {4}" header = col_style.format("Site", "Page", "Type", "Locale", "URL") sep = '-' * (len(header) + 40) self.stdout.write(sep) self.stdout.write(header) self.stdout.write(sep) # In a single query, walk through all objects in a logical order, # which traverses through the tree from parent to children. translations = (UrlNode_Translation.objects .select_related('master') .order_by('master__parent_site__id', 'master__tree_id', 'master__lft', 'language_code') ) for translation in translations: slugs.setdefault(translation.language_code, {})[translation.master_id] = translation.slug overrides.setdefault(translation.language_code, {})[translation.master_id] = translation.override_url page = translation.master if page.parent_id: if page.parent_id not in slugs[translation.language_code]: self.stderr.write("WARNING: Parent #{0} is not translated in '{1}', while the child #{2} is.".format( page.parent_id, translation.language_code, translation.master_id )) old_url = translation._cached_url try: new_url = self._construct_url(translation.language_code, translation.master_id, parents, slugs, overrides) except KeyError: if is_dry_run: # When the mptt tree is broken, some URLs can't be correctly generated yet. self.stderr.write("Failed to determine new URL for {0}, please run with --mptt-only first.".format(old_url)) return raise if old_url != new_url: translation._cached_url = new_url if not is_dry_run: translation.save() if old_url != new_url: self.stdout.write(smart_text(u"{0} {1} {2}\n".format( col_style.format( page.parent_site_id, page.pk, page.plugin.type_name, translation.language_code, translation._cached_url ), "WILL CHANGE from" if is_dry_run else "UPDATED from", old_url ))) else: self.stdout.write(smart_text(col_style.format( page.parent_site_id, page.pk, page.plugin.type_name, translation.language_code, translation._cached_url )))