Exemplo n.º 1
0
 def test_it(self):
     from kotti.views.view import view_node
     session = DBSession()
     root = session.query(Node).get(1)
     request = testing.DummyRequest()
     info = view_node(root, request)
     self.assertEqual(info['api'].context, root)
Exemplo n.º 2
0
def populate():
    """
    Create the root node (:class:`~kotti.resources.Document`) and the 'about'
    subnode in the nodes tree if there are no nodes yet.
    """
    lrm = LocalizerRequestMixin()
    lrm.registry = get_current_registry()
    lrm.locale_name = get_settings()['pyramid.default_locale_name']
    localizer = lrm.localizer

    if DBSession.query(Node).count() == 0:
        localized_root_attrs = dict(
            [(k, localizer.translate(v)) for k, v in _ROOT_ATTRS.iteritems()])
        root = Document(**localized_root_attrs)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        localized_about_attrs = dict(
            [(k, localizer.translate(v)) for k, v in _ABOUT_ATTRS.iteritems()])
        root['about'] = Document(**localized_about_attrs)

        wf = get_workflow(root)
        if wf is not None:
            DBSession.flush()  # Initializes workflow
            wf.transition_to_state(root, None, u'public')

    populate_users()
Exemplo n.º 3
0
    def test_order_of_addable_parents(self):
        from kotti.views.edit import add_node
        # The 'add_node' view sorts the 'possible_parents' returned by
        # 'addable_types' so that the parent comes first if the
        # context we're looking at does not have any children yet.

        session = DBSession()
        root = session.query(Node).get(1)
        request = testing.DummyRequest()

        with nodes_addable():
            # The child Document does not contain any other Nodes, so it's
            # second in the 'possible_parents' list returned by 'node_add':
            child = root['child'] = Document(title=u"Child")
            info = add_node(child, request)
            first_parent, second_parent = info['possible_parents']
            self.assertEqual(first_parent['node'], root)
            self.assertEqual(second_parent['node'], child)

            # Now we add a grandchild and see that this behaviour changes:
            child['grandchild'] = Document(title=u"Grandchild")
            info = add_node(child, request)
            first_parent, second_parent = info['possible_parents']
            self.assertEqual(first_parent['node'], child)
            self.assertEqual(second_parent['node'], root)
Exemplo n.º 4
0
def populate():
    """
    Create the root node (:class:`~kotti.resources.Document`) and the 'about'
    subnode in the nodes tree if there are no nodes yet.
    """
    lrm = LocalizerRequestMixin()
    lrm.registry = get_current_registry()
    # noinspection PyPropertyAccess
    lrm.locale_name = get_settings()["pyramid.default_locale_name"]
    localizer = lrm.localizer

    if DBSession.query(Node.id).count() == 0:
        localized_root_attrs = {
            k: localizer.translate(v)
            for k, v in _ROOT_ATTRS.items()
        }
        root = Document(**localized_root_attrs)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        localized_about_attrs = {
            k: localizer.translate(v)
            for k, v in _ABOUT_ATTRS.items()
        }
        root["about"] = Document(**localized_about_attrs)

        wf = get_workflow(root)
        if wf is not None:
            DBSession.flush()  # Initializes workflow
            wf.transition_to_state(root, None, "public")

    populate_users()
Exemplo n.º 5
0
def _add_document_from_file(filename, name, parent, title, package='kotti', 
                            directory='populate-content', acl=None):
    body = unicode(resource_string(package, os.path.join(directory, filename)))
    node = Document(name=name, parent=parent, title=title, body=body)
    if acl is not None:
        node.__acl__ = acl
    DBSession.add(node)
    return node
Exemplo n.º 6
0
    def test_unique_constraint(self):
        session = DBSession()

        # Try to add two children with the same name to the root node:
        root = session.query(Node).get(1)
        session.add(Node(name=u'child1', parent=root))
        session.add(Node(name=u'child1', parent=root))
        self.assertRaises(IntegrityError, session.flush)
