def start(self, local_sdp, remote_sdp, stream_index): self.greenlet = api.getcurrent() notification_center = NotificationCenter() context = 'sdp_negotiation' try: remote_media = remote_sdp.media[stream_index] self.remote_media = remote_media self.remote_accept_types = remote_media.attributes.getfirst( b'accept-types', b'').decode().split() self.remote_accept_wrapped_types = remote_media.attributes.getfirst( b'accept-wrapped-types', b'').decode().split() self.cpim_enabled = contains_mime_type( self.accept_types, 'message/cpim') and contains_mime_type( self.remote_accept_types, 'message/cpim') remote_uri_path = remote_media.attributes.getfirst(b'path') if remote_uri_path is None: raise AttributeError( "remote SDP media does not have 'path' attribute") full_remote_path = [ URI.parse(uri) for uri in remote_uri_path.decode().split() ] remote_transport = 'tls' if full_remote_path[0].use_tls else 'tcp' if self.transport != remote_transport: raise MSRPStreamError( "remote transport ('%s') different from local transport ('%s')" % (remote_transport, self.transport)) if isinstance(self.session.account, Account) and self.local_role == 'actpass': remote_setup = remote_media.attributes.getfirst( 'setup', 'passive') if remote_setup == 'passive': # If actpass is offered connectors are always started as passive # We need to switch to active if the remote answers with passive if self.session.account.msrp.connection_model == 'relay': self.msrp_connector.mode = 'active' else: local_uri = self.msrp_connector.local_uri logger = self.msrp_connector.logger self.msrp_connector = DirectConnector( logger=logger, use_sessmatch=True) self.msrp_connector.prepare(local_uri) context = 'start' self.msrp = self.msrp_connector.complete(full_remote_path) if self.msrp_session_class is not None: self.msrp_session = self.msrp_session_class( self.msrp, accept_types=self.accept_types, on_incoming_cb=self._handle_incoming, automatic_reports=False) self.msrp_connector = None except (CertificateAuthorityError, CertificateError, CertificateRevokedError) as e: peer = '%s:%s' % (full_remote_path[0].host, full_remote_path[0].port) self._failure_reason = "%s - %s" % (peer, e.error) notification_center.post_notification( 'MediaStreamDidFail', sender=self, data=NotificationData( context=context, reason=self._failure_reason, transport=self.transport, credentials=self.session.account.tls_credentials)) except Exception as e: #traceback.print_exc() self._failure_reason = str(e) notification_center.post_notification( 'MediaStreamDidFail', sender=self, data=NotificationData( context=context, reason=self._failure_reason, transport=self.transport, credentials=self.session.account.tls_credentials)) else: notification_center.post_notification('MediaStreamDidStart', sender=self) finally: self.greenlet = None
def __init__(self, parent=None): super(AddAccountDialog, self).__init__(parent) with Resources.directory: self.setupUi(self) self.background_frame.setStyleSheet("") self.button_group = QButtonGroup(self) self.button_group.setObjectName("button_group") self.button_group.addButton( self.add_account_button, self.panel_view.indexOf(self.add_account_panel)) self.button_group.addButton( self.create_account_button, self.panel_view.indexOf(self.create_account_panel)) default_font_size = self.info_label.fontInfo().pointSizeF() title_font_size = limit(default_font_size + 3, max=14) font = self.title_label.font() font.setPointSizeF(title_font_size) self.title_label.setFont(font) font_metrics = self.create_status_label.fontMetrics() self.create_status_label.setMinimumHeight( font_metrics.height() + 2 * (font_metrics.height() + font_metrics.leading()) ) # reserve space for 3 lines font_metrics = self.email_note_label.fontMetrics() self.email_note_label.setMinimumWidth( font_metrics.width( u'The E-mail address is used when sending voicemail') ) # hack to make text justification look nice everywhere self.add_account_button.setChecked(True) self.panel_view.setCurrentWidget(self.add_account_panel) self.new_password_editor.textChanged.connect( self._SH_PasswordTextChanged) self.button_group.buttonClicked[int].connect( self._SH_PanelChangeRequest) self.accept_button.clicked.connect(self._SH_AcceptButtonClicked) self.display_name_editor.statusChanged.connect( self._SH_ValidityStatusChanged) self.name_editor.statusChanged.connect(self._SH_ValidityStatusChanged) self.username_editor.statusChanged.connect( self._SH_ValidityStatusChanged) self.sip_address_editor.statusChanged.connect( self._SH_ValidityStatusChanged) self.password_editor.statusChanged.connect( self._SH_ValidityStatusChanged) self.new_password_editor.statusChanged.connect( self._SH_ValidityStatusChanged) self.verify_password_editor.statusChanged.connect( self._SH_ValidityStatusChanged) self.email_address_editor.statusChanged.connect( self._SH_ValidityStatusChanged) self.display_name_editor.regexp = re.compile('^.*$') self.name_editor.regexp = re.compile('^.+$') self.username_editor.regexp = re.compile( '^\w(?<=[^0_])[\w.-]{4,31}(?<=[^_.-])$', re.IGNORECASE ) # in order to enable unicode characters add re.UNICODE to flags self.sip_address_editor.regexp = re.compile('^[^@\s]+@[^@\s]+$') self.password_editor.regexp = re.compile('^.*$') self.new_password_editor.regexp = re.compile('^.{8,}$') self.verify_password_editor.regexp = re.compile('^$') self.email_address_editor.regexp = re.compile('^[^@\s]+@[^@\s]+$') account_manager = AccountManager() notification_center = NotificationCenter() notification_center.add_observer(self, sender=account_manager)
def stop(self): notification_center = NotificationCenter() notification_center.remove_observer( self, name='XMPPIncomingMucSessionDidStart') notification_center.remove_observer( self, name='XMPPIncomingMucSessionDidEnd')
def __init__(self, sessionController): self.notification_center = NotificationCenter() self.sessionController = None self.audio_stream = None self.chat_stream = None self.add_session(sessionController) self.add_audio_stream() self.add_chat_stream() self.timer = NSTimer.timerWithTimeInterval_target_selector_userInfo_repeats_( 1.0, self, "updateTimer:", None, True) NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSModalPanelRunLoopMode) NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSDefaultRunLoopMode) NSBundle.loadNibNamed_owner_("SessionInfoPanel", self) sessionBoxTitle = NSAttributedString.alloc( ).initWithString_attributes_( "SIP Session", NSDictionary.dictionaryWithObject_forKey_( NSColor.orangeColor(), NSForegroundColorAttributeName)) self.sessionBox.setTitle_(sessionBoxTitle) audioBoxTitle = NSAttributedString.alloc().initWithString_attributes_( "Audio RTP Stream", NSDictionary.dictionaryWithObject_forKey_( NSColor.orangeColor(), NSForegroundColorAttributeName)) self.audioBox.setTitle_(audioBoxTitle) chatBoxTitle = NSAttributedString.alloc().initWithString_attributes_( "Chat MSRP Stream", NSDictionary.dictionaryWithObject_forKey_( NSColor.orangeColor(), NSForegroundColorAttributeName)) self.chatBox.setTitle_(chatBoxTitle) self.audio_rtt_graph.setLineWidth_(1.0) self.audio_rtt_graph.setLineSpacing_(1.0) self.audio_rtt_graph.setAboveLimit_( 200) # if higher than 200 ms show red color self.audio_rtt_graph.setMinimumHeigth_(200) self.audio_packet_loss_graph.setLineWidth_(1.0) self.audio_packet_loss_graph.setLineSpacing_(1.0) self.audio_packet_loss_graph.setAboveLimit_( 3) # if higher than 3% show red color self.audio_packet_loss_graph.setLineColor_(NSColor.greenColor()) self.audio_packet_loss_graph.setMinimumHeigth_(5) self.audio_jitter_graph.setLineWidth_(1.0) self.audio_jitter_graph.setLineSpacing_(1.0) self.audio_jitter_graph.setAboveLimit_( 50) # if higher than 50 ms show red color self.audio_jitter_graph.setLineColor_(NSColor.yellowColor()) self.audio_jitter_graph.setMinimumHeigth_(100) self.resetSession() self.updatePanelValues()
def __init__(self): self.notifications = deque() NotificationCenter().add_observer(ObserverWeakrefProxy(self))
def _NH_MediaStreamDidStart(self, sender, data): self.sessionController.log_info("Screen sharing started") self.changeStatus(STREAM_CONNECTED) NotificationCenter().add_observer(self, name="MSRPTransportTrace")
def start(self): notification_center = NotificationCenter() notification_center.add_observer(self, name='JanusBackendConnected') notification_center.add_observer(self, name='JanusBackendDisconnected') self.connector = connectWS(self.factory)
def smp_verify(self, secret, question=None): if self.encrypted: self.protocol.smp_verify(secret, question) else: notification_center = NotificationCenter() notification_center.post_notification('OTRSessionSMPVerificationDidNotStart', sender=self, data=NotificationData(reason='not encrypted'))
def awakeFromNib(self): if not self.accountTable: return NSNotificationCenter.defaultCenter().addObserver_selector_name_object_( self, "userDefaultsDidChange:", "NSUserDefaultsDidChangeNotification", NSUserDefaults.standardUserDefaults()) dotPath = NSBezierPath.bezierPathWithOvalInRect_(NSMakeRect( 2, 2, 8, 8)) self.dots = {} for i, color in [("red", NSColor.redColor()), ("yellow", NSColor.yellowColor()), ("green", NSColor.greenColor())]: dot = NSImage.alloc().initWithSize_(NSMakeSize(12, 12)) dot.lockFocus() color.set() dotPath.fill() dot.unlockFocus() self.dots[i] = dot if self.advancedTabView is not None: self.tableViewSelectionDidChange_(None) if self.accountTable: self.accountTable.setDraggingSourceOperationMask_forLocal_( NSDragOperationGeneric, True) self.accountTable.registerForDraggedTypes_( NSArray.arrayWithObject_("dragged-account")) notification_center = NotificationCenter() notification_center.add_observer(self, name="CFGSettingsObjectDidChange") notification_center.add_observer(self, name="AudioDevicesDidChange") self.window().setTitle_("%s Preferences" % NSApp.delegate().applicationName) self.toolbar.setSelectedItemIdentifier_('accounts') if NSApp.delegate().applicationName == 'Blink Lite': PreferenceOptionTypes['audio.pause_music'] = HiddenOption PreferenceOptionTypes['audio.directory'] = HiddenOption PreferenceOptionTypes['audio.auto_recording'] = HiddenOption PreferenceOptionTypes['logs.directory'] = HiddenOption PreferenceOptionTypes[ 'contacts.enable_favorites_group'] = HiddenOption PreferenceOptionTypes[ 'contacts.enable_incoming_calls_group'] = HiddenOption PreferenceOptionTypes[ 'contacts.enable_outgoing_calls_group'] = HiddenOption PreferenceOptionTypes[ 'contacts.enable_missed_calls_group'] = HiddenOption PreferenceOptionTypes['contacts.maximum_calls'] = HiddenOption for identifier in ('answering_machine', 'advanced'): try: item = (item for item in self.toolbar.visibleItems() if item.itemIdentifier() == identifier).next() self.toolbar.removeItemAtIndex_( self.toolbar.visibleItems().index(item)) except StopIteration: pass self.sync_with_icloud_checkbox.setHidden_(True) else: major, minor = platform.mac_ver()[0].split('.')[0:2] self.sync_with_icloud_checkbox.setHidden_(False if ( (int(major) == 10 and int(minor) >= 7) or int(major) > 10 ) else True) self.userDefaultsDidChange_(None)
def _browse_cb(self, file, flags, interface_index, error_code, service_name, regtype, reply_domain): notification_center = NotificationCenter() file = BonjourDiscoveryFile.find_by_file(file) service_description = BonjourServiceDescription( service_name, regtype, reply_domain) if error_code != _bonjour.kDNSServiceErr_NoError: error = _bonjour.BonjourError(error_code) notification_center.post_notification( 'BonjourAccountDiscoveryDidFail', sender=self.account, data=NotificationData(reason=str(error), transport=file.transport)) removed_files = [file] + [ f for f in self._files if isinstance(f, BonjourResolutionFile) and f.discovery_file == file ] for f in removed_files: self._files.remove(f) self._select_proc.kill(RestartSelect) for f in removed_files: f.close() if self._discover_timer is None: self._discover_timer = reactor.callLater( 1, self._command_channel.send, Command('discover')) return if reply_domain != 'local.': return if flags & _bonjour.kDNSServiceFlagsAdd: try: resolution_file = next( (f for f in self._files if isinstance(f, BonjourResolutionFile) and f.discovery_file == file and f.service_description == service_description)) except StopIteration: try: resolution_file = _bonjour.DNSServiceResolve( 0, interface_index, service_name, regtype, reply_domain, self._resolve_cb) except _bonjour.BonjourError as e: notification_center.post_notification( 'BonjourAccountDiscoveryFailure', sender=self.account, data=NotificationData(error=str(e), transport=file.transport)) else: resolution_file = BonjourResolutionFile( resolution_file, discovery_file=file, service_description=service_description) self._files.append(resolution_file) self._select_proc.kill(RestartSelect) else: try: resolution_file = next( (f for f in self._files if isinstance(f, BonjourResolutionFile) and f.discovery_file == file and f.service_description == service_description)) except StopIteration: pass else: self._files.remove(resolution_file) self._select_proc.kill(RestartSelect) resolution_file.close() service_description = resolution_file.service_description if service_description in self._neighbours: record = self._neighbours.pop(service_description) notification_center.post_notification( 'BonjourAccountDidRemoveNeighbour', sender=self.account, data=NotificationData(neighbour=service_description, record=record))
def _CH_discover(self, command): notification_center = NotificationCenter() settings = SIPSimpleSettings() if self._discover_timer is not None and self._discover_timer.active(): self._discover_timer.cancel() self._discover_timer = None supported_transports = set( transport for transport in settings.sip.transport_list if transport != 'tls' or self.account.tls.certificate is not None) discoverable_transports = set( 'tcp' if transport == 'tls' else transport for transport in supported_transports) old_files = [] for file in ( f for f in self._files[:] if isinstance(f, (BonjourDiscoveryFile, BonjourResolutionFile)) and f.transport not in discoverable_transports): old_files.append(file) self._files.remove(file) self._select_proc.kill(RestartSelect) for file in old_files: file.close() for service_description in [ service for service, record in self._neighbours.items() if record.uri.transport not in supported_transports ]: record = self._neighbours.pop(service_description) notification_center.post_notification( 'BonjourAccountDidRemoveNeighbour', sender=self.account, data=NotificationData(neighbour=service_description, record=record)) discovered_transports = set(file.transport for file in self._files if isinstance(file, BonjourDiscoveryFile)) missing_transports = discoverable_transports - discovered_transports added_transports = set() for transport in missing_transports: notification_center.post_notification( 'BonjourAccountWillInitiateDiscovery', sender=self.account, data=NotificationData(transport=transport)) try: file = _bonjour.DNSServiceBrowse(regtype="_sipuri._%s" % transport, callBack=self._browse_cb) except _bonjour.BonjourError as e: notification_center.post_notification( 'BonjourAccountDiscoveryDidFail', sender=self.account, data=NotificationData(reason=str(e), transport=transport)) else: self._files.append(BonjourDiscoveryFile(file, transport)) added_transports.add(transport) if added_transports: self._select_proc.kill(RestartSelect) if added_transports != missing_transports: self._discover_timer = reactor.callLater( 1, self._command_channel.send, Command('discover', command.event)) else: command.signal()
def stop(self): notification_center = NotificationCenter() notification_center.remove_observer(self, name='NetworkConditionsDidChange') self._select_proc.kill() self._command_channel.send_exception(api.GreenletExit)
def start(self): notification_center = NotificationCenter() notification_center.add_observer(self, name='NetworkConditionsDidChange') self._select_proc = proc.spawn(self._process_files) proc.spawn(self._handle_commands)
def __init__(self): from application import log self.level = log.level self.notification_center = NotificationCenter() self.log_settings = SIPSimpleSettings().logs
def stop(self): notification_center = NotificationCenter() notification_center.remove_observer(self)
def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.saved_account_state = None notification_center = NotificationCenter() notification_center.add_observer(self, name='SIPApplicationWillStart') notification_center.add_observer(self, name='SIPApplicationDidStart') notification_center.add_observer(self, name='SIPAccountGotMessageSummary') notification_center.add_observer(self, name='SIPAccountGotPendingWatcher') notification_center.add_observer(self, name='BlinkSessionNewOutgoing') notification_center.add_observer(self, name='BlinkSessionDidReinitializeForOutgoing') notification_center.add_observer(self, name='BlinkFileTransferNewIncoming') notification_center.add_observer(self, name='BlinkFileTransferNewOutgoing') notification_center.add_observer(self, name='DocumentSharingFileTransferCompleted') notification_center.add_observer(self, sender=AccountManager()) icon_manager = IconManager() self.pending_watcher_dialogs = [] self.mwi_icons = [QIcon(Resources.get('icons/mwi-%d.png' % i)) for i in xrange(0, 11)] self.mwi_icons.append(QIcon(Resources.get('icons/mwi-many.png'))) with Resources.directory: self.setupUi() self.setWindowTitle('Blink') self.setWindowIconText('Blink') geometry = QSettings().value("main_window/geometry") if geometry: self.restoreGeometry(geometry) self.default_icon_path = Resources.get('icons/default-avatar.png') self.default_icon = QIcon(self.default_icon_path) self.last_icon_directory = Path('~').normalized self.set_user_icon(icon_manager.get('avatar')) self.active_sessions_label.hide() self.enable_call_buttons(False) self.conference_button.setEnabled(False) self.hangup_all_button.setEnabled(False) self.sip_server_settings_action.setEnabled(False) self.search_for_people_action.setEnabled(False) self.history_on_server_action.setEnabled(False) self.main_view.setCurrentWidget(self.contacts_panel) self.contacts_view.setCurrentWidget(self.contact_list_panel) self.search_view.setCurrentWidget(self.search_list_panel) # System tray if QSystemTrayIcon.isSystemTrayAvailable(): self.system_tray_icon = QSystemTrayIcon(QIcon(Resources.get('icons/blink.png')), self) self.system_tray_icon.activated.connect(self._SH_SystemTrayIconActivated) menu = QMenu(self) menu.addAction(QAction("Show", self, triggered=self._AH_SystemTrayShowWindow)) menu.addAction(QAction(QIcon(Resources.get('icons/application-exit.png')), "Quit", self, triggered=self._AH_QuitActionTriggered)) self.system_tray_icon.setContextMenu(menu) self.system_tray_icon.show() else: self.system_tray_icon = None # Accounts self.account_model = AccountModel(self) self.enabled_account_model = ActiveAccountModel(self.account_model, self) self.server_tools_account_model = ServerToolsAccountModel(self.account_model, self) self.identity.setModel(self.enabled_account_model) # Contacts self.contact_model = ContactModel(self) self.contact_search_model = ContactSearchModel(self.contact_model, self) self.contact_list.setModel(self.contact_model) self.search_list.setModel(self.contact_search_model) # Sessions (audio) self.session_model = AudioSessionModel(self) self.session_list.setModel(self.session_model) self.session_list.selectionModel().selectionChanged.connect(self._SH_SessionListSelectionChanged) # History self.history_manager = HistoryManager() # Windows, dialogs and panels self.about_panel = AboutPanel(self) self.conference_dialog = ConferenceDialog(self) self.contact_editor_dialog = ContactEditorDialog(self) self.google_contacts_dialog = GoogleContactsDialog(self) self.filetransfer_window = FileTransferWindow() self.preferences_window = PreferencesWindow(self.account_model, None) self.server_tools_window = ServerToolsWindow(self.server_tools_account_model, None) self.documents_window = DocumentsWindow() # Signals self.account_state.stateChanged.connect(self._SH_AccountStateChanged) self.account_state.clicked.connect(self._SH_AccountStateClicked) self.activity_note.editingFinished.connect(self._SH_ActivityNoteEditingFinished) self.add_contact_button.clicked.connect(self._SH_AddContactButtonClicked) self.add_search_contact_button.clicked.connect(self._SH_AddContactButtonClicked) self.audio_call_button.clicked.connect(self._SH_AudioCallButtonClicked) self.video_call_button.clicked.connect(self._SH_VideoCallButtonClicked) self.chat_session_button.clicked.connect(self._SH_ChatSessionButtonClicked) self.share_document_button.clicked.connect(self._SH_ShareDocumentButtonClicked) self.back_to_contacts_button.clicked.connect(self.search_box.clear) # this can be set in designer -Dan self.conference_button.makeConference.connect(self._SH_MakeConference) self.conference_button.breakConference.connect(self._SH_BreakConference) self.contact_list.selectionModel().selectionChanged.connect(self._SH_ContactListSelectionChanged) self.contact_model.itemsAdded.connect(self._SH_ContactModelAddedItems) self.contact_model.itemsRemoved.connect(self._SH_ContactModelRemovedItems) self.display_name.editingFinished.connect(self._SH_DisplayNameEditingFinished) self.hangup_all_button.clicked.connect(self._SH_HangupAllButtonClicked) self.identity.activated[int].connect(self._SH_IdentityChanged) self.identity.currentIndexChanged[int].connect(self._SH_IdentityCurrentIndexChanged) self.mute_button.clicked.connect(self._SH_MuteButtonClicked) self.search_box.textChanged.connect(self._SH_SearchBoxTextChanged) self.search_box.returnPressed.connect(self._SH_SearchBoxReturnPressed) self.search_box.shortcut.activated.connect(self.search_box.setFocus) self.search_list.selectionModel().selectionChanged.connect(self._SH_SearchListSelectionChanged) self.server_tools_account_model.rowsInserted.connect(self._SH_ServerToolsAccountModelChanged) self.server_tools_account_model.rowsRemoved.connect(self._SH_ServerToolsAccountModelChanged) self.session_model.sessionAdded.connect(self._SH_AudioSessionModelAddedSession) self.session_model.sessionRemoved.connect(self._SH_AudioSessionModelRemovedSession) self.session_model.structureChanged.connect(self._SH_AudioSessionModelChangedStructure) self.silent_button.clicked.connect(self._SH_SilentButtonClicked) self.switch_view_button.viewChanged.connect(self._SH_SwitchViewButtonChangedView) # Blink menu actions self.about_action.triggered.connect(self.about_panel.show) self.add_account_action.triggered.connect(self.preferences_window.show_add_account_dialog) self.manage_accounts_action.triggered.connect(self.preferences_window.show_for_accounts) self.help_action.triggered.connect(partial(QDesktopServices.openUrl, QUrl(u'http://icanblink.com/help-qt.phtml'))) self.preferences_action.triggered.connect(self.preferences_window.show) self.auto_accept_chat_action.triggered.connect(self._AH_AutoAcceptChatActionTriggered) self.received_messages_sound_action.triggered.connect(self._AH_ReceivedMessagesSoundActionTriggered) self.answering_machine_action.triggered.connect(self._AH_EnableAnsweringMachineActionTriggered) self.release_notes_action.triggered.connect(partial(QDesktopServices.openUrl, QUrl(u'http://icanblink.com/changelog-qt.phtml'))) self.quit_action.triggered.connect(self._AH_QuitActionTriggered) # Call menu actions self.redial_action.triggered.connect(self._AH_RedialActionTriggered) self.join_conference_action.triggered.connect(self.conference_dialog.show) self.history_menu.aboutToShow.connect(self._SH_HistoryMenuAboutToShow) self.history_menu.triggered.connect(self._AH_HistoryMenuTriggered) self.output_devices_group.triggered.connect(self._AH_AudioOutputDeviceChanged) self.input_devices_group.triggered.connect(self._AH_AudioInputDeviceChanged) self.alert_devices_group.triggered.connect(self._AH_AudioAlertDeviceChanged) self.video_devices_group.triggered.connect(self._AH_VideoDeviceChanged) self.mute_action.triggered.connect(self._SH_MuteButtonClicked) self.silent_action.triggered.connect(self._SH_SilentButtonClicked) # Tools menu actions self.sip_server_settings_action.triggered.connect(self._AH_SIPServerSettings) self.search_for_people_action.triggered.connect(self._AH_SearchForPeople) self.history_on_server_action.triggered.connect(self._AH_HistoryOnServer) # Window menu actions self.chat_window_action.triggered.connect(self._AH_ChatWindowActionTriggered) self.transfers_window_action.triggered.connect(self._AH_TransfersWindowActionTriggered) self.logs_window_action.triggered.connect(self._AH_LogsWindowActionTriggered) self.received_files_window_action.triggered.connect(self._AH_ReceivedFilesWindowActionTriggered) self.screenshots_window_action.triggered.connect(self._AH_ScreenshotsWindowActionTriggered) self.documents_window_action.triggered.connect(self._AH_DocumentsWindowActionTriggered)
def userDefaultsDidChange_(self, notification): userdef = NSUserDefaults.standardUserDefaults() notification_center = NotificationCenter() trace = userdef.integerForKey_("SIPTrace") if trace == Disabled: notification_center.discard_observer(self, name="SIPEngineSIPTrace") notification_center.discard_observer(self, name="DNSLookupTrace") self.sipTraceType = None elif trace == Simplified: notification_center.add_observer(self, name="SIPEngineSIPTrace") notification_center.add_observer(self, name="DNSLookupTrace") self.sipTraceType = "simple" elif trace == Full: notification_center.add_observer(self, name="SIPEngineSIPTrace") notification_center.add_observer(self, name="DNSLookupTrace") self.sipTraceType = "full" trace = userdef.integerForKey_("MSRPTrace") if trace == Disabled: notification_center.discard_observer(self, name="MSRPLibraryLog") notification_center.discard_observer(self, name="MSRPTransportTrace") self.msrpTraceType = None elif trace == Simplified: notification_center.add_observer(self, name="MSRPLibraryLog") notification_center.add_observer(self, name="MSRPTransportTrace") self.msrpTraceType = "simple" elif trace == Full: notification_center.add_observer(self, name="MSRPLibraryLog") notification_center.add_observer(self, name="MSRPTransportTrace") self.msrpTraceType = "full" trace = userdef.integerForKey_("XCAPTrace") if trace == Disabled: notification_center.discard_observer( self, name="XCAPManagerDidDiscoverServerCapabilities") notification_center.discard_observer( self, name="XCAPSubscriptionGotNotify") notification_center.discard_observer( self, name="XCAPManagerDidChangeState") self.xcapTraceType = None elif trace == Simplified: notification_center.add_observer( self, name="XCAPManagerDidDiscoverServerCapabilities") notification_center.add_observer(self, name="XCAPManagerDidChangeState") self.xcapTraceType = "simple" elif trace == Full: notification_center.add_observer( self, name="XCAPManagerDidDiscoverServerCapabilities") notification_center.add_observer(self, name="XCAPManagerDidChangeState") notification_center.add_observer(self, name="XCAPSubscriptionGotNotify") self.xcapTraceType = "full" trace = userdef.boolForKey_("EnablePJSIPTrace") if trace: notification_center.add_observer(self, name="SIPEngineLog") else: notification_center.discard_observer(self, name="SIPEngineLog") trace = userdef.boolForKey_("EnableNotificationsTrace") if trace: notification_center.add_observer(self) else: notification_center.discard_observer(self)
def onMessage(self, msg): notification_center = NotificationCenter() sender_uri = FrozenURI.parse('xmpp:' + msg['from']) sender = Identity(sender_uri) recipient_uri = FrozenURI.parse('xmpp:' + msg['to']) recipient = Identity(recipient_uri) msg_type = msg.getAttribute('type') msg_id = msg.getAttribute('id', None) is_empty = msg.body is None and msg.html is None if msg_type == 'error': error_type = msg.error['type'] conditions = [(child.name, child.defaultUri) for child in msg.error.elements()] error_message = ErrorStanza('message', sender, recipient, error_type, conditions, id=msg_id) notification_center.post_notification( 'XMPPGotErrorMessage', sender=self.parent, data=NotificationData(error_message=error_message)) return if msg_type in (None, 'normal', 'chat') and not is_empty: body = None html_body = None if msg.html is not None: html_body = msg.html.toXml() if msg.body is not None: body = unicode(msg.body) try: elem = next(c for c in msg.elements() if c.uri == RECEIPTS_NS) except StopIteration: use_receipt = False else: use_receipt = elem.name == u'request' if msg_type == 'chat': message = ChatMessage(sender, recipient, body, html_body, id=msg_id, use_receipt=use_receipt) notification_center.post_notification( 'XMPPGotChatMessage', sender=self.parent, data=NotificationData(message=message)) else: message = NormalMessage(sender, recipient, body, html_body, id=msg_id, use_receipt=use_receipt) notification_center.post_notification( 'XMPPGotNormalMessage', sender=self.parent, data=NotificationData(message=message)) return # Check if it's a composing indication if msg_type == 'chat' and is_empty: for elem in msg.elements(): try: elem = next(c for c in msg.elements() if c.uri == CHATSTATES_NS) except StopIteration: pass else: composing_indication = ChatComposingIndication(sender, recipient, elem.name, id=msg_id) notification_center.post_notification( 'XMPPGotComposingIndication', sender=self.parent, data=NotificationData( composing_indication=composing_indication)) return # Check if it's a receipt acknowledgement if is_empty: try: elem = next(c for c in msg.elements() if c.uri == RECEIPTS_NS) except StopIteration: pass else: if elem.name == u'received' and msg_id is not None: receipt = MessageReceipt(sender, recipient, msg_id) notification_center.post_notification( 'XMPPGotReceipt', sender=self.parent, data=NotificationData(receipt=receipt))
def dealloc(self): BlinkLogger().log_info(u"Disposing %s" % self) self.stream = None self.sessionController = None NotificationCenter().discard_observer(self, name="MSRPTransportTrace") super(DesktopSharingController, self).dealloc()
def onSessionInitiate(self, request): reactor.callLater(0, NotificationCenter().post_notification, 'XMPPGotJingleSessionInitiate', sender=self.parent, data=NotificationData(stanza=request, protocol=self))
class JanusClientProtocol(WebSocketClientProtocol): _event_handlers = None _pending_transactions = None _keepalive_timers = None _keepalive_interval = 45 notification_center = NotificationCenter() def onOpen(self): self.notification_center.post_notification('JanusBackendConnected', sender=self) self._pending_transactions = {} self._keepalive_timers = {} self._event_handlers = {} def onMessage(self, payload, isBinary): if isBinary: log.warn('Unexpected binary payload received') return self.notification_center.post_notification('WebRTCJanusTrace', sender=self, data=NotificationData( direction='INCOMING', message=payload, peer=self.peer)) try: message = janus.JanusMessage.from_payload(json.loads(payload)) except Exception as e: log.warning('Error decoding Janus message: {!s}'.format(e)) return if isinstance(message, (janus.CoreEvent, janus.PluginEvent)): # some of the plugin events might have the transaction, but we do not finalize # the transaction for them as they are not direct responses for the transaction handler = self._event_handlers.get(message.sender, Null) try: handler(message) except Exception as e: log.exception( 'Error while running Janus event handler: {!s}'.format(e)) return # at this point it can only be a response. clear the transaction and return the answer. try: request, deferred = self._pending_transactions.pop( message.transaction) except KeyError: log.warn('Discarding unexpected response: %s' % payload) return if isinstance(message, janus.AckResponse): deferred.callback(None) elif isinstance(message, janus.SuccessResponse): deferred.callback(message) elif isinstance(message, janus.ErrorResponse): deferred.errback( JanusError(message.error.code, message.error.reason)) else: assert isinstance(message, janus.PluginResponse) plugin_data = message.plugindata.data if isinstance(plugin_data, (janus.SIPErrorEvent, janus.VideoroomErrorEvent)): deferred.errback( JanusError(plugin_data.error_code, plugin_data.error)) else: deferred.callback(message) def connectionLost(self, reason): super(JanusClientProtocol, self).connectionLost(reason) self.notification_center.post_notification( 'JanusBackendDisconnected', sender=self, data=NotificationData(reason=reason.getErrorMessage())) def disconnect(self, code=1000, reason=u''): self.sendClose(code, reason) def _send_request(self, request): if request.janus != 'keepalive' and 'session_id' in request: # postpone keepalive messages as long as we have non-keepalive traffic for a given session keepalive_timer = self._keepalive_timers.get( request.session_id, None) if keepalive_timer is not None and keepalive_timer.active(): keepalive_timer.reset(self._keepalive_interval) deferred = defer.Deferred() message = json.dumps(request.__data__) self.notification_center.post_notification('WebRTCJanusTrace', sender=self, data=NotificationData( direction='OUTGOING', message=message, peer=self.peer)) self.sendMessage(message) self._pending_transactions[request.transaction] = request, deferred return deferred def _start_keepalive(self, response): session_id = response.data.id self._keepalive_timers[session_id] = reactor.callLater( self._keepalive_interval, self._send_keepalive, session_id) return response def _stop_keepalive(self, session_id): timer = self._keepalive_timers.pop(session_id, None) if timer is not None and timer.active(): timer.cancel() def _send_keepalive(self, session_id): deferred = self._send_request( janus.SessionKeepaliveRequest(session_id=session_id)) deferred.addBoth(self._keepalive_callback, session_id) def _keepalive_callback(self, result, session_id): if isinstance(result, Failure): self._keepalive_timers.pop(session_id) else: self._keepalive_timers[session_id] = reactor.callLater( self._keepalive_interval, self._send_keepalive, session_id) # Public API def set_event_handler(self, handle_id, event_handler): if event_handler is None: self._event_handlers.pop(handle_id, None) log.debug("Destroy Janus session, %d handlers in use" % len(self._event_handlers.keys())) else: assert callable(event_handler) self._event_handlers[handle_id] = event_handler log.debug("Create Janus session, %d handlers in use" % len(self._event_handlers.keys())) def info(self): return self._send_request(janus.InfoRequest()) def create_session(self): return self._send_request(janus.SessionCreateRequest()).addCallback( self._start_keepalive) def destroy_session(self, session_id): self._stop_keepalive(session_id) return self._send_request( janus.SessionDestroyRequest(session_id=session_id)) def attach_plugin(self, session_id, plugin): return self._send_request( janus.PluginAttachRequest(session_id=session_id, plugin=plugin)) def detach_plugin(self, session_id, handle_id): return self._send_request( janus.PluginDetachRequest(session_id=session_id, handle_id=handle_id)) def message(self, session_id, handle_id, body, jsep=None): if jsep is not None: return self._send_request( janus.MessageRequest(session_id=session_id, handle_id=handle_id, body=body, jsep=jsep)) else: return self._send_request( janus.MessageRequest(session_id=session_id, handle_id=handle_id, body=body)) def trickle(self, session_id, handle_id, candidates): return self._send_request( janus.TrickleRequest(session_id=session_id, handle_id=handle_id, candidates=candidates))
def onSessionAccept(self, request): reactor.callLater(0, NotificationCenter().post_notification, 'XMPPGotJingleSessionAccept', sender=self.parent, data=NotificationData(stanza=request))
def _lookup_srv_records(self, resolver, srv_names, additional_records=[], log_context={}): notification_center = NotificationCenter() additional_services = dict((rset.name.to_text(), rset) for rset in additional_records if rset.rdtype == rdatatype.SRV) services = {} for srv_name in srv_names: services[srv_name] = [] if srv_name in additional_services: addresses = self._lookup_a_records(resolver, [ r.target.to_text() for r in additional_services[srv_name] ], additional_records) for record in additional_services[srv_name]: services[srv_name].extend( SRVResult(record.priority, record.weight, record.port, addr) for addr in addresses.get(record.target.to_text(), ())) else: try: answer = resolver.query(srv_name, rdatatype.SRV) except dns.resolver.Timeout, e: notification_center.post_notification( 'DNSLookupTrace', sender=self, data=NotificationData(query_type='SRV', query_name=str(srv_name), nameservers=resolver.nameservers, answer=None, error=e, **log_context)) raise except exception.DNSException, e: notification_center.post_notification( 'DNSLookupTrace', sender=self, data=NotificationData(query_type='SRV', query_name=str(srv_name), nameservers=resolver.nameservers, answer=None, error=e, **log_context)) else: notification_center.post_notification( 'DNSLookupTrace', sender=self, data=NotificationData(query_type='SRV', query_name=str(srv_name), nameservers=resolver.nameservers, answer=answer, error=None, **log_context)) addresses = self._lookup_a_records( resolver, [r.target.to_text() for r in answer.rrset], answer.response.additional, log_context) for record in answer.rrset: services[srv_name].extend( SRVResult(record.priority, record.weight, record.port, addr) for addr in addresses.get(record.target.to_text(), ()))
def onTransportInfo(self, request): reactor.callLater(0, NotificationCenter().post_notification, 'XMPPGotJingleTransportInfo', sender=self.parent, data=NotificationData(stanza=request))
def incoming_session(self, session): log.info('New session from %s to %s' % (session.remote_identity.uri, session.local_identity.uri)) audio_streams = [ stream for stream in session.proposed_streams if stream.type == 'audio' ] chat_streams = [ stream for stream in session.proposed_streams if stream.type == 'chat' ] transfer_streams = [ stream for stream in session.proposed_streams if stream.type == 'file-transfer' ] if not audio_streams and not chat_streams and not transfer_streams: log.info(u'Session rejected: invalid media') session.reject(488) return audio_stream = audio_streams[0] if audio_streams else None chat_stream = chat_streams[0] if chat_streams else None transfer_stream = transfer_streams[0] if transfer_streams else None try: self.validate_acl(session.request_uri, session.remote_identity.uri) except ACLValidationError: log.info(u'Session rejected: unauthorized by access list') session.reject(403) return if transfer_stream is not None: try: room = self.get_room(session.request_uri) except RoomNotFoundError: log.info(u'Session rejected: room not found') session.reject(404) return if transfer_stream.direction == 'sendonly': # file transfer 'pull' try: file = next( file for file in room.files if file.hash == transfer_stream.file_selector.hash) except StopIteration: log.info(u'Session rejected: requested file not found') session.reject(404) return try: transfer_stream.file_selector = file.file_selector except EnvironmentError as e: log.info( u'Session rejected: error opening requested file: %s' % e) session.reject(404) return else: transfer_stream.handler.save_directory = os.path.join( ConferenceConfig.file_transfer_dir.normalized, room.uri) NotificationCenter().add_observer(self, sender=session) if audio_stream: session.send_ring_indication() streams = [ stream for stream in (audio_stream, chat_stream, transfer_stream) if stream ] reactor.callLater(4 if audio_stream is not None else 0, self.accept_session, session, streams)
def _run(self): notification_center = NotificationCenter() try: while True: command = self._channel.wait() if command.name == 'play': self._wave_file = WaveFile(self.mixer, self.filename) notification_center.add_observer( self, sender=self._wave_file, name='WaveFileDidFinishPlaying') self._wave_file.volume = self.volume try: self._wave_file.start() except SIPCoreError, e: notification_center.post_notification( 'WavePlayerDidFail', sender=self, data=NotificationData(error=e)) raise WavePlayerError(e) else: if self._current_loop == 0: notification_center.post_notification( 'WavePlayerDidStart', sender=self) notification_center.post_notification( 'AudioPortDidChangeSlots', sender=self, data=NotificationData( consumer_slot_changed=False, producer_slot_changed=True, old_producer_slot=None, new_producer_slot=self._wave_file.slot)) elif command.name == 'reschedule': self._current_loop += 1 notification_center.remove_observer( self, sender=self._wave_file, name='WaveFileDidFinishPlaying') self._wave_file = None notification_center.post_notification( 'AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=False, producer_slot_changed=True, old_producer_slot=None, new_producer_slot=None)) if self.loop_count == 0 or self._current_loop < self.loop_count: reactor.callLater(self.pause_time, self._channel.send, Command('play')) else: notification_center.post_notification( 'WavePlayerDidEnd', sender=self) break elif command.name == 'stop': if self._wave_file is not None: notification_center.remove_observer( self, sender=self._wave_file, name='WaveFileDidFinishPlaying') self._wave_file.stop() self._wave_file = None notification_center.post_notification( 'AudioPortDidChangeSlots', sender=self, data=NotificationData(consumer_slot_changed=False, producer_slot_changed=True, old_producer_slot=None, new_producer_slot=None)) notification_center.post_notification( 'WavePlayerDidEnd', sender=self) break
def start(self): notification_center = NotificationCenter() notification_center.add_observer(self, name='XMPPChatSessionDidStart') notification_center.add_observer(self, name='XMPPChatSessionDidEnd')
def start(self): notification_center = NotificationCenter() notification_center.add_observer(self)
def start(self): NotificationCenter().post_notification('XMPPChatSessionDidStart', sender=self) self._proc = proc.spawn(self._run) self.state = 'started'
def initialize(self, session, direction): self.greenlet = api.getcurrent() notification_center = NotificationCenter() notification_center.add_observer(self, sender=self) settings = SIPSimpleSettings() try: self.session = session self.transport = self.session.account.msrp.transport outgoing = direction == 'outgoing' logger = NotificationProxyLogger() if self.session.account is BonjourAccount(): if outgoing: self.msrp_connector = DirectConnector(logger=logger) self.local_role = 'active' else: if self.transport == 'tls' and settings.tls.certificate is None: raise MSRPStreamError( "Cannot accept MSRP connection without a TLS certificate" ) self.msrp_connector = DirectAcceptor(logger=logger) self.local_role = 'passive' else: if self.session.account.msrp.connection_model == 'relay': if not outgoing and self.remote_role in ('actpass', 'passive'): # 'passive' not allowed by the RFC but play nice for interoperability. -Saul self.msrp_connector = DirectConnector( logger=logger, use_sessmatch=True) self.local_role = 'active' elif outgoing and not self.session.account.nat_traversal.use_msrp_relay_for_outbound: self.msrp_connector = DirectConnector( logger=logger, use_sessmatch=True) self.local_role = 'active' else: if self.session.account.nat_traversal.msrp_relay is None: relay_host = relay_port = None else: if self.transport != self.session.account.nat_traversal.msrp_relay.transport: raise MSRPStreamError( "MSRP relay transport conflicts with MSRP transport setting" ) relay_host = self.session.account.nat_traversal.msrp_relay.host relay_port = self.session.account.nat_traversal.msrp_relay.port relay = MSRPRelaySettings( domain=self.session.account.uri.host.decode(), username=self.session.account.uri.user.decode(), password=self.session.account.credentials.password. decode(), host=relay_host, port=relay_port, use_tls=self.transport == 'tls') self.msrp_connector = RelayConnection( relay, 'passive', logger=logger, use_sessmatch=True) self.local_role = 'actpass' if outgoing else 'passive' else: if not outgoing and self.remote_role in ('actpass', 'passive'): # 'passive' not allowed by the RFC but play nice for interoperability. -Saul self.msrp_connector = DirectConnector( logger=logger, use_sessmatch=True) self.local_role = 'active' else: if not outgoing and self.transport == 'tls' and settings.tls.certificate is None: raise MSRPStreamError( "Cannot accept MSRP connection without a TLS certificate" ) self.msrp_connector = DirectAcceptor( logger=logger, use_sessmatch=True) self.local_role = 'actpass' if outgoing else 'passive' full_local_path = self.msrp_connector.prepare(local_uri=URI( host=host.default_ip, port=0, use_tls=self.transport == 'tls', credentials=self.session.account.tls_credentials)) self.local_media = self._create_local_media(full_local_path) except (CertificateError, CertificateAuthorityError, CertificateExpiredError, CertificateSecurityError, CertificateRevokedError) as e: reason = "%s for %s" % (e.error, e.certificate.subject.CN.lower()) notification_center.post_notification( 'MediaStreamDidNotInitialize', sender=self, data=NotificationData( reason=reason, transport=self.transport, credentials=self.session.account.tls_credentials)) except Exception as e: notification_center.post_notification( 'MediaStreamDidNotInitialize', sender=self, data=NotificationData( reason=str(e), transport=self.transport, credentials=self.session.account.tls_credentials)) else: notification_center.post_notification('MediaStreamDidInitialize', sender=self) finally: self._initialize_done = True self.greenlet = None