def renderMessage(self, message): if message.direction == 'outgoing': icon = NSApp.delegate().contactsWindowController.iconPathForSelf() else: sender_uri = sipuri_components_from_string(message.cpim_from)[0] # TODO: How to render the icons from Address Book? Especially in sandbox mode we do not have access to other folders icon = NSApp.delegate().contactsWindowController.iconPathForURI( sender_uri) try: timestamp = Timestamp.parse(message.cpim_timestamp) except ValueError: pass else: is_html = False if message.content_type == 'text' else True private = True if message.private == "1" else False self.chatViewController.showMessage(message.msgid, message.direction, message.cpim_from, icon, message.body, timestamp, is_private=private, recipient=message.cpim_to, state=message.status, is_html=is_html, history_entry=True)
def render_history_messages(self, messages): for message in messages: if message.direction == 'outgoing': icon = NSApp.delegate().contactsWindowController.iconPathForSelf() else: sender_uri = sipuri_components_from_string(message.cpim_from)[0] icon = NSApp.delegate().contactsWindowController.iconPathForURI(sender_uri) timestamp=Timestamp.parse(message.cpim_timestamp) is_html = False if message.content_type == 'text' else True self.chatViewController.showMessage(message.msgid, message.direction, message.cpim_from, icon, message.body, timestamp, recipient=message.cpim_to, state=message.status, is_html=is_html, history_entry=True)
def renderMessage(self, message): if message.direction == 'outgoing': icon = NSApp.delegate().contactsWindowController.iconPathForSelf() else: sender_uri = sipuri_components_from_string(message.cpim_from)[0] # TODO: How to render the icons from Address Book? Especially in sandbox mode we do not have access to other folders icon = NSApp.delegate().contactsWindowController.iconPathForURI(sender_uri) try: timestamp=Timestamp.parse(message.cpim_timestamp) except ValueError: pass else: is_html = False if message.content_type == 'text' else True private = True if message.private == "1" else False self.chatViewController.showMessage(message.msgid, message.direction, message.cpim_from, icon, message.body, timestamp, is_private=private, recipient=message.cpim_to, state=message.status, is_html=is_html, history_entry=True)
def render_history_messages(self, messages): for message in messages: if message.direction == 'outgoing': icon = NSApp.delegate( ).contactsWindowController.iconPathForSelf() else: sender_uri = sipuri_components_from_string( message.cpim_from)[0] icon = NSApp.delegate( ).contactsWindowController.iconPathForURI(sender_uri) timestamp = Timestamp.parse(message.cpim_timestamp) is_html = False if message.content_type == 'text' else True self.chatViewController.showMessage(message.msgid, message.direction, message.cpim_from, icon, message.body, timestamp, recipient=message.cpim_to, state=message.status, is_html=is_html, history_entry=True)
def _NH_SIPEngineGotMessage(self, sender, data): account = AccountManager().find_account(data.request_uri) if not account: BlinkLogger().log_warning(u"Could not find recipient account for message to %s, using default" % data.request_uri) account = AccountManager().default_account is_cpim = False cpim_message = None replication_message = False if data.content_type == 'message/cpim': try: cpim_message = CPIMMessage.parse(data.body) except CPIMParserError: BlinkLogger().log_warning(u"SMS from %s has invalid CPIM content" % format_identity_to_string(data.from_header)) return else: is_cpim = True body = cpim_message.body content_type = cpim_message.content_type sender_identity = cpim_message.sender or data.from_header if cpim_message.sender and data.from_header.uri == data.to_header.uri and data.from_header.uri == cpim_message.sender.uri: replication_message = True window_tab_identity = cpim_message.recipients[0] if cpim_message.recipients else data.to_header else: window_tab_identity = data.from_header else: body = data.body.decode('utf-8') content_type = data.content_type sender_identity = data.from_header window_tab_identity = sender_identity is_html = content_type == 'text/html' if content_type in ('text/plain', 'text/html'): BlinkLogger().log_info(u"Got SMS from %s" % format_identity_to_string(sender_identity)) elif content_type == 'application/im-iscomposing+xml': # body must not be utf-8 decoded body = cpim_message.body if is_cpim else data.body msg = IsComposingMessage.parse(body) state = msg.state.value refresh = msg.refresh.value if msg.refresh is not None else None content_type = msg.content_type.value if msg.content_type is not None else None last_active = msg.last_active.value if msg.last_active is not None else None viewer = self.openMessageWindow(SIPURI.new(window_tab_identity.uri), window_tab_identity.display_name, account, create_if_needed=False, note_new_message=False) if viewer: viewer.gotIsComposing(self.windowForViewer(viewer), state, refresh, last_active) return else: BlinkLogger().log_warning(u"SMS from %s has unknown content-type %s" % (format_identity_to_string(data.from_header), data.content_type)) return # display the message note_new_message = False if replication_message else True viewer = self.openMessageWindow(SIPURI.new(window_tab_identity.uri), window_tab_identity.display_name, account, note_new_message=note_new_message) self.windowForViewer(viewer).noteNewMessageForSession_(viewer) replication_state = None replication_timestamp = None if replication_message: replicated_response_code = data.headers.get('X-Replication-Code', Null).body if replicated_response_code == '202': replication_state = 'deferred' elif replicated_response_code == '200': replication_state = 'delivered' else: replication_state = 'failed' replicated_timestamp = data.headers.get('X-Replication-Timestamp', Null).body try: replication_timestamp = Timestamp.parse(replicated_timestamp) except (TypeError, ValueError): replication_timestamp = Timestamp(datetime.datetime.now(tzlocal())) viewer.gotMessage(sender_identity, body, is_html, replication_state, replication_timestamp) self.windowForViewer(viewer).noteView_isComposing_(viewer, False) if replication_message: return if not self.windowForViewer(viewer).window().isKeyWindow(): # notify growl growl_data = TimestampedNotificationData() if is_html: growl_data.content = html2txt(body) else: growl_data.content = body growl_data.sender = format_identity_to_string(sender_identity, format='compact') self.notification_center.post_notification("GrowlGotSMS", sender=self, data=growl_data)
def parse(cls, string): message = cls('', None) try: headers_end = string.index('\r\n\r\n') except ValueError: raise CPIMParserError('Invalid CPIM message') else: headers = cls.headers_re.findall(buffer(string, 0, headers_end+2)) body = buffer(string, headers_end+4) namespaces = {u'': Namespace(cls.standard_namespace, u'')} subjects = {} for prefix, name, value in headers: if '.' in name: continue namespace = namespaces.get(prefix) if not namespace: continue try: value = value.decode('cpim-headers') if name == 'From' and namespace == cls.standard_namespace: message.sender = CPIMIdentity.parse(value) elif name == 'To' and namespace == cls.standard_namespace: message.recipients.append(CPIMIdentity.parse(value)) elif name == 'cc' and namespace == cls.standard_namespace: message.courtesy_recipients.append(CPIMIdentity.parse(value)) elif name == 'Subject' and namespace == cls.standard_namespace: match = cls.subject_re.match(value) if match is None: raise ValueError('Illegal Subject header: %r' % value) lang, subject = match.groups() # language tags must be ASCII subjects[str(lang) if lang is not None else None] = subject elif name == 'DateTime' and namespace == cls.standard_namespace: message.timestamp = Timestamp.parse(value) elif name == 'Required' and namespace == cls.standard_namespace: message.required.extend(re.split(r'\s*,\s*', value)) elif name == 'NS' and namespace == cls.standard_namespace: match = cls.namespace_re.match(value) if match is None: raise ValueError('Illegal NS header: %r' % value) prefix, uri = match.groups() namespaces[prefix] = Namespace(uri, prefix) else: message.additional_headers.append(CPIMHeader(name, namespace, value)) except ValueError: pass if None in subjects: message.subject = MultilingualText(subjects.pop(None), **subjects) else: message.subject = MultilingualText(**subjects) mime_message = Parser().parsestr(body) message.content_type = mime_message.get_content_type() if message.content_type.startswith('multipart/') or message.content_type == 'message/rfc822': message.body = mime_message.get_payload() else: message.body = mime_message.get_payload().decode(mime_message.get_content_charset() or 'utf-8') if message.content_type is None: raise CPIMParserError("CPIM message missing Content-Type MIME header") return message