def mutate(root, args, context, info): RESOURCES_CENTER_HEADER_IMAGE = models.AttachmentPurpose.RESOURCES_CENTER_HEADER_IMAGE.value cls = models.Discussion 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 = discussion.user_can( user_id, CrudPermissions.UPDATE, permissions) if not allowed: raise HTTPUnauthorized() with cls.default_db.no_autoflush: db = discussion.db title_entries = args.get('title_entries') if title_entries is not None and len(title_entries) == 0: raise Exception( 'Resources center title entries 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( discussion, 'resources_center_title', title_entries) # add uploaded image as an attachment to the discussion image = args.get('header_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) # if there is already an IMAGE, remove it with the # associated document header_images = [ att for att in discussion.attachments if att.attachmentPurpose == RESOURCES_CENTER_HEADER_IMAGE ] if header_images: header_image = header_images[0] header_image.document.delete_file() db.delete(header_image.document) discussion.attachments.remove(header_image) db.add(models.DiscussionAttachment( document=document, discussion=discussion, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=RESOURCES_CENTER_HEADER_IMAGE )) db.flush() resources_center = ResourcesCenter() return UpdateResourcesCenter(resources_center=resources_center)
def mutate(root, args, context, info): EMBED_ATTACHMENT = models.AttachmentPurpose.EMBED_ATTACHMENT.value discussion_id = context.matchdict['discussion_id'] discussion = models.Discussion.get(discussion_id) post_id = args.get('post_id') post_id = int(Node.from_global_id(post_id)[1]) post = models.Post.get(post_id) cls = models.PostAttachment require_cls_permission(CrudPermissions.CREATE, cls, context) # add uploaded file as an attachment to the post attachment = args.get('file') if attachment is not None: filename = os.path.basename(context.POST[attachment].filename) mime_type = context.POST[attachment].type document = models.File( discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[attachment].file) attachment = models.PostAttachment( document=document, discussion=discussion, creator_id=context.authenticated_userid, post=post, title=filename, attachmentPurpose=EMBED_ATTACHMENT ) post.db.add(attachment) post.db.flush() return AddPostAttachment(post=post)
def create_document(value, context, discussion): filename = os.path.basename(context.POST[value].filename) mime_type = context.POST[value].type document = models.File(discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[value].file) return document
def create_attachment(discussion, attachment_model, new_value, attachment_purpose, context): filename = os.path.basename(context.POST[new_value].filename) mime_type = context.POST[new_value].type document = models.File(discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[new_value].file) new_attachment = attachment_model(document=document, discussion=discussion, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=attachment_purpose) return new_attachment
def mutate(root, args, context, info): discussion_id = context.matchdict['discussion_id'] discussion = models.Discussion.get(discussion_id) cls = models.Document require_cls_permission(CrudPermissions.CREATE, cls, context) allowed_filetypes = aslist( get_config()['attachment_allowed_mime_types']) def is_matched_type(s): for mime in allowed_filetypes: if re.match(mime, s): return True return False uploaded_file = args.get('file') if uploaded_file is not None: # Because the server is on GNU/Linux, os.path.basename will only work # with path using "/". Using ntpath works for both Linux and Windows path filename = ntpath.basename(context.POST[uploaded_file].filename) content = context.POST[uploaded_file].file.read() context.POST[uploaded_file].file.seek(0) filetype = magic.from_buffer(content, mime=True) if not is_matched_type(filetype): error = _('Sorry, this file type is not allowed.') log.warn( "A MIME-TYPE of %s was uploaded. It was not found in allowed_filetypes." % filetype) raise HTTPUnauthorized(context.localizer.translate(error)) mime_type = context.POST[uploaded_file].type document = models.File(discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[uploaded_file].file) discussion.db.add(document) document.db.flush() return UploadDocument(document=document)
def mutate(root, args, context, info): discussion_id = context.matchdict['discussion_id'] discussion = models.Discussion.get(discussion_id) cls = models.Document require_cls_permission(CrudPermissions.CREATE, cls, context) uploaded_file = args.get('file') if uploaded_file is not None: filename = os.path.basename(context.POST[uploaded_file].filename) mime_type = context.POST[uploaded_file].type document = models.File(discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[uploaded_file].file) discussion.db.add(document) document.db.flush() return UploadDocument(document=document)
def update_attachment(discussion, attachment_model, new_value, attachments, attachment_purpose, db, context): """Update or delete attachment.""" current_attachment = None if attachments: purposes_attachments = [ att for att in attachments if att.attachmentPurpose == attachment_purpose ] if purposes_attachments: current_attachment = purposes_attachments[0] if new_value == 'TO_DELETE' and current_attachment: # delete the new_value current_attachment.document.delete_file() db.delete(current_attachment.document) db.delete(current_attachment) attachments.remove(current_attachment) elif new_value == 'TO_DELETE': # When the entity is set to be deleted, but does not exist, do nothing (but avoid crashing the transaction) return else: filename = os.path.basename(context.POST[new_value].filename) mime_type = context.POST[new_value].type document = models.File(discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[new_value].file) # if there is already an attachment, remove it with the # associated document (image) if current_attachment: current_attachment.document.delete_file() db.delete(current_attachment.document) attachments.remove(current_attachment) attachment = attachment_model(document=document, discussion=discussion, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=attachment_purpose) attachments.append(attachment)
def mutate(root, args, context, info): discussion_id = context.matchdict['discussion_id'] discussion = models.Discussion.get(discussion_id) user_id = context.authenticated_userid or Everyone cls = models.Document 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() uploaded_file = args.get('file') if uploaded_file is not None: filename = os.path.basename(context.POST[uploaded_file].filename) mime_type = context.POST[uploaded_file].type document = models.File(discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[uploaded_file].file) discussion.db.add(document) document.db.flush() return UploadDocument(document=document)
def mutate(root, args, context, info): discussion_phase_id = args.get('discussion_phase_id') discussion_phase = models.DiscussionPhase.get(discussion_phase_id) discussion_id = context.matchdict["discussion_id"] discussion = models.Discussion.get(discussion_id) if discussion_phase is None: raise Exception( "A vote session requires a discussion phase, check discussionPhaseId value" ) phase_identifier = "voteSession" if discussion_phase.identifier != phase_identifier: raise Exception( "A vote session can only be created or edited with a '{}' discussion phase, check discussionPhaseId value" .format(phase_identifier)) vote_session = discussion_phase.vote_session if vote_session is None: require_cls_permission(CrudPermissions.CREATE, models.VoteSession, context) vote_session = models.VoteSession( discussion=discussion, discussion_phase=discussion_phase) else: require_instance_permission(CrudPermissions.UPDATE, vote_session, context) if args.get('see_current_votes', None) is not None: vote_session.see_current_votes = args['see_current_votes'] db = vote_session.db update_langstrings(vote_session, langstrings_defs, args) image = args.get('header_image') if image is not None: filename = os.path.basename(context.POST[image].filename) mime_type = context.POST[image].type ATTACHMENT_PURPOSE_IMAGE = models.AttachmentPurpose.IMAGE.value document = models.File(discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[image].file) images = [ att for att in vote_session.attachments if att.attachmentPurpose == ATTACHMENT_PURPOSE_IMAGE ] if images: image = images[0] image.document.delete_file() db.delete(image.document) vote_session.attachments.remove(image) db.add( models.VoteSessionAttachment( document=document, vote_session=vote_session, discussion=discussion, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=ATTACHMENT_PURPOSE_IMAGE)) db.add(vote_session) # create the root thematic on which we will attach all proposals for this vote session root_thematic = get_root_thematic_for_phase(discussion_phase) if root_thematic is None: root_thematic = create_root_thematic(discussion_phase) db.flush() return UpdateVoteSession(vote_session=vote_session)
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)
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)
def mutate(root, args, context, info): EMBED_ATTACHMENT = models.AttachmentPurpose.EMBED_ATTACHMENT.value cls = models.Idea 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: title_entries = args.get('title_entries') if len(title_entries) == 0: raise Exception('Idea 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 parent_idea_id = args.get('parent_id') if parent_idea_id: parent_idea_id = int(Node.from_global_id(parent_idea_id)[1]) if parent_idea_id: 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: raise Exception('Parent Idea not found') if not parent_idea_id: parent_idea = discussion.root_idea saobj = cls(discussion_id=discussion_id, title=title_langstring, **kwargs) db = saobj.db 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))) # 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() return CreateIdea(idea=saobj)
def mutate(root, args, context, info): PROFILE_PICTURE = models.AttachmentPurpose.PROFILE_PICTURE.value cls = models.User discussion_id = context.matchdict['discussion_id'] discussion = models.Discussion.get(discussion_id) user_id = context.authenticated_userid or Everyone global_id = args.get('id') id_ = int(Node.from_global_id(global_id)[1]) user = cls.get(id_) permissions = get_permissions(user_id, discussion_id) allowed = user.user_can( user_id, CrudPermissions.UPDATE, permissions) if not allowed: raise HTTPUnauthorized("You don't have the authorization to update this user. If you think it's an error, please reconnect to assembl.") with cls.default_db.no_autoflush as db: username = args.get('username') # only modify the username if it was given in parameter if username is not None: if username != user.username_p: if db.query(models.Username).filter_by( username=username ).count(): raise Exception(u"001: We already have a user with this username.") user.username_p = username name = args.get('name') # only modify the name if it was given in parameter if name is not None: user.real_name_p = name old_password = args.get('old_password') new_password = args.get('new_password') new_password2 = args.get('new_password2') # only modify the password if it was given in parameter if old_password is not None and new_password is not None and new_password2 is not None: if not user.check_password(old_password): raise Exception(u"002: The entered password doesn't match your current password.") if new_password != new_password2: raise Exception(u"003: You entered two different passwords.") if old_password == new_password: raise Exception(u"004: The new password has to be different than the current password.") try: user.password_p = new_password except LocalizableError as e: raise JSONError(e.localized_message(context.localizer)) except Exception as e: raise JSONError(str(e), code=409) # add uploaded image as an attachment to the user 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) # if there is already an PROFILE_PICTURE, remove it with the # associated document images = [ att for att in user.profile_attachments if att.attachmentPurpose == PROFILE_PICTURE] if images: image = images[0] allowed = image.user_can( user_id, CrudPermissions.DELETE, permissions) if not allowed: raise HTTPUnauthorized("The authenticated user can't delete the existing AgentProfileAttachment") image.document.delete_file() db.delete(image.document) user.profile_attachments.remove(image) allowed = models.AgentProfileAttachment.user_can_cls( user_id, CrudPermissions.CREATE, permissions) if not allowed: raise HTTPUnauthorized("The authenticated user can't create an AgentProfileAttachment") discussion.db.add(models.AgentProfileAttachment( document=document, discussion=discussion, user=user, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=PROFILE_PICTURE )) db.flush() return UpdateUser(user=user)
def mutate(root, args, context, info): ATTACHMENT_PURPOSE_IMAGE = models.AttachmentPurpose.IMAGE.value ATTACHMENT_PURPOSE_DOCUMENT = models.AttachmentPurpose.DOCUMENT.value cls = models.Resource 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: title_entries = args.get('title_entries') if len(title_entries) == 0: raise Exception( 'Resource 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) text_langstring = langstring_from_input_entries( args.get('text_entries')) kwargs = {} if text_langstring is not None: kwargs['text'] = text_langstring kwargs['embed_code'] = args.get('embed_code') saobj = cls( discussion_id=discussion_id, title=title_langstring, **kwargs) db = saobj.db db.add(saobj) 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.ResourceAttachment( document=document, resource=saobj, discussion=discussion, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=ATTACHMENT_PURPOSE_IMAGE )) doc = args.get('doc') if doc is not None: filename = os.path.basename(context.POST[doc].filename) mime_type = context.POST[doc].type document = models.File( discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[doc].file) db.add(models.ResourceAttachment( document=document, resource=saobj, discussion=discussion, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=ATTACHMENT_PURPOSE_DOCUMENT )) db.flush() return CreateResource(resource=saobj)
def mutate(root, args, context, info): ATTACHMENT_PURPOSE_IMAGE = models.AttachmentPurpose.IMAGE.value ATTACHMENT_PURPOSE_DOCUMENT = models.AttachmentPurpose.DOCUMENT.value cls = models.Resource discussion_id = context.matchdict['discussion_id'] discussion = models.Discussion.get(discussion_id) user_id = context.authenticated_userid or Everyone resource_id = args.get('id') resource_id = int(Node.from_global_id(resource_id)[1]) resource = cls.get(resource_id) permissions = get_permissions(user_id, discussion_id) allowed = resource.user_can( user_id, CrudPermissions.UPDATE, permissions) if not allowed: raise HTTPUnauthorized() with cls.default_db.no_autoflush: title_entries = args.get('title_entries') if title_entries is not None and len(title_entries) == 0: raise Exception( 'Resource 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( resource, 'title', title_entries) update_langstring_from_input_entries( resource, 'text', args.get('text_entries')) kwargs = {} kwargs['embed_code'] = args.get('embed_code', None) for attr, value in kwargs.items(): setattr(resource, attr, value) db = resource.db # add uploaded image as an attachment to the resource 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) # if there is already an IMAGE, remove it with the # associated document images = [ att for att in resource.attachments if att.attachmentPurpose == ATTACHMENT_PURPOSE_IMAGE] if images: image = images[0] image.document.delete_file() db.delete(image.document) resource.attachments.remove(image) db.add(models.ResourceAttachment( document=document, discussion=discussion, resource=resource, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=ATTACHMENT_PURPOSE_IMAGE )) # add uploaded doc as an attachment to the resource doc = args.get('doc') if doc is not None: filename = os.path.basename(context.POST[doc].filename) mime_type = context.POST[doc].type document = models.File( discussion=discussion, mime_type=mime_type, title=filename) document.add_file_data(context.POST[doc].file) # if there is already a DOCUMENT, remove it with the # associated document docs = [ att for att in resource.attachments if att.attachmentPurpose == ATTACHMENT_PURPOSE_DOCUMENT] if docs: doc = docs[0] doc.document.delete_file() db.delete(doc.document) resource.attachments.remove(doc) resource.db.add(models.ResourceAttachment( document=document, discussion=discussion, resource=resource, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=ATTACHMENT_PURPOSE_DOCUMENT )) db.flush() return UpdateResource(resource=resource)
def mutate(root, args, context, info): cls = models.Discussion discussion_id = context.matchdict['discussion_id'] discussion = cls.get(discussion_id) user_id = context.authenticated_userid or Everyone permissions = get_permissions(user_id, discussion_id) allowed = discussion.user_can( user_id, CrudPermissions.UPDATE, permissions) if not allowed: raise HTTPUnauthorized() with cls.default_db.no_autoflush as db: title_entries = args.get('title_entries') if title_entries is not None and len(title_entries) == 0: raise Exception( 'Title entries 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( discussion, 'title', title_entries) subtitle_entries = args.get('subtitle_entries') update_langstring_from_input_entries( discussion, 'subtitle', subtitle_entries) button_label_entries = args.get('button_label_entries') update_langstring_from_input_entries( discussion, 'button_label', button_label_entries) # add uploaded header image as an attachment to the discussion LANDING_PAGE_HEADER_IMAGE = models.AttachmentPurpose.LANDING_PAGE_HEADER_IMAGE.value image = args.get('header_image') if image is not None: header_images = [ att for att in discussion.attachments if att.attachmentPurpose == LANDING_PAGE_HEADER_IMAGE ] if image == 'TO_DELETE' and header_images: header_image = header_images[0] header_image.document.delete_file() db.delete(header_image.document) discussion.attachments.remove(header_image) 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 IMAGE, remove it with the # associated document if header_images: header_image = header_images[0] header_image.document.delete_file() db.delete(header_image.document) discussion.attachments.remove(header_image) db.add(models.DiscussionAttachment( document=document, discussion=discussion, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=LANDING_PAGE_HEADER_IMAGE )) # add uploaded logo image as an attachment to the discussion LANDING_PAGE_LOGO_IMAGE = models.AttachmentPurpose.LANDING_PAGE_LOGO_IMAGE.value image = args.get('logo_image') if image is not None: logo_images = [ att for att in discussion.attachments if att.attachmentPurpose == LANDING_PAGE_LOGO_IMAGE ] if image == 'TO_DELETE' and logo_images: logo_image = logo_images[0] logo_image.document.delete_file() db.delete(logo_image.document) discussion.attachments.remove(logo_image) 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 IMAGE, remove it with the # associated document if logo_images: logo_image = logo_images[0] logo_image.document.delete_file() db.delete(logo_image.document) discussion.attachments.remove(logo_image) db.add(models.DiscussionAttachment( document=document, discussion=discussion, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=LANDING_PAGE_LOGO_IMAGE )) db.flush() discussion = cls.get(discussion_id) return UpdateDiscussion(discussion=discussion)
def mutate(root, args, context, info): cls = models.DiscussionPhase phase_id = args.get('id') phase_id = int(Node.from_global_id(phase_id)[1]) phase = cls.get(phase_id) require_instance_permission(CrudPermissions.UPDATE, phase, context) with cls.default_db.no_autoflush as db: title_entries = args.get('title_entries') if len(title_entries) == 0: raise Exception( 'DiscussionPhase titleEntries needs at least one entry') update_langstring_from_input_entries(phase, 'title', title_entries) description_entries = args.get('description_entries') if description_entries is not None: update_langstring_from_input_entries(phase, 'description', description_entries) phase.identifier = args.get('identifier') phase.is_thematics_table = args.get('is_thematics_table') # SQLAlchemy wants naive datetimes phase.start = args.get('start').replace(tzinfo=None) phase.end = args.get('end').replace(tzinfo=None) phase.order = args.get('order') image = args.get('image') discussion_id = context.matchdict['discussion_id'] discussion = models.Discussion.get(discussion_id) if image is not None: if image == 'TO_DELETE' and phase.attachments: # delete the image attachment = phase.attachments[0] attachment.document.delete_file() db.delete(attachment.document) db.delete(attachment) phase.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 phase.attachments: for attachment in phase.attachments[:]: attachment.document.delete_file() db.delete(attachment.document) phase.attachments.remove(attachment) attachment = models.TimelineEventAttachment( document=document, discussion=discussion, creator_id=context.authenticated_userid, title=filename, attachmentPurpose=models.AttachmentPurpose.IMAGE.value) phase.attachments.append(attachment) db.flush() return UpdateDiscussionPhase(discussion_phase=phase)