def morph_content_to(content, after_type):
    """
    params:
        content can be a Content object or a string id
            - as this works at the database level, any content data not commited to the DB before this call will be lost
        after_type is a string of the type the object is being transformed too
        
    return:
        the new mophed object from the database
        
    Notes:
    This is a VERY expensive operation as it requires up to 3 calls to get_content,
    each of these calls is joining potentialy over 3 tables
    """
    
    content = get_content(content)
    if not content:
        raise Exception('no content to morph')
    
    if content.__type__ == None:
        return content # If we don't know the source object type then we cant process it
    if content.__type__ == after_type:
        return content # If the before and after types are the same then return the content obj as no processing needs to take place
    
    if content.id == None: # If the content has not been commited to the DB
        # then return an object of the correct type?
        # todo? 
        #log.warn('content to morph not in DB? investigate')
        raise Exception('content to morph not in DB? investigate')
    
    id                = content.id
    prev_type         = content.__type__
    sql_generator_key = content.__type__+":"+after_type
    
    if sql_generator_key not in morph_sql:
        raise Exception('unable to morph content from %s to %s' % (content.__type__, after_type) )
    
    Session.expunge(content) # Remove content from SQLAlchemys scope
    for sql_cmd in morph_sql[sql_generator_key](id):
        Session.execute(sql_cmd)
    Session.commit()
    
    content = get_content(id)
    assert content.__type__ == after_type # If this is not true then something has gone very wrong!

    # AllanC - Although the events linked to the commit of this object invalidte the list type for the 'current' content type, they do not take into consideration a content morph from the previous type
    #          In fact .. we need to invalidate the content item manually here because the SQL statement does not associate with the SQLA object and therefor does not trigger the SQLA events
    #          We need to manually invalidate the list that this content object was 'before' the morph
    invalidate_content(content)
    invalidate_content_list(prev_type, content.creator_id)
    
    return content
Example #2
0
def find_content_root(content):
    content = get_content(content)
    
    if not content:
        raise action_error(_('unable to find content'), code=404)
    
    if not content.parent:
        return False
    
    qry = Hierarchy(
        Session,
        Content.__table__,
        select([Content.__table__.c.id, Content.__table__.c.parent_id]),
        starting_node=content.id,
        return_leaf=True,
    ) # FIXME: Greg
    #print qry
    ev = Session.execute(qry).first()
    
    if ev:
        return get_content(ev.id) or False
    else:
        return False
Example #3
0
def upgrade_user_to_group(member_to_upgrade_to_group,
                          new_admins_username,
                          new_group_username=None):
    """
    Only to be called by admins/power users
    This handled the migration of users to groups at an SQL level
    """
    to_group = get_member(member_to_upgrade_to_group)
    admin_user = get_member(new_admins_username)

    # Validation
    if not to_group or to_group.__type__ != 'user':
        raise action_error('member_to_upgrade_to_group not a group', code=404)
    if get_member(new_group_username):
        raise action_error('new_group_username already taken', code=404)
    if admin_user:
        raise action_error('new_admins_username already taken', code=404)

    # Create new admin user
    admin_user = User()
    admin_user.id = new_admins_username
    admin_user.name = new_admins_username
    admin_user.status = 'active'
    admin_user.email = to_group.email
    admin_user.email_unverifyed = to_group.email_unverified
    Session.add(admin_user)
    Session.commit()  # needs to be commited to get id

    sql_cmds = []

    if new_group_username:
        sql_cmds += [
            Member.__table__.update().where(
                Member.__table__.c.id == to_group.id).values(
                    username=new_group_username),
        ]

    sql_cmds += [
        # UPDATE  member set username='******', __type__='group' WHERE id=533;
        Member.__table__.update().where(Member.__table__.c.id == to_group.id
                                        ).values(__type__='group'),

        # Reassign the login details from the old member to the new admin user
        UserLogin.__table__.update().where(
            UserLogin.__table__.c.member_id == to_group.id
        ).values(member_id=admin_user.id),

        # DELETE the matching user record that pairs with the member record
        User.__table__.delete().where(User.__table__.c.id == to_group.id),

        # INSERT matching group record to pair group name
        Group.__table__.insert().values(id=to_group.id,
                                        join_mode='invite',
                                        member_visibility='private',
                                        default_content_visibility='public',
                                        default_role='admin',
                                        num_members=1),

        # INSERT admin_user as as admin of the group
        GroupMembership.__table__.insert().values(group_id=to_group.id,
                                                  member_id=admin_user.id,
                                                  role='admin',
                                                  status='active'),
    ]

    for sql_cmd in sql_cmds:
        Session.execute(sql_cmd)
    Session.commit()