Exemple #1
0
def new(request, site):
    if request.method != 'POST':
        return redirect('admin:sites.articles.list', site)

    active_site = Site.get_cached_by_id(site)
    category = request.POST['category']
    if category not in [c[0] for c in Article.CATEGORY_CHOICES]:
        raise PermissionDenied

    article = Article(
        category=category,
        thumbnail=None,
        hide_thumbnail=False,
        published=False,
        pub_date=None,
        unpub_date=None,
        created_by=request.user,
        site=active_site,
    )
    article.save()
    version = Version(page=None, article=article, version=1, owner=request.user, active=True)
    version.save()
    version.publishers.add(request.user)
    create_template(request.POST['template'], version, request.POST['title'])
    return redirect('admin:sites.articles.edit', active_site.id, version.id)
Exemple #2
0
def new(request, site):
    active_site = Site.get_cached_by_id(site)

    if request.method != 'POST':
        return redirect('admin:sites.pages.page.list', active_site.id)

    slug = request.POST['slug'].strip().strip('/')

    unused_system_url = not is_system_url(slug, active_site)
    unused_page_slug = Page.slug_is_unique(slug, active_site)

    if not unused_system_url or not unused_page_slug:
        messages.error(request, 'slug_not_unique')
        return redirect('admin:sites.pages.page.new', active_site.id)

    page = Page(
        title=request.POST['title'],
        slug=slug,
        published=False,
        created_by=request.user,
        parent=Page.objects.get(id=request.POST['parent_id']),
        site=active_site,
    )
    page.save()

    version = Version(
        page=page,
        article=None,
        version=1,
        owner=request.user,
        active=True,
    )
    version.save()

    create_template(request.POST['template'], version)
    return redirect('admin:sites.pages.page.edit', active_site.id, version.id)