Exemplo n.º 7
0
def populate():
    if DBSession.query(Node).count() == 0:
        root = Document(**_ROOT_ATTRS)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        root['about'] = Document(**_ABOUT_ATTRS)

    populate_users()
Exemplo n.º 8
0
    def _make(self, context=None, id=1):
        from kotti.views.util import TemplateAPIEdit

        if context is None:
            session = DBSession()
            context = session.query(Node).get(id)

        request = testing.DummyRequest()
        return TemplateAPIEdit(context, request)
Exemplo n.º 9
0
def populate_users():
    principals = get_principals()
    if u'admin' not in principals:
        principals[u'admin'] = {
            'name': u'admin',
            'password': get_settings()['kotti.secret'],
            'title': u"Administrator",
            'groups': [u'role:admin'],
            }
        DBSession.flush()
        transaction.commit()
Exemplo n.º 10
0
    def test_single_choice(self):
        from kotti.views.edit import add_node

        # The view should redirect straight to the add form if there's
        # only one choice of parent and type:
        session = DBSession()
        root = session.query(Node).get(1)
        request = testing.DummyRequest()
        
        response = add_node(root, request)
        self.assertEqual(response.status, '302 Found')
        self.assertEqual(response.location, 'http://example.com/add_document')
Exemplo n.º 11
0
def populate():
    if DBSession.query(Node).count() == 0:
        root = Document(**_ROOT_ATTRS)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        root['about'] = Document(**_ABOUT_ATTRS)

        wf = get_workflow(root)
        if wf is not None:
            DBSession.flush()  # Initializes workflow
            wf.transition_to_state(root, None, u'public')

    populate_users()
Exemplo n.º 12
0
def populate():
    if DBSession.query(Node).count() == 0:
        root = Document(**_ROOT_ATTRS)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        root['about'] = Document(**_ABOUT_ATTRS)

        wf = get_workflow(root)
        if wf is not None:
            DBSession.flush()  # Initializes workflow
            wf.transition_to_state(root, None, u'public')

    populate_users()
def upgrade():

    from kotti.resources import DBSession

    from alembic.context import get_bind

    conn = get_bind()

    if conn.engine.dialect.name == 'mysql':
        update = "update nodes set path = concat(path, '/') where path not \
like '%/'"
    else:
        update = "update nodes set path = path || '/' where path not like '%/'"
    DBSession.execute(update)
Exemplo n.º 14
0
def populate_root_document():
    if DBSession.query(Node).count() == 0:
        root = Document(name=u'', title=u'Front Page')
        root.__acl__ = SITE_ACL
        root.default_view = 'front-page'
        DBSession.add(root)
        url = JOB_CONTAINERS['url']
        root[url] = Document(title=u'Job Containers', owner=u'admin')
        set_groups(u'admin', root[url], set([u'role:owner']))

        wf = get_workflow(root)
        if wf is not None:
            DBSession.flush()  # Initializes workflow
            wf.transition_to_state(root, None, u'public')
def upgrade():

    from kotti.resources import DBSession

    from alembic.context import get_bind

    conn = get_bind()

    if conn.engine.dialect.name == 'mysql':
        update = "update nodes set path = concat(path, '/') where path not \
like '%/'"

    else:
        update = "update nodes set path = path || '/' where path not like '%/'"
    DBSession.execute(update)
Exemplo n.º 16
0
    def test_root_acl(self):
        session = DBSession()
        root = session.query(Node).get(1)

        # The root object has a persistent ACL set:
        self.assertEquals(
            root.__acl__, [
                ('Allow', 'group:managers', security.ALL_PERMISSIONS),
                ('Allow', 'system.Authenticated', ('view',)),
                ('Allow', 'group:editors', ('add', 'edit')),
            ])

        # Note how the last ACE is class-defined, that is, users in
        # the 'managers' group will have all permissions, always.
        # This is to prevent lock-out.
        self.assertEquals(root.__acl__[:-2], root._default_acl())
