Exemplo n.º 1
0
    def mutate(root, args, context, info):
        EMBED_ATTACHMENT = models.AttachmentPurpose.EMBED_ATTACHMENT.value
        cls = models.Thematic
        discussion_id = context.matchdict['discussion_id']
        discussion = models.Discussion.get(discussion_id)
        user_id = context.authenticated_userid or Everyone

        thematic_id = args.get('id')
        id_ = int(Node.from_global_id(thematic_id)[1])
        thematic = cls.get(id_)

        permissions = get_permissions(user_id, discussion_id)
        allowed = thematic.user_can(user_id, CrudPermissions.UPDATE,
                                    permissions)
        if not allowed:
            raise HTTPUnauthorized()

        with cls.default_db.no_autoflush:
            # introducing history at every step, including thematics + questions  # noqa: E501
            thematic.copy(tombstone=True)
            title_entries = args.get('title_entries')
            if title_entries is not None and len(title_entries) == 0:
                raise Exception(
                    'Thematic titleEntries needs at least one entry')
                # Better to have this message than
                # 'NoneType' object has no attribute 'owner_object'
                # when creating the saobj below if title=None

            update_langstring_from_input_entries(thematic, 'title',
                                                 title_entries)
            update_langstring_from_input_entries(
                thematic, 'description', args.get('description_entries'))
            kwargs = {}
            video = args.get('video', None)
            if video is not None:
                update_langstring_from_input_entries(
                    thematic, 'video_title', video.get('title_entries', []))
                update_langstring_from_input_entries(
                    thematic, 'video_description_top',
                    video.get('description_entries_top', []))
                update_langstring_from_input_entries(
                    thematic, 'video_description_bottom',
                    video.get('description_entries_bottom', []))
                update_langstring_from_input_entries(
                    thematic, 'video_description_side',
                    video.get('description_entries_side', []))
                kwargs['video_html_code'] = video.get('html_code', None)

            if args.get('identifier') is not None:
                kwargs['identifier'] = args.get('identifier')

            for attr, value in kwargs.items():
                setattr(thematic, attr, value)

            db = thematic.db

            # change order if needed
            order = args.get('order')
            if order:
                thematic.source_links[0].order = order

            # add uploaded image as an attachment to the idea
            image = args.get('image')
            if image is not None:
                if image == 'TO_DELETE' and thematic.attachments:
                    # delete the image
                    attachment = thematic.attachments[0]
                    attachment.document.delete_file()
                    db.delete(attachment.document)
                    db.delete(attachment)
                    thematic.attachments.remove(attachment)
                else:
                    filename = os.path.basename(context.POST[image].filename)
                    mime_type = context.POST[image].type
                    document = models.File(discussion=discussion,
                                           mime_type=mime_type,
                                           title=filename)
                    document.add_file_data(context.POST[image].file)
                    # if there is already an attachment, remove it with the
                    # associated document (image)
                    if thematic.attachments:
                        thematic.attachments[0].document.delete_file()
                        db.delete(thematic.attachments[0].document)
                        thematic.attachments.remove(thematic.attachments[0])

                    attachment = models.IdeaAttachment(
                        document=document,
                        discussion=discussion,
                        creator_id=context.authenticated_userid,
                        title=filename,
                        attachmentPurpose=EMBED_ATTACHMENT)
                    thematic.attachments.append(attachment)
            db.flush()

            questions_input = args.get('questions')
            existing_questions = {
                question.id: question
                for question in thematic.get_children()
            }
            updated_questions = set()
            if questions_input is not None:
                for idx, question_input in enumerate(questions_input):
                    if question_input.get('id', None) is not None:
                        id_ = int(Node.from_global_id(question_input['id'])[1])
                        updated_questions.add(id_)
                        question = models.Question.get(id_)
                        # archive the question
                        question.copy(tombstone=True)
                        update_langstring_from_input_entries(
                            question, 'title', question_input['title_entries'])
                        # modify question order
                        question.source_links[0].order = idx + 1.0
                    else:
                        title_ls = langstring_from_input_entries(
                            question_input['title_entries'])
                        question = models.Question(title=title_ls,
                                                   discussion_id=discussion_id)
                        db.add(
                            models.IdeaLink(source=thematic,
                                            target=question,
                                            order=idx + 1.0))

                # remove question (tombstone) that are not in questions_input
                for question_id in set(existing_questions.keys()).difference(
                        updated_questions):
                    existing_questions[question_id].is_tombstone = True

            db.flush()

        return UpdateThematic(thematic=thematic)
