Exemplo n.º 1
0
def prepare_folder_menu(folders, user):
    """
        Given list of folders, prepare folder menu showing all those folders
        at once. Ignores from input all folder inaccessible for the given user.

        Returns dict with following keys:
            folder_children - dictionary {folder.id: list of children instances}
            folder_tree - HTML of folder tree
    """
    # Note: This method calls Folder.many_get_user_stats, which makes it
    # sometimes very slow. Actually, the method is relatively fast. Still, more
    # optimizations are welcome here, because this method is called on almost
    # every request...

    data = get_visible_folder_tree(folders, user)

    if not data:
        return {'folder_children': {}, 'folder_tree': u''}

    ancestor_ids = data['ancestor_ids']
    folder_children = data['folder_children']
    sorted_folders = data['sorted_folders']

    # Get user's solution statuses.
    user_stats = Folder.many_get_user_stats(sorted_folders, user)

    # Finally, generate menu HTML
    menu = [x._html_menu_item(x.id in ancestor_ids, x._depth,
        user_stats.get(x.id)) for x in sorted_folders]

    return {
        'folder_children': folder_children,
        'folder_tree': u''.join(menu),
#        'sorted_folders': sorted_folders, # Not used currently. Enable if needed.
    }
Exemplo n.º 2
0
def folder_inline_year_shortcuts(context, folder_descriptors, split=1000):
    """
        Output links to folders and their (year-like) children in format:
            Parent folder with a long name          (main folder)
            '05 '06 '07 ... '12                     (year folders/children)

        folder_descriptors is a list of descriptions, one for each folder, where
        a description is a human readable info that uniquely describes the
        folder.
        When `split` parameter is given, result will be divided into
        `split`-sized results

        Currently, description is a string of comma-separated tags.
        For example: 'IMO' represent the main folder containing all IMO tasks.

        Optionally, the string can contain + sign, which is replaced with
        user's selected tag (from school class).
    """
    user = context.get('user')

    school_class = user and user.is_authenticated() \
        and user.get_profile().school_class

    chosen_tag = school_class and   \
        next((x[2] for x in settings.USERPROFILE_SCHOOL_CLASS_INFO \
            if x[0] == school_class), None)

    # Replace + with chosen tag (appropriate school class)
    if chosen_tag:
        folder_descriptors = [x.replace('+', chosen_tag) for x in folder_descriptors]

    # Find all main folders
    main_folders = _descriptors_to_folders(folder_descriptors)
    ids = [x.id for x in main_folders]

    # Find all year folders
    year_children = defaultdict(list)
    children = Folder.objects.filter(parent_id__in=ids)
    for x in children:
        # If a year-like folder
        if x.short_name.isdigit():
            year_children[x.parent_id].append(x)

    all_folders = main_folders[:]

    # Pick only last X years for each of the main folders
    for key, value in year_children.iteritems():
        _sorted = sorted(value, key=lambda x: x.name, reverse=True)
        _sorted = _sorted[:settings.FOLDER_INLINE_YEAR_COUNT][::-1]
        year_children[key] = _sorted
        all_folders.extend(_sorted)

    # Get user's statistics for all of these folder. That's the whole
    # purpose of this inline year shortcuts.
    user_stats = Folder.many_get_user_stats(all_folders, user)
    for x in all_folders:
        # Keep only last two digits
        x.t_short_year_name = "'" + x.short_name[-2:]

        stats = user_stats.get(x.id)
        solvable_task_count = stats and stats[1]

        any, any_non_rated, percent, RGB =  \
            Folder.parse_solution_stats(stats and stats[2], solvable_task_count)

        # Main folder
        if any and x.id in year_children:
            plus_sign = '+' if any_non_rated else ''
            x.t_percent_str = mark_safe(
                '<span style="color:#%02X%02X%02X;">(%s%d%%)</span>'    \
                    % (RGB[0], RGB[1], RGB[2], plus_sign, 100 * percent))
        x.t_color = '#%02X%02X%02X' % RGB

    # Stick children to main folders:
    for x in main_folders:
        x.t_year_children = year_children[x.id]

    return {
        'main_folder_chunks': [main_folders[i:i + split]  \
            for i in range(0, len(main_folders), split)],
    }