コード例 #1
0
    def test_create_map(self, client):
        root = Node.root()
        r = root.add(langslugs=dict(fr="fr", en="en", nl="nl"))

        assert Node.get("/fr", language="fr") == \
               Node.get("/en", language="en") == \
               Node.get("/nl", language="nl") == r
コード例 #2
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_remove_single_root(self, client, root):
        """ single, non-recursive removal """
        root.add("aaa")
        assert Node.get("/aaa")

        root.remove("aaa")
        assert not Node.get("/aaa")
コード例 #3
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_remove_single_child(self, client, root):
        """ single, non-recursive removal """
        child = root.add("aaa")
        child.add("bbb")

        assert Node.get("/aaa/bbb")

        child.remove("bbb")
        assert not Node.get("/aaa/bbb")
コード例 #4
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_remove_recursive(self, client, root):
        """ recursive removal """
        child = root.add("aaa")
        child.add("b1")
        child.add("b2")
        assert Node.get("/aaa/b1")

        root.remove("aaa")
        assert not Node.get("/aaa/b1")
        assert not Node.get("/aaa/b2")
コード例 #5
0
    def test_add_different_slugs(self, client):
        translation.activate('en')
        root = Node.root()
        child = root.add("child")
        child.rename("kind", language="nl")
        grandchild = child.add("grandchild")

        assert grandchild.get_path(language="nl") == "/kind/grandchild"
        assert grandchild.get_path(language="en") == "/child/grandchild"
        assert Node.get("/child/grandchild", language="nl") is None
        assert Node.get("/kind/grandchild", language="en") is None
コード例 #6
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_remove_recursive_child(self, client, root):
        """ recursive removal """
        c1 = root.add("aaa")
        c2 = c1.add("bbb")
        c2.add("b1")
        c2.add("b2")
        assert Node.get("/aaa/bbb/b1")

        c1.remove("bbb")
        assert Node.get("/aaa")
        assert not Node.get("/aaa/bbb/b1")
        assert not Node.get("/aaa/bbb/b2")
コード例 #7
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_move_node(self, client, root):
        """ move a node and its descendants elsewhere """
        src = root.add("src")
        src_c = src.add("child")
        target = root.add("target")

        res, success, failed = target.paste(src)

        assert Node.get('/target/src') == src
        assert Node.get('/target/src/child') == src_c
        assert Node.get('/src') is None
        assert res.path == "/target/src"
コード例 #8
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_remove_ignore_similar(self, client, root):
        """ removing /aaa shouldn't affect /aaaa """
        root.add("aaa")
        root.add("aaaa")

        root.remove("aaa")
        assert Node.get("/aaaa")
コード例 #9
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_move_node_inuse(self, client, root):
        """ pasting a node to a node containing a child with the same name,
            e.g. pasting /foo to /target when there's already a /target/foo
        """
        src = root.add("src")
        src_c = src.add("child")
        target = root.add("target")
        target_src = target.add("src")

        # import pytest; pytest.set_trace()
        res, success, failed = target.paste(src)

        assert Node.get('/target/src') == target_src
        assert src.path != "/src"
        assert src.path != "/target/src"
        assert Node.get(src.path + "/child")
コード例 #10
0
    def test_rename_complex(self, client):
        """ a rather confusing case:
            try to swap /r1 and /r2 for a specific language """
        translation.activate('en')
        root = Node.root()
        r1 = root.add("r1")
        r11 = r1.add("r11")
        r2 = root.add("r2")
        r22 = r2.add("r22")

        r1.rename("rX", language="nl")
        r2.rename("r1", language="nl")
        r1.rename("r2", language="nl")

        assert Node.get("/r1", language="nl") == r2
        assert Node.get("/r2", language="nl") == r1