Exemplo n.º 2
0
    def mutate(root, args, context, info):
        EMBED_ATTACHMENT = models.AttachmentPurpose.EMBED_ATTACHMENT.value
        cls = models.Thematic
        discussion_id = context.matchdict['discussion_id']
        discussion = models.Discussion.get(discussion_id)
        user_id = context.authenticated_userid or Everyone

        permissions = get_permissions(user_id, discussion_id)
        allowed = cls.user_can_cls(user_id, CrudPermissions.CREATE,
                                   permissions)
        if not allowed or (allowed == IF_OWNED and user_id == Everyone):
            raise HTTPUnauthorized()

        identifier = args.get('identifier')
        with cls.default_db.no_autoflush:
            title_entries = args.get('title_entries')
            if len(title_entries) == 0:
                raise Exception(
                    'Thematic titleEntries needs at least one entry')
                # Better to have this message than
                # 'NoneType' object has no attribute 'owner_object'
                # when creating the saobj below if title=None

            title_langstring = langstring_from_input_entries(title_entries)
            description_langstring = langstring_from_input_entries(
                args.get('description_entries'))
            kwargs = {}
            if description_langstring is not None:
                kwargs['description'] = description_langstring

            video = args.get('video')
            if video is not None:
                video_title = langstring_from_input_entries(
                    video.get('title_entries', None))
                if video_title is not None:
                    kwargs['video_title'] = video_title

                video_description_top = langstring_from_input_entries(
                    video.get('description_entries_top', None))
                if video_description_top is not None:
                    kwargs['video_description_top'] = video_description_top

                video_description_bottom = langstring_from_input_entries(
                    video.get('description_entries_bottom', None))
                if video_description_bottom is not None:
                    kwargs[
                        'video_description_bottom'] = video_description_bottom

                video_description_side = langstring_from_input_entries(
                    video.get('description_entries_side', None))
                if video_description_side is not None:
                    kwargs['video_description_side'] = video_description_side

                video_html_code = video.get('html_code', None)
                if video_html_code is not None:
                    kwargs['video_html_code'] = video_html_code

            # Our thematic, because it inherits from Idea, needs to be
            # associated to the root idea of the discussion.
            # We create a hidden root thematic, corresponding to the
            # `identifier` phase, child of the root idea,
            # and add our thematic as a child of this root thematic.
            root_thematic = get_root_thematic_for_phase(discussion, identifier)
            if root_thematic is None:
                root_thematic = create_root_thematic(discussion, identifier)

            saobj = cls(discussion_id=discussion_id,
                        title=title_langstring,
                        identifier=identifier,
                        **kwargs)
            db = saobj.db
            db.add(saobj)
            order = len(root_thematic.get_children()) + 1.0
            db.add(
                models.IdeaLink(source=root_thematic,
                                target=saobj,
                                order=args.get('order', order)))

            # add uploaded image as an attachment to the idea
            image = args.get('image')
            if image is not None:
                filename = os.path.basename(context.POST[image].filename)
                mime_type = context.POST[image].type
                document = models.File(discussion=discussion,
                                       mime_type=mime_type,
                                       title=filename)
                document.add_file_data(context.POST[image].file)
                db.add(
                    models.IdeaAttachment(
                        document=document,
                        idea=saobj,
                        discussion=discussion,
                        creator_id=context.authenticated_userid,
                        title=filename,
                        attachmentPurpose=EMBED_ATTACHMENT))

            db.flush()

            questions_input = args.get('questions')
            if questions_input is not None:
                for idx, question_input in enumerate(questions_input):
                    title_ls = langstring_from_input_entries(
                        question_input['title_entries'])
                    question = models.Question(title=title_ls,
                                               discussion_id=discussion_id)
                    db.add(
                        models.IdeaLink(source=saobj,
                                        target=question,
                                        order=idx + 1.0))
                db.flush()

        return CreateThematic(thematic=saobj)