Exemplo n.º 17
0
 def _used_snippets(self, context, slot):
    snippets = DBSession.query(DocumentSlotToSnippet).filter(
            and_(DocumentSlotToSnippet.document_id == context.id,
                DocumentSlotToSnippet.slot_name == slot))\
                        .order_by(DocumentSlotToSnippet.position).all()
    return [{"snippet": "snippet-%d" % snippet.snippet_id} for 
            snippet in snippets]
def downgrade():
    from kotti import DBSession
    from kotti.resources import Node

    for node in DBSession.query(Node).with_polymorphic([Node]):
        # remove trailing '/' from all nodes but root
        if node.path != u'/':
            node.path = node.path[:-1]
Exemplo n.º 19
0
def add_translation(context, request):
    """XXX: Check that we dont leak anything"""
    source_id = request.params['id']
    source = DBSession.query(Content).get(int(source_id))

    translation = context[source.__name__] = source.copy()
    api.link_translation(source, translation)
    return HTTPFound(location=request.resource_url(translation, 'edit'))
def upgrade():

    from kotti.resources import DBSession

    from alembic.context import get_bind

    conn = get_bind()

    if conn.engine.dialect.name == 'mysql':
        update = "UPDATE nodes " \
                 "SET path = concat(path, '/') " \
                 "WHERE path NOT LIKE '%/'"
    else:
        update = "UPDATE nodes " \
                 "SET path = path || '/' " \
                 "WHERE path NOT LIKE '%/'"
    DBSession.execute(update)
def downgrade():
    from kotti import DBSession
    from kotti.resources import Node

    for node in DBSession.query(Node).with_polymorphic([Node]):
        # remove trailing '/' from all nodes but root
        if node.path != '/':
            node.path = node.path[:-1]
Exemplo n.º 22
0
 def _used_snippets(self, context, slot):
     snippets = DBSession.query(DocumentSlotToSnippet).filter(
             and_(DocumentSlotToSnippet.document_id == context.id,
                 DocumentSlotToSnippet.slot_name == slot))\
                         .order_by(DocumentSlotToSnippet.position).all()
     return [{
         "snippet": "snippet-%d" % snippet.snippet_id
     } for snippet in snippets]
Exemplo n.º 23
0
def populate():
    """
    Create the root node (Document) and the 'about' subnode in the nodes tree
    if there are no nodes yet.
    """

    if DBSession.query(Node).count() == 0:
        root = Document(**_ROOT_ATTRS)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        root['about'] = Document(**_ABOUT_ATTRS)

        wf = get_workflow(root)
        if wf is not None:
            DBSession.flush()  # Initializes workflow
            wf.transition_to_state(root, None, u'public')

    populate_users()
Exemplo n.º 24
0
    def test_multiple_types(self):
        from kotti.views.util import addable_types
        # Test a scenario where we may add multiple types to a folder:
        session = DBSession()
        root = session.query(Node).get(1)
        request = testing.DummyRequest()

        with nodes_addable():
            # We should be able to add both Nodes and Documents now:
            possible_parents, possible_types = addable_types(root, request)
            self.assertEqual(len(possible_parents), 1)
            self.assertEqual(possible_parents[0]['factories'], [Document, Node])

            document_info, node_info = possible_types
            self.assertEqual(document_info['factory'], Document)
            self.assertEqual(node_info['factory'], Node)
            self.assertEqual(document_info['nodes'], [root])
            self.assertEqual(node_info['nodes'], [root])
Exemplo n.º 25
0
def populate():
    """
    Create the root node (:class:`~kotti.resources.Document`) and the 'about'
    subnode in the nodes tree if there are no nodes yet.
    """

    if DBSession.query(Node).count() == 0:
        root = Document(**_ROOT_ATTRS)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        root['about'] = Document(**_ABOUT_ATTRS)

        wf = get_workflow(root)
        if wf is not None:
            DBSession.flush()  # Initializes workflow
            wf.transition_to_state(root, None, u'public')

    populate_users()