コード例 #11
0
    def test_copy(self, client):
        root = Node.root()
        src = root.add(langslugs=dict(fr="source", nl="bron", en="src"))
        src2 = src.add(langslugs=dict(fr="fr", nl="nl", en="en"))
        target = root.add(langslugs=dict(fr="destination",
                                         nl="doel", en="target"))

        target.paste(src, copy=True)

        assert Node.get("/source", language="fr") == src
        assert Node.get("/destination/source", language="fr") is not None
        assert Node.get("/destination/source/fr", language="fr") is not None
        assert Node.get("/destination/source", language="fr") != src
        assert Node.get("/doel/bron", language="nl") is not None
        assert Node.get("/doel/bron/nl", language="nl") is not None
        assert Node.get("/doel/bron", language="nl") != src
        assert Node.get("/target/src", language="en") is not None
        assert Node.get("/target/src/en", language="en") is not None
        assert Node.get("/target/src", language="en") != src
コード例 #12
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_copy_node_position(self, client, root):
        """ a node loses its original position when copied,
            it should always be moved to the bottom """
        src = root.add("src", position=0)
        target = root.add("target")
        target_child = target.add("child", position=10)

        res, success, failed = target.paste(src, copy=True)

        assert Node.get("/target/src").position > target_child.position
コード例 #13
0
ファイル: forms.py プロジェクト: reichertwd/wheelcms_axle
    def clean_slug(self):
        if self.attach:
            return

        slug = self.data.get("slug", "").strip().lower()

        language = self.data.get("language", settings.FALLBACK)

        ## XXX move the whole slug generation / stopwords stuff to separate method
        title = self.cleaned_data.get("title", "").lower()
        title_no_sw = " ".join(x for x in title.split() if x not in set(stopwords.get(language, [])))

        parent_path = self.parent.get_path(language=language)

        if not slug:
            slug = re.sub("[^%s]+" % Node.ALLOWED_CHARS, "-", title_no_sw)[: Node.MAX_PATHLEN].strip("-")
            slug = re.sub("-+", "-", slug)

            ## slug may be empty now by all space/stopwords/dash removal
            if not slug:
                slug = "node"
            existing = Node.get(path=parent_path + "/" + slug, language=language)

            base_slug = slug[: Node.MAX_PATHLEN - 6]  ## some space for counter
            count = 1
            while (existing and existing != self.node) or (slug in self.reserved):
                slug = base_slug + str(count)
                existing = Node.get(path=self.parent.path + "/" + slug, language=language)

                count += 1

        if slug in self.reserved:
            raise forms.ValidationError("This is a reserved name")

        if not Node.validpathre.match(slug):
            raise forms.ValidationError("Only numbers, letters, _-")
        existing = Node.get(path=parent_path + "/" + slug, language=language)
        if existing and existing != self.node:
            raise forms.ValidationError("Name in use")

        return slug
コード例 #14
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_move_node_duplicate_name(self, client, root):
        """ Move a node somewhere where there's already a similar slug """
        # issue #789
        src = root.add("src")
        src_c = src.add("child")
        root_child = root.add("child")

        res, success, failed = root.paste(src_c)

        assert Node.get('/child') == root_child
        assert src_c.parent() == root
        assert src_c.path.startswith('/')
コード例 #15
0
ファイル: forms.py プロジェクト: wheelcms/wheelcms_axle
    def clean_slug(self):
        if self.attach:
            return

        slug = self.data.get('slug', '').strip().lower()


        language = self.data.get('language', settings.FALLBACK)

        parent_path = self.parent.get_path(language=language)

        if not slug:
            title = self.cleaned_data.get('title', '')
            slug = generate_slug(title, language=language,
                                 max_length=Node.MAX_PATHLEN,
                                 allowed=Node.ALLOWED_CHARS,
                                 default="node")


            existing = Node.get(path=parent_path + "/" + slug, language=language)

            base_slug = slug[:Node.MAX_PATHLEN-6] ## some space for counter
            count = 1
            while (existing and existing != self.node) or \
                  (slug in self.reserved):
                slug = base_slug + str(count)
                existing = Node.get(path=self.parent.path + '/' + slug, language=language)

                count += 1

        if slug in self.reserved:
            raise forms.ValidationError("This is a reserved name")

        if not Node.validpathre.match(slug):
            raise forms.ValidationError("Only numbers, letters, _-")
        existing = Node.get(path=parent_path + "/" + slug, language=language)
        if existing and existing != self.node:
            raise forms.ValidationError("Name in use")

        return slug