Exemplo n.º 3
0
    def mutate(root, args, context, info):
        cls = models.Thematic
        discussion_id = context.matchdict['discussion_id']
        user_id = context.authenticated_userid or Everyone

        thematic_id = args.get('id')
        id_ = int(Node.from_global_id(thematic_id)[1])
        thematic = cls.get(id_)

        permissions = get_permissions(user_id, discussion_id)
        allowed = thematic.user_can(user_id, CrudPermissions.UPDATE,
                                    permissions)
        if not allowed or (allowed == IF_OWNED and user_id == Everyone):
            raise HTTPUnauthorized()

        with cls.default_db.no_autoflush:
            title_entries = args.get('title_entries')
            if len(title_entries) == 0:
                raise Exception(
                    'Thematic titleEntries needs at least one entry')
                # Better to have this message than
                # 'NoneType' object has no attribute 'owner_object'
                # when creating the saobj below if title=None

            update_langstring_from_input_entries(thematic, 'title',
                                                 title_entries)
            update_langstring_from_input_entries(
                thematic, 'description', args.get('description_entries'))
            kwargs = {}
            video = args.get('video')
            if video is not None:
                update_langstring_from_input_entries(thematic, 'video_title',
                                                     video['title_entries'])
                update_langstring_from_input_entries(
                    thematic, 'video_description',
                    video['description_entries'])
                kwargs['video_html_code'] = video['html_code']

            # take the first entry and set it for short_title
            kwargs['short_title'] = title_entries[0]['value']
            kwargs['identifier'] = args.get('identifier')
            for attr, value in kwargs.items():
                setattr(thematic, attr, value)
            db = thematic.db
            db.flush()

            questions_input = args.get('questions')
            existing_questions = {
                question.id: question
                for question in thematic.get_children()
            }
            updated_questions = set()
            if questions_input is not None:
                for question_input in questions_input:
                    if question_input.get('id', None) is not None:
                        id_ = int(Node.from_global_id(question_input['id'])[1])
                        updated_questions.add(id_)
                        question = models.Question.get(id_)
                        update_langstring_from_input_entries(
                            question, 'title', question_input['title_entries'])
                    else:
                        title_ls = langstring_from_input_entries(
                            question_input['title_entries'])
                        models.Question(title=title_ls,
                                        discussion_id=discussion_id)
                        thematic.children.append(
                            models.Question(title=title_ls,
                                            discussion_id=discussion_id))

            # remove question (tombstone it) that are not in questions_input
            for question_id in set(
                    existing_questions.keys()).difference(updated_questions):
                existing_questions[
                    question_id].tombstone_date = datetime.utcnow()

            db.flush()

        return UpdateThematic(thematic=thematic)