Exemple #3
0
def create(request):
    if not request.user.is_admin_in_forening(request.active_forening):
        return render(request, 'central/admin/sites/create_disallowed.html')

    available_site_types = []
    for t in Site.TYPE_CHOICES:
        if t[0] == 'mal':
            if not request.user.has_perm('sherpa/admin'):
                continue
        available_site_types.append(t)

    site_templates = Site.objects.filter(
        forening=Forening.DNT_CENTRAL_ID,
        type='mal',
    ).order_by('title')

    context = {
        'available_site_types': available_site_types,
        'site_templates': site_templates,
        'template_types': Site.TEMPLATE_TYPE_CHOICES,
    }

    if request.method == 'GET':
        context['form'] = CreateSiteForm(request.user, auto_id='%s')
        return render(request, 'central/admin/sites/create.html', context)

    elif request.method == 'POST':
        form = CreateSiteForm(request.user, request.POST, auto_id='%s')
        context['form'] = form

        if not form.is_valid():
            return render(request, 'central/admin/sites/create.html', context)

        if not request.POST['domain-type'] in ['fqdn', 'subdomain']:
            raise PermissionDenied

        site_forening = form.cleaned_data['forening']
        type = form.cleaned_data['type']
        title = form.cleaned_data['title']
        template_main = form.cleaned_data['template_main']
        template_type = form.cleaned_data['template_type']
        template_description = form.cleaned_data['template_description']
        domain = form.cleaned_data['domain']

        site = Site(
            domain=domain,
            type=type,
            forening=site_forening,
            title=title,
            template_main=template_main,
            template_type=template_type,
            template_description=template_description,
        )

        site.save()

        # If this is a main template, clear other templates of this type in case any of them were previous main
        if site.type == 'mal' and site.template_main:
            Site.objects.filter(
                type=site.type,
                template_type=site.template_type,
            ).exclude(
                id=site.id,
            ).update(
                template_main=False
            )

        # Invalidate the forening's homepage site cache
        cache.delete('forening.homepage_site.%s' % site_forening.id)

        if 'use-template' not in request.POST:
            # User explicitly requested not to clone any template, just create a front page
            page = Page(
                site=site,
                title='Forside',
                published=True,
                created_by=request.user,
                created_date=datetime.now(),
            )
            page.save()

            version = Version(
                page=page,
                version=1,
                owner=request.user,
            )
            version.save()
        elif request.POST.get('template', '').strip() == '':
            # Sherpa-admin error; a site-template for the chosen site type doesn't exist!
            # This needs to be fixed.
            logger.error(
                "Sherpa-bruker opprettet en site med en mal som ikke finnes",
                extra={
                    'request': request,
                    'missing_template_type': request.POST.get('missing-template-type', '<unknown>'),
                }
            )
            site.delete()
            messages.error(request, 'invalid_template')
            return render(request, 'central/admin/sites/create.html', context)
        else:
            # All right, let's clone the entire template site
            # Note that for most objects, we'll just set the primary key to None, change the site field to the
            # new site, and save it, which will insert a new object.
            # For related fields, we'll need to save the related set in memory before saving the new object, so
            # that we can iterate it, clone them and re-relate them to the new object
            # Additionally, replace domain name references in content from the template-domain to the new one
            template_site = Site.get_cached_by_id(request.POST['template'])
            assert template_site.type == 'mal'

            # Menus
            for menu in Menu.objects.filter(site=template_site):
                menu.id = None
                menu.site = site

                # Replace domain references with the new site domain
                menu.url = re.sub(template_site.domain, site.domain, menu.url)

                menu.save()

            # Pages

            # Used to map old IDs to their new corresponding pages. This is needed because the parent reference can't
            # be duplicated, it needs to be updated with its corresponding new parent
            page_id_mapping = {}

            # Order by the left value in order to insert new nodes in a consistent way
            for page in Page.objects.filter(site=template_site).order_by('lft'):
                versions = page.versions.all()
                old_id = page.id
                page.id = None
                page.site = site

                # Reset MPTT state and let our library recreate them
                page.tree_id = None
                page.lft = None
                page.rght = None
                page.level = None

                # Set parent to the corresponding clone; use the old parent id to retrieve it
                if page.parent is not None:
                    page.parent = page_id_mapping[page.parent.id]

                # Change creation to the user creating the new site and reset modification
                page.created_by = request.user
                page.created_date = datetime.now()
                page.modified_by = None
                page.modified_date = None

                # Insert the new node appropriately
                if page.parent is None:
                    Page.objects.insert_node(page, target=None, save=True)
                else:
                    Page.objects.insert_node(page, target=page.parent, position='last-child', save=True)

                page.save()

                # Remember which old id maps to this page
                page_id_mapping[old_id] = page

                for version in versions:
                    rows = version.rows.all()
                    version.id = None
                    version.page = page
                    version.save()

                    for row in rows:
                        columns = row.columns.all()
                        row.id = None
                        row.version = version
                        row.save()

                        for column in columns:
                            contents = column.contents.all()
                            column.id = None
                            column.row = row
                            column.save()

                            for content in contents:
                                content.id = None
                                content.column = column

                                # Replace domain references with the new site domain
                                # Use a json dump with prepended/trailing quotes stripped to ensure the
                                # replacement string is properly escaped if inserted into json-formatted content
                                json_safe_domain = json.dumps(site.domain)[1:-1]
                                content.content = re.sub(template_site.domain, json_safe_domain, content.content)

                                # For aktiviteteslisting-widgets, force arranger-filter to the new site's related
                                # forening
                                if content.type == 'widget':
                                    parsed_content = json.loads(content.content)
                                    if parsed_content['widget'] == 'aktivitet_listing':
                                        # Note that the list of ids contains strings, because we forgot to convert
                                        # it to int in the widget-editor save logic, but that's not a problem since
                                        # the filter lookup will implicitly convert it. So force it to str to be
                                        # consistent
                                        parsed_content['foreninger'] = [str(site.forening.id)]
                                        content.content = json.dumps(parsed_content)

                                content.save()

            # Articles
            for article in Article.objects.filter(site=template_site):
                versions = article.versions.all()
                article.id = None
                article.site = site

                # Change creation to the user creating the new site and reset modification
                article.created_by = request.user
                article.created_date = datetime.now()
                article.modified_by = None
                article.modified_date = None

                article.save()

                for version in versions:
                    rows = version.rows.all()
                    version.id = None
                    version.article = article
                    version.save()

                    for row in rows:
                        columns = row.columns.all()
                        row.id = None
                        row.version = version
                        row.save()

                        for column in columns:
                            contents = column.contents.all()
                            column.id = None
                            column.row = row
                            column.save()

                            for content in contents:
                                content.id = None
                                content.column = column

                                # Replace domain references with the new site domain
                                # Use a json dump with prepended/trailing quotes stripped to ensure the
                                # replacement string is properly escaped if inserted into json-formatted content
                                json_safe_domain = json.dumps(site.domain)[1:-1]
                                content.content = re.sub(template_site.domain, json_safe_domain, content.content)

                                # For aktiviteteslisting-widgets, force arranger-filter to the new site's related
                                # forening
                                if content.type == 'widget':
                                    parsed_content = json.loads(content.content)
                                    if parsed_content['widget'] == 'aktivitet_listing':
                                        # Note that the list of ids contains strings, because we forgot to convert
                                        # it to int in the widget-editor save logic, but that's not a problem since
                                        # the filter lookup will implicitly convert it. So force it to str to be
                                        # consistent
                                        parsed_content['foreninger'] = [str(site.forening.id)]
                                        content.content = json.dumps(parsed_content)

                                content.save()

            # Campaigns
            for campaign in Campaign.objects.filter(site=template_site):
                campaign_texts = campaign.text.all()
                campaign.id = None
                campaign.site = site

                # Replace domain references with the new site domain
                campaign.button_anchor = re.sub(template_site.domain, site.domain, campaign.button_anchor)

                campaign.save()

                for campaign_text in campaign_texts:
                    campaign_text.id = None
                    campaign_text.campaign = campaign
                    campaign_text.save()

        # Add default language menu options
        LanguageMenuOption.objects.create(
            site=site,
            label="English",
            destination="https://english.dnt.no/",
            sort=1
        )
        LanguageMenuOption.objects.create(
            site=site,
            label="Deutsch",
            destination="https://deutsch.dnt.no/",
            sort=2
        )
        LanguageMenuOption.objects.create(
            site=site,
            label="Français",
            destination="https://www.dnt.no/francais/",
            sort=3
        )

        request.session.modified = True
        messages.info(request, 'site_created')
        return redirect('admin:sites.show', site.id)