Exemple #1
0
 def fin():
     print("finalizer subidea_thread_phase_1")
     test_session.delete(l_r_1)
     test_session.add(IdeaLink(source=root_idea, target=subidea_1))
     test_session.flush()
Exemple #2
0
def save_idea(request):
    """Update this idea.

    In case the ``parentId`` is changed, handle all
    ``IdeaLink`` changes and send relevant ideas on the socket."""
    discussion = request.context
    user_id = authenticated_userid(request)
    permissions = request.permissions
    idea_id = request.matchdict['id']
    idea_data = json.loads(request.body)
    # Idea.default_db.execute('set transaction isolation level read committed')
    # Special items in TOC, like unsorted posts.
    if idea_id in ['orphan_posts']:
        return {'ok': False, 'id': Idea.uri_generic(idea_id)}

    idea = Idea.get_instance(idea_id)
    db = idea.db
    if not idea:
        raise HTTPNotFound("No such idea: %s" % (idea_id))
    if isinstance(idea, RootIdea):
        raise HTTPBadRequest("Cannot edit root idea.")
    if (idea.discussion_id != discussion.id):
        raise HTTPBadRequest(
            "Idea from discussion %s cannot be saved from different discussion (%s)."
            % (idea.discussion_id, discussion.id))

    context = idea.get_instance_context(request=request)
    for key, attr_name in langstring_fields.items():
        if key in idea_data:
            current = getattr(idea, attr_name)
            ls_data = idea_data[key]
            # TODO: handle legacy string instance?
            subcontext = idea.get_collection_context(key, context)
            if current:
                if ls_data:
                    current.update_from_json(ls_data,
                                             context=subcontext,
                                             permissions=permissions)
                else:
                    current.delete()
            elif ls_data:
                current = LangString.create_from_json(ls_data,
                                                      context=subcontext)
                setattr(idea, attr_name, current._instance)

    new_parent_id = idea_data.get('parentId', None)
    if new_parent_id:
        # TODO: Make sure this is sent as a list!
        # Actually, use embedded links to do this properly...
        new_parent_ids = {new_parent_id}
        old_parent_ids = {
            Idea.uri_generic(l.source_id)
            for l in idea.source_links
        }
        if new_parent_ids != old_parent_ids:
            added_parent_ids = new_parent_ids - old_parent_ids
            removed_parent_ids = old_parent_ids - new_parent_ids
            added_parents = [Idea.get_instance(id) for id in added_parent_ids]
            current_parents = idea.get_parents()
            removed_parents = [
                p for p in current_parents if p.uri() in removed_parent_ids
            ]
            if None in added_parents:
                missing = [
                    id for id in added_parent_ids if not Idea.get_instance(id)
                ]
                raise HTTPNotFound("Missing parentId %s" % (','.join(missing)))
            if not idea.has_permission_req(P_ASSOCIATE_IDEA):
                raise HTTPUnauthorized("Cannot associate idea " + idea.uri())
            for parent in added_parents + removed_parents:
                if not parent.has_permission_req(P_ASSOCIATE_IDEA):
                    raise HTTPUnauthorized("Cannot associate parent idea " +
                                           idea.uri())
            old_ancestors = set()
            new_ancestors = set()
            for parent in current_parents:
                old_ancestors.add(parent)
                old_ancestors.update(parent.get_all_ancestors())
            kill_links = {
                l
                for l in idea.source_links
                if Idea.uri_generic(l.source_id) in removed_parent_ids
            }
            order = idea_data.get('order', 0.0)
            for parent in added_parents:
                if kill_links:
                    link = kill_links.pop()
                    db.expire(link.source, ['target_links'])
                    link.copy(True)
                    link.order = order
                    link.source = parent
                else:
                    link = IdeaLink(source=source, target=idea, order=order)
                    db.add(link)
                db.expire(parent, ['target_links'])
                order += 1.0
            for link in kill_links:
                db.expire(link.source, ['target_links'])
                kill_links.is_tombstone = True
            db.expire(idea, ['source_links'])
            db.flush()
            for parent in idea.get_parents():
                new_ancestors.add(parent)
                new_ancestors.update(parent.get_all_ancestors())
            for ancestor in new_ancestors ^ old_ancestors:
                ancestor.send_to_changes()
        else:
            order = idea_data.get('order', None)
            if order is not None:
                new_parent_id = Idea.get_database_id(new_parent_id)
                parent_links = [
                    link for link in idea.source_links
                    if link.source_id == new_parent_id
                ]
                assert len(parent_links) == 1
                parent_links[0].order = idea_data.get('order', 0.0)

    if 'subtype' in idea_data:
        idea.rdf_type = idea_data['subtype']
    idea.send_to_changes()

    return {'ok': True, 'id': idea.uri()}