<commit_before>import collections
from website import settings
from website.models import Node
from website.notifications.model import Subscription
from modularodm import Q
from modularodm.exceptions import NoResultsFound


class NotificationsDict(dict):
    def __init__(self):
        super(dict, self).__init__()
        self.update(messages=[], children=collections.defaultdict(NotificationsDict))

    def add_message(self, keys, messages):
        d_to_use = self
        for key in keys:
            d_to_use = d_to_use['children'][key]
        if not isinstance(messages, list):
            messages = [messages]
        d_to_use['messages'].extend(messages)
        return True


class SubscriptionsDict(dict):
    def __init__(self):
        super(dict, self).__init__()
        self.update(subscriptions=collections.defaultdict(SubscriptionsDict),
                    children=collections.defaultdict(SubscriptionsDict))

    def add_subscription(self, keys, subscription):
        d_to_use = self
        for key in keys:
            d_to_use = d_to_use['children'][key]
        for notification_type in settings.NOTIFICATION_TYPES:
            if getattr(subscription, notification_type):
                d_to_use['subscriptions'] = {subscription.event_name: []}
                d_to_use['subscriptions'][subscription.event_name].append(notification_type)
        return True


def get_configured_projects(user):
    configured_project_ids = []
    user_subscriptions = get_all_user_subscriptions(user)
    for subscription in user_subscriptions:
        try:
            node = Node.load(subscription.object_id)
        except NoResultsFound:
            # handle case where object_id for the subscription is NOT a project, but a user
            pass

        if node and node.project_or_component == 'project' and not node.is_deleted and subscription.object_id not in configured_project_ids:
                configured_project_ids.append(subscription.object_id)

    return configured_project_ids


def get_all_user_subscriptions(user):
    user_subscriptions = []
    for notification_type in settings.NOTIFICATION_TYPES:
        if getattr(user, notification_type, []):
            for subscription in getattr(user, notification_type, []):
                if subscription:
                    user_subscriptions.append(subscription)

    return user_subscriptions


def format_data(user, node_ids, subscriptions_available, data):
    subscriptions_available = subscriptions_available if subscriptions_available else settings.SUBSCRIPTIONS_AVAILABLE

    for idx, node_id in enumerate(node_ids):
        node = Node.load(node_id)
        index = len(data)
        data.append({'node_id': node_id,
                     'title': node.title,
                     'kind': 'folder' if node.nodes else 'node',
                     'nodeUrl': node.url,
                     'children': []
                    })
<commit_msg>Only top-level projects are kind == 'folder'<commit_after>import collections
from website import settings
from website.models import Node
from website.notifications.model import Subscription
from modularodm import Q
from modularodm.exceptions import NoResultsFound


class NotificationsDict(dict):
    def __init__(self):
        super(dict, self).__init__()
        self.update(messages=[], children=collections.defaultdict(NotificationsDict))

    def add_message(self, keys, messages):
        d_to_use = self
        for key in keys:
            d_to_use = d_to_use['children'][key]
        if not isinstance(messages, list):
            messages = [messages]
        d_to_use['messages'].extend(messages)
        return True


class SubscriptionsDict(dict):
    def __init__(self):
        super(dict, self).__init__()
        self.update(subscriptions=collections.defaultdict(SubscriptionsDict),
                    children=collections.defaultdict(SubscriptionsDict))

    def add_subscription(self, keys, subscription):
        d_to_use = self
        for key in keys:
            d_to_use = d_to_use['children'][key]
        for notification_type in settings.NOTIFICATION_TYPES:
            if getattr(subscription, notification_type):
                d_to_use['subscriptions'] = {subscription.event_name: []}
                d_to_use['subscriptions'][subscription.event_name].append(notification_type)
        return True


def get_configured_projects(user):
    configured_project_ids = []
    user_subscriptions = get_all_user_subscriptions(user)
    for subscription in user_subscriptions:
        try:
            node = Node.load(subscription.object_id)
        except NoResultsFound:
            # handle case where object_id for the subscription is NOT a project, but a user
            pass

        if node and node.project_or_component == 'project' and not node.is_deleted and subscription.object_id not in configured_project_ids:
                configured_project_ids.append(subscription.object_id)

    return configured_project_ids


def get_all_user_subscriptions(user):
    user_subscriptions = []
    for notification_type in settings.NOTIFICATION_TYPES:
        if getattr(user, notification_type, []):
            for subscription in getattr(user, notification_type, []):
                if subscription:
                    user_subscriptions.append(subscription)

    return user_subscriptions


def format_data(user, node_ids, subscriptions_available, data):
    subscriptions_available = subscriptions_available if subscriptions_available else settings.SUBSCRIPTIONS_AVAILABLE

    for idx, node_id in enumerate(node_ids):
        node = Node.load(node_id)
        index = len(data)
        data.append({'node_id': node_id,
                     'title': node.title,
                     'kind': 'folder' if not node.node__parent else 'node',
                     'nodeUrl': node.url,
                     'children': []
                    })

{'fraction_non_alphanumeric': 0.0793570219966159, 'fraction_numerical': 0.0, 'mean_word_length': 2.8358208955223883, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6589033', 'n_tokens_mistral': 1586, 'n_tokens_neox': 1563, 'n_words': 368}