Exemplo n.º 26
0
    def test_set_and_get_acl(self):
        session = DBSession()
        root = session.query(Node).get(1)

        # The __acl__ attribute of Nodes allows ACEs to be retrieved
        # and set:
        del root.__acl__
        self.assertRaises(AttributeError, root._get_acl)

        # When setting the ACL, we can also pass 3-tuples instead of
        # instances of ACE:
        root.__acl__ = [('Allow', 'system.Authenticated', ('edit',))]
        self.assertEquals(
            root.__acl__, [
                ('Allow', 'group:managers', security.ALL_PERMISSIONS),
                ('Allow', 'system.Authenticated', ('edit',))
                ])

        root.__acl__ = [
            ACE('Allow', 'system.Authenticated', ('view',)),
            ACE('Deny', 'system.Authenticated', ('view',)),
            ]
        
        self.assertEquals(
            root.__acl__, [
                ('Allow', 'group:managers', security.ALL_PERMISSIONS),
                ('Allow', 'system.Authenticated', ('view',)),
                ('Deny', 'system.Authenticated', ('view',)),
                ])

        # We can reorder the ACL:
        first, second = root.aces
        root.__acl__ = [second, first]
        self.assertEquals(
            root.__acl__, [
                ('Allow', 'group:managers', security.ALL_PERMISSIONS),
                ('Deny', 'system.Authenticated', ('view',)),
                ('Allow', 'system.Authenticated', ('view',)),
                ])
        self.assertEquals(root.aces, [second, first])
        self.assertEquals((first.position, second.position), (1, 0))

        root._del_acl()
        self.assertRaises(AttributeError, root._del_acl)
Exemplo n.º 27
0
def get_source(content):
    """Given a translation target, this returns the translation source
    or None.

    If ``content`` is the source, this returns ``None``.
    """
    translation = DBSession.query(Translation).filter_by(
        target_id=content.id).first()
    if translation is not None:
        return translation.source
Exemplo n.º 28
0
def populate():
    """
    Create the root node (:class:`~kotti.resources.Document`) and the 'about'
    subnode in the nodes tree if there are no nodes yet.
    """
    lrm = LocalizerRequestMixin()
    lrm.registry = get_current_registry()
    lrm.locale_name = get_settings()['pyramid.default_locale_name']
    localizer = lrm.localizer

    if DBSession.query(Node.id).count() == 0:
        pkgdir = os.path.dirname(__file__)
        pagesdir = os.path.join(pkgdir, 'static/pages')
        #import pdb ; pdb.set_trace()
        root_filename = os.path.join(pagesdir, 'index.md')
        root_atts = make_markdown_attrs('', root_filename,
                                        title='Welcome to XYZZY',
                                        description='Home Page')
        root_atts['body'] = markdown.markdown(root_atts['body'])
        root = Document(**root_atts)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        webatts = make_markdown_attrs('webdesign',
                                      os.path.join(
                                          pagesdir, 'webdesign/index.md'),
                                      title='Web Design',
                                      description='Pages on Web Design')
        root['webdesign'] = MarkDownDocument(**webatts)
        wpages = ['history', 'development', 'stylesheets',
                  'javascript-components']
        for wp in wpages:
            wpfn = os.path.join(pagesdir, 'webdesign/%s.md' % wp)
            wptitle = ' '.join([p.capitalize() for p in wp.split('-')])
            wpatts = make_markdown_attrs(wp, wpfn, title=wptitle)
            root['webdesign'][wp] = MarkDownDocument(**wpatts)
        
        wf = get_workflow(root)
        if wf is not None:
            DBSession.flush()  # Initializes workflow
            wf.transition_to_state(root, None, u'public')

    populate_users()
Exemplo n.º 29
0
def autolink_language_root(event):
    context = event.object

    lr = DBSession.query(LanguageRoot).first()
    if lr is None:
        return

    source = api.get_source(lr)
    if source is None:
        source = lr

    api.link_translation(source, context)