コード例 #16
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_copy_node_inuse(self, client, root):
        """ pasting a node to a node containing a child with the same name,
            e.g. pasting /foo to /target when there's already a /target/foo
        """
        src = root.add("src")
        src_c = src.add("child")
        target = root.add("target")
        target_src = target.add("src")

        res, success, failed = target.paste(src)

        assert res.path != "/target/src"
        assert Node.get(res.path + "/child")
コード例 #17
0
    def test_node_slug_offspring_language(self, client):
        """ A node with different slugs for different languages,
            with children"""
        translation.activate('en')
        root = Node.root()
        child = root.add("child")
        child1 = child.add("grandchild1")
        child2 = child.add("grandchild2")

        # import pytest; pytest.set_trace()
        child.rename("kind", language="nl")
        child2.rename("kleinkind2", language="nl")


        translation.activate('nl')
        nl_child2 = Node.get("/kind/kleinkind2")
        assert nl_child2 == child2
        assert nl_child2.path == "/kind/kleinkind2"

        nl_child1 = Node.get("/kind/grandchild1")
        assert nl_child1 == child1
        assert nl_child1.path == "/kind/grandchild1"
コード例 #18
0
ファイル: main.py プロジェクト: wheelcms/wheelcms_axle
    def breadcrumb(self, operation="", details=""):
        """ generate breadcrumb path. """
        language = self.active_language()

        base = self.instance or self.parent
        if not base:
            ## parent
            return []

        parts = base.get_path(language=language).split("/")
        res = []
        for i in range(len(parts)):
            subpath = "/".join(parts[:i+1])
            node = Node.get(subpath, language=language)
            content = node.content(language=language)
            primary_content = node.primary_content()

            ## If we're in "contents" mode, link to the node's
            ## contents view.

            if operation == "Contents":
                subpath += '/contents'

            path = node.get_absolute_url()

            ## last entry should not get path
            if not operation:
                if i == len(parts) - 1:
                    path = ""

            if node.isroot():
                if primary_content and not content:
                    title = "Home (untranslated)"
                elif content:
                    title = "Home"
                else:
                    title = "Unattached rootnode"
            else:
                if primary_content and not content:
                    title = 'Untranslated content "%s"' % primary_content.title
                elif not content:
                    title = "Unattached node %s" % (subpath or '/')
                else:
                    title = content.title

            res.append((title, path))

        if operation:
            res.append((operation + details, ""))

        return res
コード例 #19
0
 def test_node(self, client):
     translation.activate('en')
     root = Node.root()
     child = root.add("child")
     en_child = Node.get("/child")
     assert en_child == child
     assert en_child.path == "/child"
     assert en_child.slug() == "child"
     assert en_child.get_path("en") == "/child"
     assert en_child.slug("en") == "child"
     assert en_child.get_path("nl") == "/child"
     assert en_child.slug("nl") == "child"
     assert en_child.get_path("fr") == "/child"
     assert en_child.slug("fr") == "child"
コード例 #20
0
    def test_copy_content_node_unique_sub(self, client):
        root = Node.root()
        sub = root.add("sub")
        Type1(title="content on sub", node=sub).save()
        subc1 = sub.add("c1")
        TypeUnique(uniek="unique content on sub/c1", node=subc1).save()
        subc2 = sub.add("c2")
        Type1(title="content on sub/c2", node=subc2).save()

        subunique = subc1.add("subunique")

        sub2, success, failed = root.paste(sub, copy=True)
        assert len(sub2.children()) == 1
        assert Node.get(sub2.path + "/c1/subunique") is None
        assert len(success) == 2
        assert len(failed) == 1
