Esempio n. 1
0
def _create_or_update_task(
        ctask, user, competition, chain, index, text, comment):
    edit = bool(ctask.task_id)
    if not edit:
        content = MathContent(text=text)
        content.save()
        task = Task(content=content, author=user, hidden=True)
        comment = MathContent(text=comment)
        comment.save()
        ctask.comment = comment
    else:
        task = ctask.task
        task.content.text = text
        task.content.save()
        ctask.comment.text = comment
        ctask.comment.save()

    update_ctask_task(task, competition, chain, index + 1, commit=True)

    if not edit:
        if competition.automatic_task_tags:
            add_tags(task, competition.automatic_task_tags)
        if competition.admin_group:
            ObjectPermission.objects.create(content_object=task,
                    group=competition.admin_group, permission_type=VIEW)
            ObjectPermission.objects.create(content_object=task,
                    group=competition.admin_group, permission_type=EDIT)
        ctask.task = task
Esempio n. 2
0
def create_tasks_from_json(description):
    """
    Given a list of Task description dictionaries, create Task instances,
    together with other related objects.

    Supported special data:
        _content (string) - the text of the task, MathContent text
        _folder_id (int) - ID of the folder where to add the task
        _folder_position (int) - position in that folder
        _tags (string) - a comma-separated list of tags
        _difficulty (int) - difficulty rating to be assigned by the author
        _permissions (dict {"permission type ID": [list of group IDs]})
                - group permission to automatically assign.
                - (ID is a string because in JSON keys must be strings)

    All other elements with an underscore are ignored.

    Params:
        description (list): list of dict object, describing the tasks

    Returns:
        A list of the new Task objects.

    If an exception is thrown in the middle of the process, the exception is
    caputed, the message changed, and raised again.
    """
    # Approx.
    task_fields = set(Task._meta.get_all_field_names())
    task_fields |= set(x + '_id' for x in task_fields)

    created_objects = []
    created_tasks = []
    message_list = []

    # List of objects to create
    folder_tasks = []
    object_permissions = []

    try:
        for k, desc in enumerate(description):
            message_list.append('Creating {}. task...'.format(k + 1))

            # First, prepare data to be able to create Task.
            # --- math content ---
            math_content = MathContent()
            math_content.text = desc['_content']
            message_list.append(desc['_content'])
            math_content.save()
            created_objects.append(math_content)

            # Second, create Task.
            task = Task()
            task.content = math_content
            for key, value in desc.iteritems():
                if key[0] != '_' and key in task_fields:
                    setattr(task, key, value)
            task.save()
            created_objects.append(task)
            created_tasks.append(task)

            # Third, save other data.

            # --- tags ---
            tags = desc.get('_tags', '')
            set_tags(task, tags)

            # --- difficulty ---
            difficulty = desc.get('_difficulty')
            if difficulty:
                task.difficulty_rating.update(task.author, int(difficulty))

            # --- folder ids ---
            folder_id = desc.get('_folder_id')
            if folder_id is not None:
                folder_tasks.append(FolderTask(
                        folder_id=folder_id, task=task,
                        position=desc.get('_folder_position', 0)))

            # --- group permissions ---
            for perm, group_ids in desc.get('_permissions', {}).iteritems():
                for group_id in group_ids:
                    object_permissions.append(ObjectPermission(
                            content_object=task, group_id=group_id,
                            permission_type=perm))


        FolderTask.objects.bulk_create(folder_tasks)
        ObjectPermission.objects.bulk_create(object_permissions)
    except Exception as e:
        # This should remove all dependend objects.
        for obj in created_objects:
            obj.delete()

        message_list.append("Reverting changes...")
        message = "\n".join(message_list) + "\n\n" + traceback.format_exc()
        raise type(e)(message)
    finally:
        # SPEED: Don't invalidate everything.
        invalidate_cache_for_folders(Folder.objects.all())
    return created_tasks