Exemplo n.º 30
0
def add_node(context, request):
    """This view's responsibility is to present the user with a form
    where they can choose between locations to add to, and types of
    nodes to add, and redirect to the actual add form based on this
    information.
    """
    all_types = configuration['kotti.available_types']
    
    if request.POST:
        what, where = request.POST['what'], request.POST['where']
        session = DBSession()
        what = [t for t in all_types if t.type_info.name == what][0]
        where = session.query(Node).get(int(where))
        location = resource_url(
            where, request, what.type_info.add_view)
        return HTTPFound(location=location)

    possible_parents, possible_types = addable_types(context, request)
    if len(possible_parents) == 1 and len(possible_parents[0]['factories']) == 1:
        # Redirect to the add form straight away if there's only one
        # choice of parents and addable types:
        parent = possible_parents[0]
        add_view = parent['factories'][0].type_info.add_view
        location = resource_url(parent['node'], request, add_view)
        return HTTPFound(location=location)

    # Swap first and second possible parents if there's no content in
    # 'possible_parents[0]' yet.  This makes the parent then the
    # default choice in the form:
    api = TemplateAPIEdit(context, request)
    if not api.list_children() and len(possible_parents) > 1:
        possible_parents[0], possible_parents[1] = (
            possible_parents[1], possible_parents[0])

    return {
        'api': api,
        'possible_parents': possible_parents,
        'possible_types': possible_types,
        }
Exemplo n.º 31
0
    def test_multiple_parents_and_types(self):
        from kotti.views.util import addable_types
        # A scenario where we can add multiple types to multiple folders:
        session = DBSession()
        root = session.query(Node).get(1)
        request = testing.DummyRequest()

        with nodes_addable():
            # We should be able to add both to the child and to the parent:
            child = root['child'] = Document(title=u"Child")
            possible_parents, possible_types = addable_types(child, request)
            child_parent, root_parent = possible_parents
            self.assertEqual(child_parent['node'], child)
            self.assertEqual(root_parent['node'], root)
            self.assertEqual(child_parent['factories'], [Document, Node])
            self.assertEqual(root_parent['factories'], [Document, Node])

            document_info, node_info = possible_types
            self.assertEqual(document_info['factory'], Document)
            self.assertEqual(node_info['factory'], Node)
            self.assertEqual(document_info['nodes'], [child, root])
            self.assertEqual(node_info['nodes'], [child, root])
Exemplo n.º 32
0
 def save_success(self, appstruct):
     appstruct.pop('csrf_token', None)
     context = self.request.context
     mapper = lambda snippet: ("snippet-%d" % snippet.id, snippet)
     view_name = self.context.default_view or "view"
     slots_names = [name for name, title in get_registered_slots(view_name)]
     for slot in context.slots:
         if slot.name in slots_names:
             snippets = self._available_snippets(context, slot.name)
             snippets = dict(map(mapper, snippets))
             while slot.snippets:
                 slot.snippets.pop()
             for snippet in appstruct[slot.name]:
                 snippet_id = snippet['snippet']
                 if snippet_id in snippets:
                     s = snippets[snippet_id]
                     if s not in slot.snippets:
                         slot.snippets.append(snippets[snippet_id])
             del appstruct[slot.name]
     for slot_name in appstruct:
         snippets = self._available_snippets(context, slot_name)
         snippets = dict(map(mapper, snippets))
         slot = DocumentSlot()
         slot.document = context
         slot.name = slot_name
         for snippet in appstruct[slot_name]:
             snippet_id = snippet['snippet']
             if snippet_id in snippets:
                 s = snippets[snippet_id]
                 if s not in slot.snippets:
                     slot.snippets.append(snippets[snippet_id])
     for slot in context.slots:
         if slot.name not in slots_names:
             context.slots.remove(slot)
             DBSession.delete(slot)
     DBSession.flush()
     return HTTPFound(self.request.resource_url(context))