Exemplo n.º 4
0
    def mutate(root, args, context, info):
        cls = models.Thematic
        discussion_id = context.matchdict['discussion_id']
        discussion = models.Discussion.get(discussion_id)
        user_id = context.authenticated_userid or Everyone

        permissions = get_permissions(user_id, discussion_id)
        allowed = cls.user_can_cls(user_id, CrudPermissions.CREATE,
                                   permissions)
        if not allowed or (allowed == IF_OWNED and user_id == Everyone):
            raise HTTPUnauthorized()

        identifier = args.get('identifier')
        with cls.default_db.no_autoflush:
            title_entries = args.get('title_entries')
            if len(title_entries) == 0:
                raise Exception(
                    'Thematic titleEntries needs at least one entry')
                # Better to have this message than
                # 'NoneType' object has no attribute 'owner_object'
                # when creating the saobj below if title=None

            title_langstring = langstring_from_input_entries(title_entries)
            description_langstring = langstring_from_input_entries(
                args.get('description_entries'))
            kwargs = {}
            if description_langstring is not None:
                kwargs['description'] = description_langstring

            video = args.get('video')
            if video is not None:
                video_title = langstring_from_input_entries(
                    video['title_entries'])
                if video_title is not None:
                    kwargs['video_title'] = video_title

                video_description = langstring_from_input_entries(
                    video['description_entries'])
                if video_description is not None:
                    kwargs['video_description'] = video_description

                kwargs['video_html_code'] = video['html_code']

            # Our thematic, because it inherits from Idea, needs to be
            # associated to the root idea of the discussion.
            # We create a hidden root thematic, corresponding to the
            # `identifier` phase, child of the root idea,
            # and add our thematic as a child of this root thematic.
            root_thematic = [
                idea for idea in discussion.root_idea.get_children()
                if getattr(idea, 'identifier', '') == identifier
            ]
            if not root_thematic:
                short_title = u'Phase {}'.format(identifier)
                root_thematic = cls(discussion_id=discussion_id,
                                    short_title=short_title,
                                    title=langstring_from_input_entries([{
                                        'locale_code':
                                        'en',
                                        'value':
                                        short_title
                                    }]),
                                    identifier=identifier,
                                    hidden=True)
                discussion.root_idea.children.append(root_thematic)
            else:
                root_thematic = root_thematic[0]

            # take the first entry and set it for short_title
            short_title = title_entries[0]['value']
            saobj = cls(discussion_id=discussion_id,
                        title=title_langstring,
                        short_title=short_title,
                        identifier=identifier,
                        **kwargs)
            root_thematic.children.append(saobj)
            db = saobj.db
            db.add(saobj)
            db.flush()

            questions_input = args.get('questions')
            if questions_input is not None:
                for question_input in questions_input:
                    title_ls = langstring_from_input_entries(
                        question_input['title_entries'])
                    saobj.children.append(
                        models.Question(title=title_ls,
                                        discussion_id=discussion_id))
                db.flush()

        return CreateThematic(thematic=saobj)