コード例 #21
0
ファイル: main.py プロジェクト: wheelcms/wheelcms_axle
    def resolve(cls, nodepath):
        """ resolve a node path to an actual node in correct language 
            context. """
        ## Do a bit of path normalization: Except for root, start with /,
        ## remove trailing /
        ## Old 'coerce' used to
        # locale.activate_content_language(None)
        ## Is that necessary for anything?
        if nodepath in ("/", ""):
            nodepath = ""
        else:
            nodepath = "/{0}".format(nodepath.strip('/'))

        language = get_active_language()

        return Node.get(nodepath, language=language)
コード例 #22
0
ファイル: test_node.py プロジェクト: wheelcms/wheelcms_axle
    def test_copy_node(self, client, root):
        """ copy a node and its descendants elsewhere """
        src = root.add("src")
        src_c = src.add("child")
        target = root.add("target")

        target.paste(src, copy=True)

        ## it has been copied and is not the original
        assert Node.get('/target/src') is not None
        assert Node.get('/target/src') != src
        assert Node.get('/target/src/child') is not None
        assert Node.get('/target/src/child') != src_c

        ## the original is still there
        assert Node.get('/src') is not None
        assert Node.get('/src') == src
        assert Node.get('/src/child') is not None
        assert Node.get('/src/child') == src_c
コード例 #23
0
    def test_node_slug_language(self, client):
        """ A node with different slugs for different languages """
        translation.activate('en')
        root = Node.root()
        child = root.add("child")
        child.rename("kind", language="nl")
        child.rename("enfant", language="fr")

        translation.activate('nl')
        nl_child = Node.get("/kind")
        assert nl_child == child
        assert nl_child.path == "/kind"
        assert nl_child.slug() == "kind"
        assert nl_child.get_path("nl") == "/kind"

        assert nl_child.get_path("en") == "/child"
        assert nl_child.slug("en") == "child"
        assert nl_child.get_path("fr") == "/enfant"
        assert nl_child.slug("fr") == "enfant"
コード例 #24
0
    def test_move(self, client):
        ## meteen recursief
        root = Node.root()
        src = root.add(langslugs=dict(fr="source", nl="bron", en="src"))
        src2 = src.add(langslugs=dict(fr="fr", nl="nl", en="en"))

        # import pytest;pytest.set_trace()
        target = root.add(langslugs=dict(fr="destination",
                                         nl="doel", en="target"))

        target.paste(src, copy=False)

        assert Node.get("/source", language="fr") is None
        assert Node.get("/destination/source", language="fr") == src
        assert Node.get("/destination/source/fr", language="fr") == src2
        assert Node.get("/doel/bron", language="nl") == src
        assert Node.get("/doel/bron/nl", language="nl") == src2
        assert Node.get("/target/src", language="en") == src
        assert Node.get("/target/src/en", language="en") == src2
コード例 #25
0
ファイル: test_node.py プロジェクト: reichertwd/wheelcms_axle
 def test_direct_path(self, client):
     """ retrieve a node directly through its path """
     n = Node.root().add("a").add("b").add("c")
     assert Node.get("/a/b/c") == n
コード例 #26
0
ファイル: test_node.py プロジェクト: reichertwd/wheelcms_axle
 def test_direct_root(self, client):
     """ retrieve the root node directly through its path """
     n = Node.root()
     assert Node.get("") == n