Exemplo n.º 33
0
 def save_success(self, appstruct):
     appstruct.pop('csrf_token', None)
     context = self.request.context
     mapper = lambda snippet: ("snippet-%d" % snippet.id, snippet)
     view_name = self.context.default_view or "view"
     slots_names = [name for name, title in get_registered_slots(view_name)]
     for slot in context.slots:
         if slot.name in slots_names:
             snippets = self._available_snippets(context, slot.name)
             snippets = dict(map(mapper, snippets))
             while slot.snippets:
                 slot.snippets.pop()
             for snippet in appstruct[slot.name]:
                 snippet_id = snippet['snippet']
                 if snippet_id in snippets:
                     s = snippets[snippet_id]
                     if s not in slot.snippets:
                         slot.snippets.append(snippets[snippet_id])
             del appstruct[slot.name]
     for slot_name in appstruct:
         snippets = self._available_snippets(context, slot_name)
         snippets = dict(map(mapper, snippets))
         slot = DocumentSlot()
         slot.document = context
         slot.name = slot_name
         for snippet in appstruct[slot_name]:
             snippet_id = snippet['snippet']
             if snippet_id in snippets:
                 s = snippets[snippet_id]
                 if s not in slot.snippets:
                     slot.snippets.append(snippets[snippet_id])
     for slot in context.slots:
         if slot.name not in slots_names:
             context.slots.remove(slot)
             DBSession.delete(slot)
     DBSession.flush()
     return HTTPFound(self.request.resource_url(context))
Exemplo n.º 34
0
def get_translations(content):
    source = get_source(content)
    if source is None:
        source = content

    query = DBSession.query(Translation, Content).filter(
        Translation.source_id == source.id,
        Content.id == Translation.target_id,
        )
    res = dict((content.language, content) for translation, content in query)
    res.pop(content.language, None)
    if source is not content:
        res[source.language] = source

    return res
Exemplo n.º 35
0
def populate():
    if DBSession.query(Node).count() == 0:
        root = Document(**_ROOT_ATTRS)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        root['about'] = Document(**_ABOUT_ATTRS)

    if DBSession.query(Settings).count() == 0:
        settings = Settings(data={'kotti.db_version': get_version()})
        DBSession.add(settings)

    populate_users()
Exemplo n.º 36
0
def populate():
    if DBSession.query(Node).count() == 0:
        root = Document(**_ROOT_ATTRS)
        root.__acl__ = SITE_ACL
        DBSession.add(root)
        root['about'] = Document(**_ABOUT_ATTRS)

    if DBSession.query(Settings).count() == 0:
        settings = Settings(data={'kotti.db_version': get_version()})
        DBSession.add(settings)

    populate_users()
Exemplo n.º 37
0
def populate():
    nodecount = DBSession.query(Node).count()
    if nodecount == 0:
        p = _add_document_from_file(
            "home.html", u"", None, u"Welcome to Kotti!", acl=SITE_ACL)
        _add_document_from_file(
            "about.html", u"about", p, u"About")

    settingscount = DBSession.query(Settings).count()
    if settingscount == 0:
        settings = Settings(data={'kotti.db_version': get_version()})
        DBSession.add(settings)

    populate_users()
    DBSession.flush()
    transaction.commit()
Exemplo n.º 38
0
    def test_container_methods(self):
        session = DBSession()

        # Test some of Node's container methods:
        root = session.query(Node).get(1)
        self.assertEquals(root.keys(), [])

        child1 = Node(name=u'child1', parent=root)
        session.add(child1)
        self.assertEquals(root.keys(), [u'child1'])
        self.assertEquals(root[u'child1'], child1)

        del root[u'child1']
        self.assertEquals(root.keys(), [])        

        # When we delete a parent node, all its child nodes will be
        # released as well:
        root[u'child2'] = Node()
        root[u'child2'][u'subchild'] = Node()
        self.assertEquals(
            session.query(Node).filter(Node.name == u'subchild').count(), 1)
        del root[u'child2']
        self.assertEquals(
            session.query(Node).filter(Node.name == u'subchild').count(), 0)
Exemplo n.º 39
0
 def _available_snippets(self, context, slot):
     snippets = DBSession.query(Snippet).all()
     return snippets
def upgrade():

    from kotti.resources import DBSession
    DBSession.execute(
        "update nodes set path = path || '/' where path not like '%/'"
    )