Exemplo n.º 5
0
    def mutate(root, args, context, info):
        EMBED_ATTACHMENT = models.AttachmentPurpose.EMBED_ATTACHMENT.value
        MEDIA_ATTACHMENT = models.AttachmentPurpose.MEDIA_ATTACHMENT.value
        cls = models.Idea
        discussion_id = context.matchdict['discussion_id']
        discussion = models.Discussion.get(discussion_id)
        user_id = context.authenticated_userid or Everyone

        thematic_id = args.get('id')
        id_ = int(Node.from_global_id(thematic_id)[1])
        thematic = cls.get(id_)

        permissions = get_permissions(user_id, discussion_id)
        allowed = thematic.user_can(user_id, CrudPermissions.UPDATE,
                                    permissions)
        if not allowed:
            raise HTTPUnauthorized()

        with cls.default_db.no_autoflush as db:
            # introducing history at every step, including thematics + questions  # noqa: E501
            thematic.copy(tombstone=True)
            title_entries = args.get('title_entries')
            if title_entries is not None and len(title_entries) == 0:
                raise Exception(
                    'Thematic titleEntries needs at least one entry')
                # Better to have this message than
                # 'NoneType' object has no attribute 'owner_object'
                # when creating the saobj below if title=None

            update_langstring_from_input_entries(thematic, 'title',
                                                 title_entries)
            update_langstring_from_input_entries(
                thematic, 'description', args.get('description_entries'))
            kwargs = {}
            video = args.get('video', None)
            if video is not None:
                update_langstring_from_input_entries(
                    thematic, 'video_title', video.get('title_entries', []))
                update_langstring_from_input_entries(
                    thematic, 'video_description_top',
                    video.get('description_entries_top', []))
                update_langstring_from_input_entries(
                    thematic, 'video_description_bottom',
                    video.get('description_entries_bottom', []))
                update_langstring_from_input_entries(
                    thematic, 'video_description_side',
                    video.get('description_entries_side', []))
                kwargs['video_html_code'] = video.get('html_code', None)

                video_media = video.get('media_file', None)
                if video_media:
                    update_attachment(discussion, models.IdeaAttachment,
                                      video_media, thematic.attachments,
                                      MEDIA_ATTACHMENT, db, context)

            kwargs['message_view_override'] = args.get('message_view_override')

            for attr, value in kwargs.items():
                setattr(thematic, attr, value)

            # change order if needed
            order = args.get('order')
            if order:
                thematic.source_links[0].order = order

            # add uploaded image as an attachment to the idea
            image = args.get('image')
            if image is not None:
                update_attachment(discussion, models.IdeaAttachment, image,
                                  thematic.attachments, EMBED_ATTACHMENT, db,
                                  context)

            # Create the idea announcement object which corresponds to the instructions
            announcement = args.get('announcement')
            if announcement is not None:
                announcement_title_entries = announcement.get('title_entries')
                if len(announcement_title_entries) == 0:
                    raise Exception(
                        'Announcement titleEntries needs at least one entry')

                announcement_title_langstring = langstring_from_input_entries(
                    announcement_title_entries)
                announcement_body_langstring = langstring_from_input_entries(
                    announcement.get('body_entries', None))
                saobj2 = create_idea_announcement(
                    user_id, discussion, thematic,
                    announcement_title_langstring,
                    announcement_body_langstring)
                db.add(saobj2)

            questions_input = args.get('questions')
            existing_questions = {
                question.id: question
                for question in thematic.get_children()
            }
            updated_questions = set()
            if questions_input is not None:
                for idx, question_input in enumerate(questions_input):
                    if question_input.get('id', None) is not None:
                        id_ = int(Node.from_global_id(question_input['id'])[1])
                        updated_questions.add(id_)
                        question = models.Question.get(id_)
                        # archive the question
                        question.copy(tombstone=True)
                        update_langstring_from_input_entries(
                            question, 'title', question_input['title_entries'])
                        # modify question order
                        question.source_links[0].order = idx + 1.0
                    else:
                        title_ls = langstring_from_input_entries(
                            question_input['title_entries'])
                        question = models.Question(title=title_ls,
                                                   discussion_id=discussion_id)
                        db.add(
                            models.IdeaLink(source=thematic,
                                            target=question,
                                            order=idx + 1.0))

                # remove question (tombstone) that are not in questions_input
                for question_id in set(existing_questions.keys()).difference(
                        updated_questions):
                    existing_questions[question_id].is_tombstone = True

            db.flush()

        return UpdateThematic(thematic=thematic)