コード例 #27
0
ファイル: main.py プロジェクト: wheelcms/wheelcms_axle
    def handle_panel_selection_details(self, path, type, klass="", title="",
                                       target="", download=False,
                                       newselection=False):
        """
            Setup the panel to configure a link/image insert
        """
        ## resolve relative / prefixed url to absolute node path
        path = resolve_path(path)

        node = Node.get(path)
        instance = None
        spoke = None
        default_title = title

        if node:
            instance = node.content()
            spoke = instance.spoke()
            if newselection:
                default_title = instance.title

        SIZE_CHOICES = (
            ("img_content_original", "Original"),
            ("img_content_thumb", "Thumb"),
            ("img_content_small", "Small"),
            ("img_content_medium", "Medium"),
            ("img_content_large", "Large"),
        )
        FLOAT_CHOICES = (
            ("img_align_left", "Left"),
            ("img_align_center", "Center"),
            ("img_align_right", "Right")
        )
        ALIGN_CHOICES = (
            ("img_align_top", "Top"),
            ("img_align_middle", "Middle"),
            ("img_align_bottom", "Bottom")
        )

        TARGET_CHOICES = (
            ("_self", "Same window"),
            ("_blank", "New window"),
        )
        ## _parent and _top are not sensible options, nor is an explicit
        ## framename

        ## translate klass back to size/float/align
        forminitial = dict(title=default_title, target=target, download=download,
                           size=SIZE_CHOICES[-1][0],
                           float=FLOAT_CHOICES[1][0],
                           align=ALIGN_CHOICES[0][0])

        ## if not target, determine local/new based on locality of url
        if not forminitial['target']:
            if path:
                forminitial['target'] = "_self"
            else:
                forminitial['target'] = "_blank"
        klass_parts = klass.split()

        for part in klass_parts:
            if part in [s[0] for s in SIZE_CHOICES]:
                forminitial['size'] = part
            if part in [f[0] for f in FLOAT_CHOICES]:
                forminitial['float'] = part
            if part in [a[0] for a in ALIGN_CHOICES]:
                forminitial['align'] = part

        class PropForm(AngularForm):
            ng_ns = "propsform"

            title = forms.CharField()
            if type == "link":
                target = forms.ChoiceField(choices=TARGET_CHOICES,
                                           initial="_self",
                         help_text="Where should the link open in when clicked?")
                if spoke and isinstance(spoke, FileSpoke):
                    download = forms.BooleanField(
                                help_text="If checked, link will point to "
                                "download immediately in stead of File content")
            if type == "image":
                size = forms.ChoiceField(choices=SIZE_CHOICES)
                float = forms.ChoiceField(choices=FLOAT_CHOICES)
                align = forms.ChoiceField(choices=ALIGN_CHOICES)

        propform = PropForm(initial=forminitial)

        return dict(initialdata=forminitial,
                    template=self.render_template("wheelcms_axle/popup_properties.html", spoke=spoke,
                             instance=instance, mode=type, form=propform))
コード例 #28
0
ファイル: test_node.py プロジェクト: reichertwd/wheelcms_axle
 def test_direct_path_notfound(self, client):
     """ retrieve a node directly through its path """
     Node.root().add("a").add("b").add("c")
     assert Node.get("/d/e/f") is None
コード例 #29
0
ファイル: test_node.py プロジェクト: reichertwd/wheelcms_axle
 def test_root_lookup(self, client):
     """ get("") should implicitly create root node """
     assert Node.get("").isroot()
