def send(self): lookup = DNSLookup() settings = SIPSimpleSettings() account = DefaultAccount() if account.sip.outbound_proxy is not None: uri = SIPURI( host=account.sip.outbound_proxy.host, port=account.sip.outbound_proxy.port, parameters={'transport': account.sip.outbound_proxy.transport}) else: uri = self.to_uri try: routes = lookup.lookup_sip_proxy( uri, settings.sip.transport_list).wait() except DNSLookupError: msg = 'DNS lookup error while looking for %s proxy' % uri log.warning(msg) raise SIPMessageError(0, msg) else: route = routes.pop(0) from_header = FromHeader(self.from_uri) to_header = ToHeader(self.to_uri) route_header = RouteHeader(route.uri) notification_center = NotificationCenter() for chunk in chunks(self.body, 1000): if self.use_cpim: additional_headers = [] payload = CPIMPayload( self.body.encode('utf-8'), self.content_type, charset='utf-8', sender=ChatIdentity(self.from_uri, None), recipients=[ChatIdentity(self.to_uri, None)], additional_headers=additional_headers) payload, content_type = payload.encode() else: content_type = self.content_type payload = self.body.encode('utf-8') request = SIPMessageRequest(from_header, to_header, route_header, content_type, payload) notification_center.add_observer(self, sender=request) self._requests.add(request) request.send() error = None count = len(self._requests) while count > 0: notification = self._channel.wait() if notification.name == 'SIPMessageDidFail': error = (notification.data.code, notification.data.reason) count -= 1 self._requests.clear() if error is not None: raise SIPMessageError(*error)
def textView_doCommandBySelector_(self, textView, selector): if selector == "insertNewline:" and self.chatViewController.inputText == textView: content = str(textView.string()) textView.setString_("") textView.didChangeText() if content: self.sendMessage(content) self.chatViewController.resetTyping() recipient = ChatIdentity(self.target_uri, self.display_name) self.notification_center.post_notification( 'ChatViewControllerDidDisplayMessage', sender=self, data=NotificationData( direction='outgoing', history_entry=False, remote_party=format_identity_to_string(recipient), local_party=format_identity_to_string(self.account) if self.account is not BonjourAccount() else 'bonjour.local', check_contact=True)) return True return False
def _NH_XMPPIncomingMucSessionGotMessage(self, notification): if not self._sip_session: return message = notification.data.message sender_uri = message.sender.uri.as_sip_uri() del sender_uri.parameters['gr'] # no GRUU in CPIM From header sender = ChatIdentity(sender_uri, display_name=self.nickname) message_id = self._msrp_stream.send_message(message.body, 'text/plain', sender=sender) self._pending_messages_map[message_id] = message
def sendMessage(self, content, content_type="text/plain"): # entry point for sending messages, they will be added to self.message_queue if content_type != "application/im-iscomposing+xml": icon = NSApp.delegate().contactsWindowController.iconPathForSelf() if not isinstance(content, OTRInternalMessage): timestamp = ISOTimestamp.now() hash = hashlib.sha1() content = content.decode() if isinstance(content, bytes) else content hash.update((content + str(timestamp)).encode("utf-8")) id = hash.hexdigest() call_id = '' encryption = '' if self.encryption.active: encryption = 'verified' if self.encryption.verified else 'unverified' self.chatViewController.showMessage(call_id, id, 'outgoing', None, icon, content, timestamp, state="sent", media_type='sms', encryption=encryption) recipient = ChatIdentity(self.target_uri, self.display_name) mInfo = MessageInfo(id, sender=self.account, recipient=recipient, timestamp=timestamp, content_type=content_type, content=content, status="queued", encryption=encryption) self.messages[id] = mInfo self.message_queue.put(mInfo) else: self.message_queue.put(content) # Async DNS lookup if host is None or host.default_ip is None: self.setRoutesFailed( NSLocalizedString("No Internet connection", "Label")) return if self.last_route is None: self.lookup_destination(self.target_uri) else: self.setRoutesResolved([self.last_route])
def _send_queued_messages(self): sender = None while self._xmpp_message_queue: message = self._xmpp_message_queue.popleft() if message.body is None: continue sender_uri = message.sender.uri.as_sip_uri() sender_uri.parameters['gr'] = encode_resource(sender_uri.parameters['gr'].decode('utf-8')) sender = ChatIdentity(sender_uri) self.msrp_stream.send_message(message.body, 'text/plain', sender=sender, message_id=str(message.id), notify_progress=message.use_receipt) if sender: self.msrp_stream.send_composing_indication('idle', 30, sender=sender)
def _send(self): if self.session.routes: from_uri = self.account.uri content = self.content if isinstance( self.content, bytes) else self.content.encode() additional_sip_headers = [] if self.account.sms.use_cpim: ns = CPIMNamespace('urn:ietf:params:imdn', 'imdn') additional_headers = [CPIMHeader('Message-ID', ns, self.id)] if self.account.sms.enable_imdn and self.content_type not in self.__disabled_imdn_content_types__: additional_headers.append( CPIMHeader('Disposition-Notification', ns, 'positive-delivery, display')) payload = CPIMPayload( content, self.content_type, charset='utf-8', sender=ChatIdentity(from_uri, self.account.display_name), recipients=[ChatIdentity(self.sip_uri, None)], timestamp=str(self.timestamp), additional_headers=additional_headers) payload, content_type = payload.encode() else: payload = content content_type = self.content_type route = self.session.routes[0] message_request = Message(FromHeader(from_uri, self.account.display_name), ToHeader(self.sip_uri), RouteHeader(route.uri), content_type, payload, credentials=self.account.credentials, extra_headers=additional_sip_headers) notification_center = NotificationCenter() notification_center.add_observer(self, sender=message_request) message_request.send() else: pass
def composeReplicationMessage(self, sent_message, response_code): if sent_message.content_type == "application/im-iscomposing+xml": return if isinstance(self.account, Account): if not self.account.sms.disable_replication: contact = NSApp.delegate( ).contactsWindowController.getFirstContactMatchingURI( self.target_uri) msg = CPIMPayload( sent_message.content, sent_message.content_type, charset='utf-8', sender=ChatIdentity(self.account.uri, self.account.display_name), recipients=[ ChatIdentity(self.target_uri, contact.name if contact else None) ]) self.sendReplicationMessage(response_code, msg.encode()[0], content_type='message/cpim')
def _NH_XMPPChatSessionGotComposingIndication(self, notification): if self.sip_session is None or self.sip_session.state != 'connected': return if self._sip_session_timer is not None and self._sip_session_timer.active(): self._sip_session_timer.reset(SESSION_TIMEOUT) message = notification.data.message state = None if message.state == 'composing': state = 'active' elif message.state == 'paused': state = 'idle' if state is not None: sender_uri = message.sender.uri.as_sip_uri() del sender_uri.parameters['gr'] # no GRUU in CPIM From header sender = ChatIdentity(sender_uri) self.msrp_stream.send_composing_indication(state, 30, sender=sender) if message.use_receipt: self.xmpp_session.send_receipt_acknowledgement(message.id)
def _NH_XMPPChatSessionGotMessage(self, notification): if self.sip_session is None or self.sip_session.state != 'connected': self._xmpp_message_queue.append(notification.data.message) return if self._sip_session_timer is not None and self._sip_session_timer.active(): self._sip_session_timer.reset(SESSION_TIMEOUT) message = notification.data.message sender_uri = message.sender.uri.as_sip_uri() del sender_uri.parameters['gr'] # no GRUU in CPIM From header sender = ChatIdentity(sender_uri) self.use_receipts = message.use_receipt if not message.use_receipt: notify_progress = False else: notify_progress = True self._pending_xmpp_stanzas[message.id] = message # Prefer plaintext self.msrp_stream.send_message(message.body, 'text/plain', sender=sender, message_id=str(message.id), notify_progress=notify_progress) self.msrp_stream.send_composing_indication('idle', 30, sender=sender)
def __init__(self, username, uri, content, content_type='text/plain'): self.sender = ChatIdentity(uri, display_name=username) self.content = content self.content_type = content_type