Exemplo n.º 6
0
    def mutate(root, args, context, info):
        EMBED_ATTACHMENT = models.AttachmentPurpose.EMBED_ATTACHMENT.value
        MEDIA_ATTACHMENT = models.AttachmentPurpose.MEDIA_ATTACHMENT.value
        cls = models.Idea
        phase_identifier = args.get('identifier')
        if phase_identifier == Phases.survey.value:
            cls = models.Thematic

        discussion_id = context.matchdict['discussion_id']
        discussion = models.Discussion.get(discussion_id)
        user_id = context.authenticated_userid or Everyone

        permissions = get_permissions(user_id, discussion_id)
        allowed = cls.user_can_cls(user_id, CrudPermissions.CREATE,
                                   permissions)
        if not allowed or (allowed == IF_OWNED and user_id == Everyone):
            raise HTTPUnauthorized()

        with cls.default_db.no_autoflush as db:
            title_entries = args.get('title_entries')
            if len(title_entries) == 0:
                raise Exception(
                    'Thematic titleEntries needs at least one entry')
                # Better to have this message than
                # 'NoneType' object has no attribute 'owner_object'
                # when creating the saobj below if title=None

            title_langstring = langstring_from_input_entries(title_entries)
            description_langstring = langstring_from_input_entries(
                args.get('description_entries'))
            kwargs = {}
            if description_langstring is not None:
                kwargs['description'] = description_langstring

            kwargs['message_view_override'] = args.get('message_view_override')

            video = args.get('video')
            video_media = None
            if video is not None:
                video_title = langstring_from_input_entries(
                    video.get('title_entries', None))
                if video_title is not None:
                    kwargs['video_title'] = video_title

                video_description_top = langstring_from_input_entries(
                    video.get('description_entries_top', None))
                if video_description_top is not None:
                    kwargs['video_description_top'] = video_description_top

                video_description_bottom = langstring_from_input_entries(
                    video.get('description_entries_bottom', None))
                if video_description_bottom is not None:
                    kwargs[
                        'video_description_bottom'] = video_description_bottom

                video_description_side = langstring_from_input_entries(
                    video.get('description_entries_side', None))
                if video_description_side is not None:
                    kwargs['video_description_side'] = video_description_side

                video_html_code = video.get('html_code', None)
                if video_html_code is not None:
                    kwargs['video_html_code'] = video_html_code

                video_media = video.get('media_file', None)

            parent_idea_id = args.get('parent_id')
            if parent_idea_id:
                parent_idea_id = int(Node.from_global_id(parent_idea_id)[1])
                parent_idea = models.Idea.get(parent_idea_id)
                if not parent_idea:
                    raise Exception('Parent Idea not found')
                if parent_idea.discussion != discussion:
                    # No cross-debate references are allowed,
                    # for security reasons
                    raise Exception(
                        'Parent Idea does not belong to this discussion'
                    )  # noqa: E501
            else:
                if phase_identifier in (Phases.thread.value,
                                        Phases.multiColumns.value):
                    parent_idea = discussion.root_idea
                else:
                    # Our thematic, because it inherits from Idea, needs to be
                    # associated to the root idea of the discussion.
                    # We create a hidden root thematic, corresponding to the
                    # `identifier` phase, child of the root idea,
                    # and add our thematic as a child of this root thematic.
                    parent_idea = get_root_thematic_for_phase(
                        discussion, phase_identifier)
                    if parent_idea is None:
                        parent_idea = create_root_thematic(
                            discussion, phase_identifier)

            saobj = cls(discussion_id=discussion_id,
                        title=title_langstring,
                        **kwargs)
            if cls == models.Thematic:
                saobj.identifier = phase_identifier  # I don't think this is really used

            db.add(saobj)
            order = len(parent_idea.get_children()) + 1.0
            db.add(
                models.IdeaLink(source=parent_idea,
                                target=saobj,
                                order=args.get('order', order)))

            # Create the idea announcement object which corresponds to the instructions
            announcement = args.get('announcement')
            if announcement is not None:
                announcement_title_entries = announcement.get('title_entries')
                if len(announcement_title_entries) == 0:
                    raise Exception(
                        'Announcement titleEntries needs at least one entry')

                announcement_title_langstring = langstring_from_input_entries(
                    announcement_title_entries)
                announcement_body_langstring = langstring_from_input_entries(
                    announcement.get('body_entries', None))
                saobj2 = create_idea_announcement(
                    user_id, discussion, saobj, announcement_title_langstring,
                    announcement_body_langstring)
                db.add(saobj2)

            # add uploaded image as an attachment to the idea
            image = args.get('image')
            if image is not None:
                new_attachment = create_attachment(discussion,
                                                   models.IdeaAttachment,
                                                   image, EMBED_ATTACHMENT,
                                                   context)
                new_attachment.idea = saobj
                db.add(new_attachment)

            # add uploaded image as an attachment to the idea
            if video_media is not None:
                new_attachment = create_attachment(discussion,
                                                   models.IdeaAttachment,
                                                   video_media,
                                                   MEDIA_ATTACHMENT, context)
                new_attachment.idea = saobj
                db.add(new_attachment)

            questions_input = args.get('questions')
            if questions_input is not None:
                for idx, question_input in enumerate(questions_input):
                    title_ls = langstring_from_input_entries(
                        question_input['title_entries'])
                    question = models.Question(title=title_ls,
                                               discussion_id=discussion_id)
                    db.add(
                        models.IdeaLink(source=saobj,
                                        target=question,
                                        order=idx + 1.0))

        db.flush()
        return CreateThematic(thematic=saobj)