def patch(self): """Update a message with payload. method follows the rfc5789 PATCH and rfc7396 Merge patch specifications, + 'current_state' caliopen's specs. stored messages are modified according to the fields within the payload, ie payload fields squash existing db fields, no other modification done. If message doesn't existing, response is 404. If payload fields are not conform to the message db schema, response is 422 (Unprocessable Entity). Successful response is 204, without a body. """ message_id = self.request.swagger_data["message_id"] patch = self.request.json message = ObjectMessage(self.user.user_id, message_id=message_id) try: message.patch_draft(patch, db=True, index=True, with_validation=True) except Exception as exc: raise MergePatchError(exc) return Response(None, 204)
def patch(self): """Update a message with payload. method follows the rfc5789 PATCH and rfc7396 Merge patch specifications, + 'current_state' caliopen's specs. stored messages are modified according to the fields within the payload, ie payload fields squash existing db fields, no other modification done. If message doesn't existing, response is 404. If payload fields are not conform to the message db schema, response is 422 (Unprocessable Entity). Successful response is 204, without a body. """ message_id = self.request.swagger_data["message_id"] patch = self.request.json if 'privacy_features' in patch: features = marshal_features(patch['privacy_features']) patch['privacy_features'] = features if 'privacy_features' in patch.get('current_state', {}): current = patch['current_state']['privacy_features'] features = marshal_features(current) patch['current_state']['privacy_features'] = features message = ObjectMessage(user=self.user, message_id=message_id) try: message.patch_draft(self.user, patch, db=True, index=True, with_validation=True) except Exception as exc: raise MergePatchError(exc) return Response(None, 204)
def _update_external_references(self, user): """ copy externals references from current draft's ancestor and change parent_id to reflect new message's hierarchy :return: """ from caliopen_main.message.objects.message import Message parent_msg = Message(user, message_id=self.parent_id) parent_msg.get_db() parent_msg.unmarshall_db() if parent_msg: self.external_references = ExternalReferences( vars(parent_msg.external_references)) self.external_references.ancestors_ids.append( parent_msg.external_references.message_id) self.external_references.parent_id = parent_msg.external_references.message_id self.external_references.message_id = "" # will be set by broker at sending time
def delete(self): message_id = self.request.swagger_data["message_id"] message = ObjectMessage(user=self.user, message_id=message_id) try: message.get_db() message.get_index() except NotFound: raise ResourceNotFound try: message.delete_db() message.delete_index() except Exception as exc: raise HTTPServerError(exc) return Response(None, 204)
def delete(self): message_id = self.request.swagger_data["message_id"] message = ObjectMessage(self.user.user_id, message_id=message_id) try: message.get_db() message.get_index() except NotFound: raise ResourceNotFound try: message.delete_db() message.delete_index() except Exception as exc: raise HTTPServerError(exc) return Response(None, 204)
def collection_post(self): data = self.request.json # ^ json payload should have been validated by swagger module try: message = ObjectMessage.create_draft(user=self.user, **data) except Exception as exc: log.warn(exc) raise MergePatchError(error=exc) message_url = self.request.route_path('message', message_id=str( message.message_id)) message_url = message_url.replace("/v1/", "/v2/") self.request.response.location = message_url.encode('utf-8') return {'location': message_url}
def collection_post(self): data = self.request.json if 'privacy_features' in data: features = marshal_features(data['privacy_features']) data['privacy_features'] = features # ^ json payload should have been validated by swagger module try: message = ObjectMessage.create_draft(user=self.user, **data) except Exception as exc: log.exception(exc) raise MergePatchError(error=exc) message_url = self.request.route_path('message', message_id=str( message.message_id)) message_url = message_url.replace("/v1/", "/v2/") self.request.response.location = message_url.encode('utf-8') return {'location': message_url}
def update_external_references(self, user): """ copy externals references from current draft's ancestor and change parent_id to reflect new message's hierarchy :return: """ from caliopen_main.message.objects.message import Message parent_msg = Message(user, message_id=self.parent_id) parent_msg.get_db() parent_msg.unmarshall_db() if parent_msg: self.external_references = ExternalReferences( vars(parent_msg.external_references)) self.external_references.ancestors_ids.append( parent_msg.external_references.message_id) self.external_references.parent_id = parent_msg.external_references.message_id self.external_references.message_id = "" # will be set by broker at sending time
from_participant = [x for x in message.participants if x['type'] == 'From'] if not from_participant: log.error('No from participant found for message {} : {}'. format(message.message_id, message.participants)) else: is_received = False if from_participant[0]['address'] in identities: log.info('Sent mail') cpt['sent'] += 1 else: log.info('Received mail') cpt['received'] += 1 is_received = True if not args.test: obj = ObjMessage(message.user_id, message_id=message.message_id) patch = {'current_state': {'is_received': None}, 'is_received': is_received} try: error = obj.apply_patch(patch, db=True, index=True) if error is not None: log.error('Unable to patch message {}: {}'. format(message.message_id, error)) except PatchConflict as exc: log.exception('Patch conflict for message {} :{}'. format(message.message_id, exc)) except NotFound as exc: log.exception('Message not found {}: {}'. format(message.message_id, exc)) except Exception as exc: log.exception('Unhandled exception {}'.format(exc))
def __init__(self, client=None, mappings_version=None): self.es_client = client self.types = (Contact(), Message()) self.mappings_version = mappings_version
def process_raw(self, raw_msg_id): """Process a raw message for an user, ie makes it a rich 'message'.""" raw = RawMessage.get(raw_msg_id) if not raw: log.error('Raw message <{}> not found'.format(raw_msg_id)) raise NotFound log.debug('Retrieved raw message {}'.format(raw_msg_id)) qualifier = UserMessageQualifier(self.user) message = qualifier.process_inbound(raw) # store and index message obj = Message(self.user) obj.unmarshall_dict(message.to_native()) obj.user_id = uuid.UUID(self.user.user_id) obj.message_id = uuid.uuid4() obj.date_insert = datetime.datetime.now(tz=pytz.utc) obj.marshall_db() obj.save_db() obj.marshall_index() obj.save_index() return obj
def __init__(self, es_client): self.es_client = es_client self.types = (Contact(), Message())
def process_raw(self, raw_msg_id): """Process a raw message for an user, ie makes it a rich 'message'.""" raw = RawMessage.get(raw_msg_id) if not raw: log.error('Raw message <{}> not found'.format(raw_msg_id)) raise NotFound log.debug('Retrieved raw message {}'.format(raw_msg_id)) message = self.qualifier.process_inbound(raw) external_refs = ModelMessageExternalRefLookup.filter( user_id=self.user.user_id, external_msg_id=message.external_msg_id) if external_refs: # message already imported, update it with identity_id if needed for external_ref in external_refs: obj = Message(user=self.user, message_id=external_ref.message_id) if str(external_ref.identity_id) != self.identity.identity_id: obj.get_db() obj.unmarshall_db() obj.user_identities.append(self.identity.identity_id) obj.marshall_db() obj.save_db() obj.marshall_index() obj.save_index() MessageExternalRefLookup.create( self.user, external_msg_id=external_ref.external_msg_id, identity_id=self.identity.identity_id, message_id=external_ref.message_id) raise Exception(DUPLICATE_MESSAGE_EXC) # store and index Message obj = Message(user=self.user) obj.unmarshall_dict(message.to_native()) obj.user_id = uuid.UUID(self.user.user_id) obj.user_identities = [uuid.UUID(self.identity.identity_id)] obj.message_id = uuid.uuid4() obj.date_insert = datetime.datetime.now(tz=pytz.utc) obj.date_sort = obj.date_insert obj.marshall_db() obj.save_db() obj.marshall_index() obj.save_index() # store external_msg_id in lookup table # but do not abort if it failed try: MessageExternalRefLookup.create( self.user, external_msg_id=obj.external_msg_id, identity_id=obj.user_identity, message_id=obj.message_id) except Exception as exc: log.exception("UserMessageDelivery failed " "to store message_external_ref : {}".format(exc)) return obj
def _check_discussion_consistency(self, user): from caliopen_main.message.objects.message import Message new_discussion = False if not hasattr(self, 'discussion_id') or self.discussion_id == "" \ or self.discussion_id is None: # no discussion_id provided. Try to find one with draft's parent_id # or create new discussion if hasattr(self, 'parent_id') \ and self.parent_id is not None \ and self.parent_id != "": parent_msg = Message(user, message_id=self.parent_id) try: parent_msg.get_db() parent_msg.unmarshall_db() except NotFound: raise err.PatchError(message="parent message not found") self.discussion_id = parent_msg.discussion_id else: discussion = Discussion.create_from_message(user, self) self.discussion_id = discussion.discussion_id new_discussion = True if not new_discussion: dim = DIM(user) d_id = self.discussion_id last_message = dim.get_last_message(d_id, -10, 10, True) if last_message == {}: raise err.PatchError( message='No such discussion {}'.format(d_id)) is_a_reply = (str(last_message.message_id) != str(self.message_id)) if is_a_reply: # check participants consistency if hasattr(self, "participants") and len(self.participants) > 0: participants = [p['address'] for p in self.participants] last_msg_participants = [ p['address'] for p in last_message.participants ] if len(participants) != len(last_msg_participants): raise err.PatchError( message="list of participants " "is not consistent for this discussion") participants.sort() last_msg_participants.sort() for i, participant in enumerate(participants): if participant != last_msg_participants[i]: raise err.PatchConflict( message="list of participants " "is not consistent for this discussion") else: self.build_participants_for_reply(user) # check parent_id consistency if 'parent_id' in self and self.parent_id != "" \ and self.parent_id is not None: if not dim.message_belongs_to( discussion_id=self.discussion_id, message_id=self.parent_id): raise err.PatchConflict(message="provided message " "parent_id does not belong " "to this discussion") else: self.parent_id = last_message.parent_id self.update_external_references(user) else: last_message = None else: last_message = None return last_message
] if not from_participant: log.error( 'No from participant found for message {} : {}'.format( message.message_id, message.participants)) else: is_received = False if from_participant[0]['address'] in identities: log.info('Sent mail') cpt['sent'] += 1 else: log.info('Received mail') cpt['received'] += 1 is_received = True if not args.test: obj = ObjMessage(message.user_id, message_id=message.message_id) patch = { 'current_state': { 'is_received': None }, 'is_received': is_received } try: error = obj.apply_patch(patch, db=True, index=True) if error is not None: log.error('Unable to patch message {}: {}'.format( message.message_id, error)) except PatchConflict as exc: log.exception( 'Patch conflict for message {} :{}'.format( message.message_id, exc))
def process_raw(self, raw_msg_id): """Process a raw message for an user, ie makes it a rich 'message'.""" raw = RawMessage.get(raw_msg_id) if not raw: log.error('Raw message <{}> not found'.format(raw_msg_id)) raise NotFound log.debug('Retrieved raw message {}'.format(raw_msg_id)) message = self.qualifier.process_inbound(raw) external_refs = ModelMessageExternalRefLookup.filter( user_id=self.user.user_id, external_msg_id=message.external_msg_id) if external_refs: # message already imported, update it with identity_id if needed for external_ref in external_refs: obj = Message(user=self.user, message_id=external_ref.message_id) if str(external_ref.identity_id) != self.identity.identity_id: obj.get_db() obj.unmarshall_db() obj.user_identities.append(self.identity.identity_id) obj.marshall_db() obj.save_db() obj.marshall_index() obj.save_index() MessageExternalRefLookup.create(self.user, external_msg_id=external_ref.external_msg_id, identity_id=self.identity.identity_id, message_id=external_ref.message_id) raise DuplicateObject(DUPLICATE_MESSAGE_EXC) # store and index Message obj = Message(user=self.user) obj.unmarshall_dict(message.to_native()) obj.user_id = uuid.UUID(self.user.user_id) obj.user_identities = [uuid.UUID(self.identity.identity_id)] obj.message_id = uuid.uuid4() obj.date_insert = datetime.datetime.now(tz=pytz.utc) obj.date_sort = obj.date_insert obj.marshall_db() obj.save_db() obj.marshall_index() obj.save_index() # store external_msg_id in lookup table # but do not abort if it failed try: MessageExternalRefLookup.create(self.user, external_msg_id=obj.external_msg_id, identity_id=obj.user_identity, message_id=obj.message_id) except Exception as exc: log.exception("UserMessageDelivery failed " "to store message_external_ref : {}".format(exc)) return obj