@@ -0,0 +1,2232 @@
+# -*- coding: utf-8 -*-%0Aimport sys%0Aimport logging%0A%0Afrom website.app import init_app%0Afrom website.models import NodeLog, Node%0Afrom scripts import utils as script_utils%0Afrom modularodm import Q%0A%0Alogger = logging.getLogger(__name__)%0A%0A%0Adef get_all_parents(node):%0A    # return a list contains all possible forked_from and registered_from of the node to the very origin%0A    parent_list = %5B%5D%0A    while True:%0A        if get_parent(node) is None:%0A            return parent_list%0A        if get_parent(node):%0A            parent_list.append(get_parent(node))%0A        node = get_parent(node)%0A%0A%0Adef get_parent(node):%0A    # detemine the latest action of the node that generate this node and return its parent%0A    if node.forked_from and node.registered_from:%0A        if node.forked_date %3E node.registered_date:%0A            return node.forked_from%0A        else:%0A            return node.registered_from%0A    elif node.forked_from and not node.registered_from:%0A        return node.forked_from%0A    elif node.registered_from and not node.forked_from:%0A        return node.registered_from%0A    else:%0A        return None%0A%0A%0Adef do_migration(records, dry=False):%0A    for node in records:%0A        logs = list(NodeLog.find(Q('was_connected_to', 'contains', node)))%0A%0A        for log in logs:%0A            log_node = log.node__logged%5B0%5D%0A            # if the log_node is not contained in the node parent list then it doesn't belong to this node%0A            if log_node not in get_all_parents(node):%0A                logger.info('Removing log %7B%7D from list because it is not associated with node %7B%7D'.format(log, node))%0A                logs.remove(log)%0A%0A        node.logs = logs%0A        logger.info('Adding %7B%7D logs to %7B%7D'.format(len(logs), node))%0A        if not dry:%0A            node.save()%0A%0A%0Adef get_targets():%0A    return Node.find(%0A        (%0A            (Q('registered_from', 'ne', None) & Q('logs', 'eq', %5B%5D))%0A            %7C Q('forked_from', 'ne', None)%0A        )%0A        & Q('is_deleted', 'ne', True)%0A    )%0A%0A%0Adef main():%0A    init_app(routes=False)  # Sets the storage backends on all models%0A    dry = 'dry' in sys.argv%0A    if not dry:%0A        script_utils.add_file_logger(logger, __file__)%0A    do_migration(get_targets(), dry)%0A%0A%0Aif __name__ == '__main__':%0A    main()

fix the 0 logs fork and registration