コード例 #30
0
ファイル: main.py プロジェクト: wheelcms/wheelcms_axle
    def panels(self, path, original, mode):
        """
            Generate panels for the file selection popup
            mode can be either "link" (any content) or "image" (only image
            based content)
        """
        language = self.active_language()
        if not self.hasaccess():
            return self.forbidden()


        ##
        ## No path means a new item is to be selected. Use the current
        ## item as a starting point
        
        if not path:
            path = self.instance.path
        else:
            path = resolve_path(path)

        if path is None:
            return self.notfound()

        original = resolve_path(original) or ""

        ## remove optional 'action', marked by a +
        ## not sure if this is the right place to do this, or if the browser
        ## modal should have been invoked without the action in the first place


        path = strip_action(path)
        original = strip_action(original)

        node = start = Node.get(path)# , language=language)

        ##
        ## Selectable means the node is a valid selection. Unattached
        ## nodes are never selectable and in image mode only image based
        ## content is a valid selection
        def is_selectable(node):
            content = node.content()
            if content:
                if mode == "link":
                    return True
                elif isinstance(content, ImageContent):
                    return True
            return False

        ## Is the starting point a valid selection?
        start_selectable = is_selectable(node)

        panels = []

        ## first panel: bookmarks/shortcuts

        bookmarks_paths = [''] # root
        if self.instance.path not in bookmarks_paths:
            bookmarks_paths.append(self.instance.path)
        #if path not in bookmarks_paths:
        #    bookmarks_paths.append(path)
        ## original can also be an external url, starting with http
        if original not in bookmarks_paths and not original.startswith("http"):
            bookmarks_paths.append(original)

        bookmarks = []

        for p in bookmarks_paths:
            ## handle non-existing nodes and unattached nodes
            n = Node.get(p)
            if not n:
                continue
            content = n.content()
            if not content: ## unattached
                continue
            spoke = content.spoke()
            selectable = is_selectable(n)
            bookmarks.append(dict(children=[], path=n.get_absolute_url(),
                            title=content.title,
                            meta_type=content.meta_type,
                            content=content,
                            selectable=selectable,
                            icon=spoke.icon_base() + '/' + spoke.icon,
                            spoke=spoke))

        panels.append(self.render_template("wheelcms_axle/popup_links.html",
                                           instance=self.instance,
                                           bookmarks=bookmarks
                                           ))
        upload = False

        for i in range(2):
            content = node.content()

            if content:
                ## FileSpoke also includes ImageSpoke

                spoke = content.spoke()
                addables = [x for x in spoke.addable_children()
                            if issubclass(x, FileSpoke)]
                instance = dict(children=[], path=node.get_absolute_url(),
                                title=content.title,
                                meta_type=content.meta_type,
                                content=content,
                                spoke=spoke,
                                addables=addables)
            else:
                addables = [x for x in type_registry.values()
                            if issubclass(x, FileSpoke)]
                instance = dict(children=[], path=node.get_absolute_url(),
                                title="Unattached node",
                                meta_type="none",
                                content=None,
                                spoke=None,
                                addables=addables)

            if i == 0:
                ## first iteration means current context. Check if uploading
                ## is possible.
                upload = bool(addables)

            for child in node.children():
                content = child.content()

                if not content:
                    continue  ## ignore unattached nodes
                spoke = content.spoke()

                selectable = is_selectable(child)

                selected = path == child.path or \
                           path.startswith(child.path + '/')
                instance['children'].append(
                                      dict(title=content.title,
                                           path=child.get_absolute_url(),
                                           icon=spoke.icon_base() + '/' +
                                                spoke.icon,
                                           selectable=selectable,
                                           meta_type=content.meta_type,
                                           selected=selected))

            panels.insert(1,
                          self.render_template("wheelcms_axle/popup_list.html",
                                               instance=instance,
                                               path=node.get_absolute_url(),
                                               mode=mode,
                                               selectable=(i==0)))
            if node.isroot():
                break
            node = node.parent()

        ## generate the crumbs
        crumbs = []
        node = start
        while True:
            content = node.content()
            selectable = is_selectable(node)
            if node.isroot():
                crumbs.insert(0, dict(path=node.get_absolute_url(),
                                      selectable=selectable, title="Home"))
                break
            crumbs.insert(0, dict(path=node.get_absolute_url(),
                                  selectable=selectable,
                                  title=node.content().title))
            node = node.parent()

        crumbtpl = self.render_template("wheelcms_axle/popup_crumbs.html",
                                        crumbs=crumbs)
        return dict(panels=panels, path=start.get_absolute_url(),
                    crumbs=crumbtpl, upload=upload, selectable=start_selectable)