def updateBonjourServersPopupButton(self): settings = SIPSimpleSettings() account = AccountManager().default_account if isinstance(account, BonjourAccount): self.bonjour_server_combolist.removeAllItems() if SIPManager().bonjour_conference_services.servers: servers = set() servers_dict = {} for server in (server for server in SIPManager().bonjour_conference_services.servers if server.uri.transport in settings.sip.transport_list): servers_dict.setdefault("%s@%s" % (server.uri.user, server.uri.host), []).append(server) for transport in (transport for transport in ('tls', 'tcp', 'udp') if transport in settings.sip.transport_list): for k, v in servers_dict.items(): try: server = next((server for server in v if server.uri.transport == transport)) except StopIteration: pass else: servers.add(server) break for server in servers: self.bonjour_server_combolist.addItemWithTitle_('%s (%s)' % (server.host, server.uri.host)) item = self.bonjour_server_combolist.lastItem() item.setRepresentedObject_(server) self.ok_button.setEnabled_(True) else: self.bonjour_server_combolist.addItemWithTitle_(NSLocalizedString("No conference server in this neighbourhood", "Menu item")) self.bonjour_server_combolist.lastItem().setEnabled_(False) self.ok_button.setEnabled_(False) else: self.ok_button.setEnabled_(False)
def init(self): if self: NSBundle.loadNibNamed_owner_("EnrollmentWindow", self) icloud_sync_enabled = NSUserDefaults.standardUserDefaults().stringForKey_("iCloudSyncEnabled") self.syncWithiCloudCheckbox.setHidden_(not icloud_sync_enabled) self.selectRadio_(self.radioMatrix) if not SIPManager().validateAddAccountAction(): self.nextButton.setEnabled_(False) self.purchaseProLabel.setHidden_(False) if NSApp.delegate().contactsWindowController.first_run: NotificationCenter().add_observer(self, name='SIPAccountManagerDidAddAccount') if NSApp.delegate().allowed_domains: self.allowed_domains = NSApp.delegate().allowed_domains self.syncWithiCloudCheckbox.setHidden_(True) self.syncWithiCloudCheckbox.setState_(NSOffState) self.domainButton.setHidden_(True) self.addressText.cell().setPlaceholderString_('user@' + self.allowed_domains[0]) if not NSApp.delegate().icloud_enabled: self.syncWithiCloudCheckbox.setHidden_(True) return self
def muteBeforeSpeechWillStart(self): hasAudio = any(sess.hasStreamOfType("audio") for sess in self.sessionControllersManager.sessionControllers) if hasAudio: if not SIPManager().is_muted(): NSApp.delegate().contactsWindowController.muteClicked_(None) self.muted_by_synthesizer = True if self.speech_recognizer: self.speech_recognizer.stopListening()
def init(self): if self: NSBundle.loadNibNamed_owner_("EnrollmentWindow", self) self.selectRadio_(self.radioMatrix) if not SIPManager().validateAddAccountAction(): self.nextButton.setEnabled_(False) self.purchaseProLabel.setHidden_(False) if NSApp.delegate().contactsWindowController.first_run: NotificationCenter().add_observer( self, name='SIPAccountManagerDidAddAccount') return self
def applicationDidFinishLaunching_(self, sender): self.blinkMenu.setTitle_(self.applicationNamePrint) config_file = ApplicationData.get('config') self.icloud_manager = iCloudManager() self.backend = SIPManager() self.contactsWindowController.setup(self.backend) while True: try: first_run = not os.path.exists(config_file) self.contactsWindowController.first_run = first_run self.backend.init() self.backend.fetch_account() accounts = AccountManager().get_accounts() if not accounts or (first_run and accounts == [BonjourAccount()]): self.wait_for_enrollment = True self.enroll() break except FileParserError, exc: BlinkLogger().log_warning(u"Error parsing configuration file: %s" % exc) if NSRunAlertPanel(NSLocalizedString("Error", "Window title"), NSLocalizedString("The configuration file is corrupted. You will need to replace it and re-enter your account information. \n\nYour current configuration file will be backed up to %s.corrupted. ", "Label") % config_file, NSLocalizedString("Replace", "Button title"), NSLocalizedString("Quit", "Button title"), None) != NSAlertDefaultReturn: NSApp.terminate_(None) return os.rename(config_file, config_file+".corrupted") BlinkLogger().log_info(u"Renamed configuration file to %s" % config_file+".corrupted") except BaseException, exc: import traceback print traceback.print_exc() NSRunAlertPanel(NSLocalizedString("Error", "Window title"), NSLocalizedString("There was an error during startup of core functionality:\n%s", "Label") % exc, NSLocalizedString("Quit", "Button title"), None, None) NSApp.terminate_(None) return
def _addIncomingSession(self, session, streams, is_update_proposal): view = self.getItemView() self.sessions[session] = view settings = SIPSimpleSettings() stream_type_list = list(set(stream.type for stream in streams)) if len(self.sessions) == 1: if "screen-sharing" in stream_type_list: base_text = NSLocalizedString("Screen Sharing from %s", "Label") elif "video" in stream_type_list: base_text = NSLocalizedString("Video call from %s", "Label") elif "audio" in stream_type_list: base_text = NSLocalizedString("Audio call from %s", "Label") elif stream_type_list == ["file-transfer"]: base_text = NSLocalizedString("File transfer from %s", "Label") elif stream_type_list == ["chat"]: base_text = NSLocalizedString("Chat from %s", "Label") else: base_text = NSLocalizedString("Call from %s", "Label") title = base_text % format_identity_to_string(session.remote_identity, check_contact=True, format='compact') self.panel.setTitle_(title) if settings.sounds.enable_speech_synthesizer: self.speak_text = title self.startSpeechSynthesizerTimer() else: self.panel.setTitle_(NSLocalizedString("Multiple Incoming Calls", "Label")) NotificationCenter().add_observer(self, sender=session) subjectLabel = view.viewWithTag_(1) fromLabel = view.viewWithTag_(2) accountLabel = view.viewWithTag_(3) acceptButton = view.viewWithTag_(5) rejectButton = view.viewWithTag_(7) accepyOnlyButton = view.viewWithTag_(6) busyButton = view.viewWithTag_(8) callerIcon = view.viewWithTag_(99) chatIcon = view.viewWithTag_(31) audioIcon = view.viewWithTag_(32) fileIcon = view.viewWithTag_(33) screenIcon = view.viewWithTag_(34) videoIcon = view.viewWithTag_(35) stream_types = [s.type for s in streams] session_manager = SessionManager() have_audio_call = any(s for s in session_manager.sessions if s is not session and s.streams and 'audio' in (stream.type for stream in s.streams)) if not have_audio_call: self.startSpeechRecognition() typeCount = 0 if 'audio' in stream_types: frame = audioIcon.frame() typeCount+= 1 frame.origin.x = NSMaxX(view.frame()) - 10 - (NSWidth(frame) + 10) * typeCount audioIcon.setFrame_(frame) audioIcon.setHidden_(False) if not is_update_proposal: frame = view.frame() frame.size.height += 20 # give extra space for the counter label view.setFrame_(frame) if session.account.audio.auto_accept: have_audio_call = any(s for s in session_manager.sessions if s is not session and s.streams and 'audio' in (stream.type for stream in s.streams)) if not have_audio_call: self.enableAutoAnswer(view, session, session.account.audio.answer_delay) elif settings.answering_machine.enabled or (is_anonymous(session.remote_identity.uri) and session.account.pstn.anonymous_to_answering_machine): self.enableAnsweringMachine(view, session) if 'chat' in stream_types: frame = chatIcon.frame() typeCount+= 1 frame.origin.x = NSMaxX(view.frame()) - 10 - (NSWidth(frame) + 10) * typeCount chatIcon.setFrame_(frame) chatIcon.setHidden_(False) if 'screen-sharing' in stream_types: frame = screenIcon.frame() typeCount+= 1 frame.origin.x = NSMaxX(view.frame()) - 10 - (NSWidth(frame) + 10) * typeCount screenIcon.setFrame_(frame) screenIcon.setHidden_(False) if 'video' in stream_types: #have_video_call = any(s for s in session_manager.sessions if s is not session and s.streams and 'video' in (stream.type for stream in s.streams)) #if not have_video_call: # NSApp.delegate().contactsWindowController.showLocalVideoWindow() frame = videoIcon.frame() typeCount+= 1 frame.origin.x = NSMaxX(view.frame()) - 10 - (NSWidth(frame) + 10) * typeCount videoIcon.setFrame_(frame) videoIcon.setHidden_(False) is_file_transfer = False if 'file-transfer' in stream_types: is_file_transfer = True frame = fileIcon.frame() typeCount+= 1 frame.origin.x = NSMaxX(view.frame()) - 10 - (NSWidth(frame) + 10) * typeCount fileIcon.setFrame_(frame) fileIcon.setHidden_(False) if settings.file_transfer.auto_accept and NSApp.delegate().contactsWindowController.my_device_is_active: BlinkLogger().log_info(u"Auto answer enabled for file transfers from known contacts") self.enableAutoAnswer(view, session, random.uniform(10, 20)) self.sessionsListView.addSubview_(view) frame = self.sessionsListView.frame() frame.origin.y = self.extraHeight - 14 frame.size.height = self.sessionsListView.minimumHeight() self.sessionsListView.setFrame_(frame) height = frame.size.height + self.extraHeight size = NSMakeSize(NSWidth(self.panel.frame()), height) screenSize = NSScreen.mainScreen().frame().size if size.height > (screenSize.height * 2) / 3: size.height = (screenSize.height * 2) / 3 frame = self.panel.frame() frame.size.height = size.height frame.size.height = NSHeight(self.panel.frameRectForContentRect_(frame)) self.panel.setFrame_display_animate_(frame, True, True) self.sessionsListView.relayout() acceptButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(0)) rejectButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(2)) busyButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(3)) # no Busy or partial accept option for Stream Update Proposals busyButton.setHidden_(is_update_proposal or is_file_transfer) accepyOnlyButton.setHidden_(is_update_proposal) if is_file_transfer: busyButton.setAttributedTitle_("") if is_update_proposal: subject, only_button_title, only_button_object = self.format_subject_for_incoming_reinvite(session, streams) only_button_title = "" else: subject, only_button_title, only_button_object = self.format_subject_for_incoming_invite(session, streams) subjectLabel.setStringValue_(subject) accepyOnlyButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(only_button_object)) frame = subjectLabel.frame() frame.size.width = NSWidth(self.sessionsListView.frame()) - 80 - 40 * typeCount subjectLabel.setFrame_(frame) has_audio_streams = any(s for s in reduce(lambda a,b:a+b, [session.proposed_streams for session in self.sessions.keys()], []) if s.type=="audio") caller_contact = NSApp.delegate().contactsWindowController.getFirstContactMatchingURI(session.remote_identity.uri) if caller_contact: if caller_contact.icon: callerIcon.setImage_(caller_contact.icon) if not is_update_proposal and caller_contact.auto_answer and NSApp.delegate().contactsWindowController.my_device_is_active: if has_audio_streams: if not NSApp.delegate().contactsWindowController.has_audio: BlinkLogger().log_info(u"Auto answer enabled for this contact") video_requested = any(s for s in session.blink_supported_streams if s.type == "video") if video_requested and not settings.video.enable_when_auto_answer: blink_supported_streams = [s for s in session.blink_supported_streams if s.type != "video"] session.blink_supported_streams = blink_supported_streams self.enableAutoAnswer(view, session, session.account.audio.answer_delay) else: video_requested = any(s for s in session.blink_supported_streams if s.type == "video") if video_requested and not settings.video.enable_when_auto_answer: blink_supported_streams = [s for s in session.blink_supported_streams if s.type != "video"] session.blink_supported_streams = blink_supported_streams BlinkLogger().log_info(u"Auto answer enabled for this contact") self.enableAutoAnswer(view, session, session.account.audio.answer_delay) fromLabel.setStringValue_(u"%s" % format_identity_to_string(session.remote_identity, check_contact=True, format='full')) fromLabel.sizeToFit() if has_audio_streams: outdev = settings.audio.output_device indev = settings.audio.input_device if outdev == u"system_default": outdev = SIPManager()._app.engine.default_output_device if indev == u"system_default": indev = SIPManager()._app.engine.default_input_device outdev = outdev.strip() if outdev is not None else 'None' indev = indev.strip() if indev is not None else 'None' if outdev != indev: if indev.startswith('Built-in Mic') and outdev.startswith(u'Built-in Out'): self.deviceLabel.setStringValue_(NSLocalizedString("Using Built-in Microphone and Output", "Label")) else: self.deviceLabel.setStringValue_(NSLocalizedString("Using %s for output ", "Label") % outdev.strip() + NSLocalizedString(" and %s for input", "Label") % indev.strip()) else: self.deviceLabel.setStringValue_(NSLocalizedString("Using audio device", "Label") + " " + outdev.strip()) BlinkLogger().log_info(u"Using input/output audio devices: %s/%s" % (indev.strip(), outdev.strip())) self.deviceLabel.sizeToFit() self.deviceLabel.setHidden_(False) else: self.deviceLabel.setHidden_(True) acceptButton.setTitle_(NSLocalizedString("Accept", "Button title")) accepyOnlyButton.setTitle_(only_button_title or "") if False and sum(a.enabled for a in AccountManager().iter_accounts())==1: accountLabel.setHidden_(True) else: accountLabel.setHidden_(False) if isinstance(session.account, BonjourAccount): accountLabel.setStringValue_(NSLocalizedString("To Bonjour account", "Label")) else: to = format_identity_to_string(session.account) accountLabel.setStringValue_(NSLocalizedString("To %s", "Label") % to) accountLabel.sizeToFit() if len(self.sessions) == 1: self.acceptAllButton.setTitle_(NSLocalizedString("Accept", "Button title")) self.acceptAllButton.setHidden_(False) self.acceptButton.setTitle_(only_button_title or "") self.acceptButton.setHidden_(not only_button_title) self.rejectButton.setTitle_(NSLocalizedString("Reject", "Button title")) self.acceptAllButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(0)) self.rejectButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(2)) self.busyButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(3)) self.acceptButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(only_button_object)) self.answeringMachineButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(4)) self.conferenceButton.cell().setRepresentedObject_(NSNumber.numberWithInt_(5)) self.busyButton.setHidden_(is_update_proposal or is_file_transfer) for i in (5, 6, 7, 8): view.viewWithTag_(i).setHidden_(True) else: self.acceptAllButton.setHidden_(False) self.acceptAllButton.setTitle_(NSLocalizedString("Accept All", "Button title")) self.acceptButton.setHidden_(True) self.busyButton.setHidden_(is_update_proposal or is_file_transfer) self.rejectButton.setTitle_(NSLocalizedString("Reject All", "Button title")) for v in self.sessions.values(): for i in (5, 6, 7, 8): btn = v.viewWithTag_(i) btn.setHidden_(len(btn.attributedTitle()) == 0) if not has_audio_streams or is_update_proposal: self.answeringMachineButton.setHidden_(True) else: self.answeringMachineButton.setHidden_(not settings.answering_machine.show_in_alert_panel) if not self.isConferencing: self.conferenceButton.setHidden_(True) else: self.conferenceButton.setHidden_(False)
class BlinkAppDelegate(NSObject): """Responsible for starting and stopping the application Register URL types handled by Blink Updating the dock icon with missed calls Migrating data from one version to another Start enrollment if run first time Calling Initial SIP URL if necessary Handle wake up from sleep Show about panel""" contactsWindowController = objc.IBOutlet() chatWindowController = objc.IBOutlet() debugWindow = objc.IBOutlet() aboutPanel = objc.IBOutlet() migrationPanel = objc.IBOutlet() migrationText = objc.IBOutlet() migrationProgressWheel = objc.IBOutlet() aboutVersion = objc.IBOutlet() aboutSlogan = objc.IBOutlet() aboutCopyright = objc.IBOutlet() aboutIcon = objc.IBOutlet() aboutzRTPIcon = objc.IBOutlet() ui_notification_center = None application_will_end = False wake_up_timestamp = None ip_change_timestamp = None transport_lost_timestamp = None debug = False blinkMenu = objc.IBOutlet() ready = False missedCalls = 0 missedChats = 0 urisToOpen = [] wait_for_enrollment = False updater = None # branding about_version = "1.0" about_slogan = "A state of the art, easy to use SIP client" help_url = "http://help-pro.icanblink.com" last_history_entries = 10 allowed_domains = [] icloud_enabled = False answering_machine_enabled = True history_enabled = True recording_enabled = True file_logging_enabled = True advanced_options_enabled = True hidden_account_preferences_sections = () chat_replication_password_hidden = True external_alert_enabled = True migrate_passwords_to_keychain = True service_provider_help_url = None service_provider_name = None maximum_accounts = None account_extension = None sp_update_url = None main_window_title = None call_transfer_enabled = True phone_numbers_enabled = True ldap_directory_enabled = True chat_print_enabled = True pause_music_enabled = True about_image = 'about' account_extension = None general_extension = None supported_languages = { "system_default": NSLocalizedString("System Default", "Menu item"), "en": NSLocalizedString("English", "Menu item"), "nl": NSLocalizedString("Nederlands", "Menu item"), "es": NSLocalizedString("Spanish", "Menu item"), "ro": NSLocalizedString("Romanian", "Menu item"), "pt": NSLocalizedString("Portuguese", "Menu item") } statusbar_menu_icon = 'invisible' about_copyright = "Copyright 2009-2021 AG Projects" active_transports = set() terminating = False @objc.python_method @property def video_devices(self): devices = set() for item in Engine().video_devices: if 'colorbar' in item.lower(): continue if 'null' in item.lower(): continue devices.add(item) return list(devices) def init(self): self = objc.super(BlinkAppDelegate, self).init() if self: self.applicationName = str(NSBundle.mainBundle().infoDictionary().objectForKey_("CFBundleExecutable")) self.applicationNamePrint = str(NSBundle.mainBundle().infoDictionary().objectForKey_("CFBundleName")) build = str(NSBundle.mainBundle().infoDictionary().objectForKey_("CFBundleVersion")) date = str(NSBundle.mainBundle().infoDictionary().objectForKey_("BlinkVersionDate")) branding_file = NSBundle.mainBundle().infoDictionary().objectForKey_("BrandingFile") try: branding = __import__(branding_file) except ImportError: try: import branding except ImportError: branding = Null branding.init(self) BlinkLogger().log_info("Starting %s %s" % (self.applicationNamePrint, build)) self.registerURLHandler() NSWorkspace.sharedWorkspace().notificationCenter().addObserver_selector_name_object_(self, "computerDidWake:", NSWorkspaceDidWakeNotification, None) NSWorkspace.sharedWorkspace().notificationCenter().addObserver_selector_name_object_(self, "computerWillSleep:", NSWorkspaceWillSleepNotification, None) NSDistributedNotificationCenter.defaultCenter().addObserver_selector_name_object_suspensionBehavior_(self, "callFromAddressBook:", "CallTelephoneNumberWithBlinkFromAddressBookNotification", "AddressBook", NSNotificationSuspensionBehaviorDeliverImmediately) NSDistributedNotificationCenter.defaultCenter().addObserver_selector_name_object_suspensionBehavior_(self, "callFromAddressBook:", "CallSipAddressWithBlinkFromAddressBookNotification", "AddressBook", NSNotificationSuspensionBehaviorDeliverImmediately) NotificationCenter().add_observer(self, name="CFGSettingsObjectDidChange") NotificationCenter().add_observer(self, name="SIPApplicationDidStart") NotificationCenter().add_observer(self, name="SIPApplicationWillEnd") NotificationCenter().add_observer(self, name="SIPApplicationDidEnd") NotificationCenter().add_observer(self, name="NetworkConditionsDidChange") NotificationCenter().add_observer(self, name="SIPEngineTransportDidDisconnect") NotificationCenter().add_observer(self, name="SIPEngineTransportDidConnect") NotificationCenter().add_observer(self, name="DNSNameserversDidChange") NotificationCenter().add_observer(self, name="SystemDidWakeUpFromSleep") # remove obsolete settings userdef = NSUserDefaults.standardUserDefaults() userdef.removeObjectForKey_('SIPTrace') userdef.removeObjectForKey_('MSRPTrace') userdef.removeObjectForKey_('XCAPTrace') userdef.removeObjectForKey_('EnablePJSIPTrace') userdef.removeObjectForKey_('EnableNotificationsTrace') try: from Updater import Updater except ImportError: pass else: self.updater = Updater() self.purge_temporary_files() return self @objc.python_method @run_in_thread('file-io') def purge_temporary_files(self): for dir in ('.tmp_screenshots', '.tmp_snapshots', '.tmp_file_transfers'): folder = ApplicationData.get(dir) if os.path.exists(folder): try: shutil.rmtree(folder) except EnvironmentError: pass @objc.python_method def gui_notify(self, title, body, subtitle=None): if self.application_will_end: return major, minor = platform.mac_ver()[0].split('.')[0:2] if (int(major) == 10 and int(minor) >= 8) or int(major) > 10: if self.ui_notification_center is None: self.ui_notification_center = Foundation.NSUserNotificationCenter.defaultUserNotificationCenter() self.ui_notification_center.setDelegate_(self) notification = Foundation.NSUserNotification.alloc().init() notification.setTitle_(title) if subtitle is not None: notification.setSubtitle_(subtitle) notification.setInformativeText_(body) self.ui_notification_center.scheduleNotification_(notification) def userNotificationCenter_didDeliverNotification_(self, center, notification): pass def userNotificationCenter_didActivateNotification_(self, center, notification): pass def userNotificationCenter_shouldPresentNotification_(self, center, notification): return True # Needed by run_in_gui_thread and call_in_gui_thread def callObject_(self, callable): try: callable() except: log.err() # Needed by call_later def callTimerObject_(self, timer): callable = timer.userInfo() try: callable() except: log.err() @objc.python_method def enroll(self): enroll = EnrollmentController.alloc().init() enroll.setCreateAccount() enroll.runModal() @objc.python_method def updateDockTile(self): if self.missedCalls > 0 or self.missedChats > 0: icon = NSImage.imageNamed_("Blink") image = NSImageView.alloc().initWithFrame_(NSMakeRect(0, 0, 32, 32)) image.setImage_(icon) if self.missedCalls > 0 and self.missedChats > 0: NSApp.dockTile().setBadgeLabel_("%i / %i" % (self.missedCalls, self.missedChats)) else: NSApp.dockTile().setBadgeLabel_("%i" % (self.missedCalls + self.missedChats)) NSApp.dockTile().setContentView_(image) else: NSApp.dockTile().setBadgeLabel_("") NSApp.dockTile().setContentView_(None) icon = None NSApp.setApplicationIconImage_(icon) NSApp.dockTile().display() @objc.python_method def noteNewMessage(self, window): if not NSApp.isActive(): self.missedChats += 1 self.updateDockTile() @objc.python_method def noteMissedCall(self): self.missedCalls += 1 self.updateDockTile() NSApp.requestUserAttention_(NSInformationalRequest) def applicationShouldHandleReopen_hasVisibleWindows_(self, sender, flag): if not flag: self.contactsWindowController.showWindow_(None) self.missedCalls = 0 self.missedChats = 0 self.updateDockTile() return False def applicationDidBecomeActive_(self, notif): self.missedCalls = 0 self.missedChats = 0 self.updateDockTile() def applicationDidFinishLaunching_(self, sender): BlinkLogger().log_debug("Application launched") branding_file = NSBundle.mainBundle().infoDictionary().objectForKey_("BrandingFile") try: branding = __import__(branding_file) except ImportError: try: import branding except ImportError: branding = Null branding.setup(self) if self.updater and self.sp_update_url is not None: self.updater.sp.setFeedURL_(NSURL.URLWithString_(self.sp_update_url)) self.blinkMenu.setTitle_(self.applicationNamePrint) config_file = ApplicationData.get('config') self.icloud_manager = iCloudManager() self.backend = SIPManager() self.contactsWindowController.setup(self.backend) while True: try: first_run = not os.path.exists(config_file) self.contactsWindowController.first_run = first_run self.backend.init() self.backend.fetch_account() accounts = AccountManager().get_accounts() if not accounts or (first_run and accounts == [BonjourAccount()]): self.wait_for_enrollment = True self.enroll() break except FileParserError as exc: BlinkLogger().log_warning("Error parsing configuration file: %s" % exc) if NSRunAlertPanel(NSLocalizedString("Error", "Window title"), NSLocalizedString("The configuration file is corrupted. You will need to replace it and re-enter your account information. \n\nYour current configuration file will be backed up to %s.corrupted. ", "Label") % config_file, NSLocalizedString("Replace", "Button title"), NSLocalizedString("Quit", "Button title"), None) != NSAlertDefaultReturn: NSApp.terminate_(None) return os.rename(config_file, config_file+".corrupted") BlinkLogger().log_info("Renamed configuration file to %s" % config_file+".corrupted") except BaseException as exc: import traceback print(traceback.print_exc()) NSRunAlertPanel(NSLocalizedString("Error", "Window title"), NSLocalizedString("There was an error during startup of core functionality:\n%s", "Label") % exc, NSLocalizedString("Quit", "Button title"), None, None) NSApp.terminate_(None) return # window should be shown only after enrollment check if self.wait_for_enrollment: BlinkLogger().log_info('Starting User Interface') self.contactsWindowController.model.moveBonjourGroupFirst() self.contactsWindowController.showWindow_(None) self.wait_for_enrollment = False self.contactsWindowController.setupFinished() SMSWindowManager.SMSWindowManager().setOwner_(self.contactsWindowController) self.debugWindow = DebugWindow.alloc().init() self.chatWindowController = ChatWindowController.ChatWindowController.alloc().init() def killSelfAfterTimeout_(self, arg): time.sleep(15) BlinkLogger().log_info("Application forcefully terminated because core engine did not be stop in a timely manner") os._exit(0) def applicationShouldTerminate_(self, sender): if self.terminating: return True self.terminating = True BlinkLogger().log_info('Application will be terminated') NSThread.detachNewThreadSelector_toTarget_withObject_("killSelfAfterTimeout:", self, None) NotificationCenter().post_notification("BlinkShouldTerminate", None) NotificationCenter().add_observer(self, name="SIPApplicationDidEnd") app = SIPApplication() app.stop() import Profiler Profiler.stop(os.path.join(ApplicationData.directory, 'logs', 'profiler.stats')) return False @objc.python_method @run_in_gui_thread def handle_notification(self, notification): handler = getattr(self, '_NH_%s' % notification.name, Null) handler(notification) @objc.python_method def _NH_SIPEngineTransportDidDisconnect(self, notification): self.transport_lost_timestamp = int(time.time()) transport = '%s:%s' % (notification.data.transport, notification.data.remote_address) try: self.active_transports.remove(transport) except KeyError: return for account_info in self.contactsWindowController.accounts: account = account_info.account if account is BonjourAccount(): continue if not account.enabled: continue if account_info.registrar != transport: continue account_info.register_state = 'failed' if host is None or host.default_ip is None: account_info.register_failure_reason = NSLocalizedString("No Internet connection", "Label") else: account_info.register_failure_reason = NSLocalizedString("Connection failed", "Label") self.contactsWindowController.refreshAccountList() BlinkLogger().log_info('Re-register account %s' % account.id) account.reregister() account.resubscribe() presence_state = account.presence_state account.presence_state = None account.presence_state = presence_state if notification.data.reason != 'Success': BlinkLogger().log_info("%s connection %s <-> %s lost" % (notification.data.transport, notification.data.local_address, notification.data.remote_address)) #nc_title = NSLocalizedString("Connection failed", "Label") #nc_body = NSLocalizedString("Remote Address", "Label") + " %s:%s" % (notification.data.transport, notification.data.remote_address) #self.gui_notify(nc_title, nc_body) else: NotificationCenter().post_notification("BlinkTransportFailed", data=NotificationData(transport=transport)) @objc.python_method def _NH_SIPEngineTransportDidConnect(self, notification): transport = "%s:%s" %(notification.data.transport, notification.data.remote_address) if transport not in self.active_transports: BlinkLogger().log_info("%s connection %s <-> %s established" % (notification.data.transport, notification.data.local_address, notification.data.remote_address)) self.active_transports.add(transport) @objc.python_method def _NH_DNSNameserversDidChange(self, notification): BlinkLogger().log_info("DNS servers changed to %s" % ", ".join(notification.data.nameservers)) @objc.python_method def _NH_NetworkConditionsDidChange(self, notification): self.ip_change_timestamp = int(time.time()) BlinkLogger().log_info("Network conditions changed") if host.default_ip is None: BlinkLogger().log_info("No IP address") else: BlinkLogger().log_info("IP address changed to %s" % host.default_ip) @objc.python_method def _NH_SIPApplicationWillEnd(self, notification): BlinkLogger().log_info("Core engine will be stopped") self.purge_temporary_files() @objc.python_method def _NH_CFGSettingsObjectDidChange(self, notification): if 'gui.extended_debug' in notification.data.modified: settings = SIPSimpleSettings() self.debug = settings.gui.extended_debug @objc.python_method def _NH_SIPApplicationDidStart(self, notification): settings = SIPSimpleSettings() self.debug = settings.gui.extended_debug self.purge_temporary_files() @objc.python_method def _NH_SIPApplicationDidEnd(self, notification): BlinkLogger().log_info("Core engine stopped") NSApp.terminate_(self) def applicationWillTerminate_(self, notification): NotificationCenter().post_notification("BlinkWillTerminate", None) BlinkLogger().log_info("Application ended") def computerDidWake_(self, notification): self.wake_up_timestamp = int(time.time()) NotificationCenter().post_notification("SystemDidWakeUpFromSleep", None) def computerWillSleep_(self, notification): NotificationCenter().post_notification("SystemWillSleep", None) def callFromAddressBook_(self, notification): url = notification.userInfo()["URI"] name = notification.userInfo()["DisplayName"] url = self.normalizeExternalURL(url) BlinkLogger().log_info("Will start outgoing session to %s %s from Address Book" % (name, url)) if not self.ready: self.urisToOpen.append((str(url), ('audio'), list())) else: self.contactsWindowController.joinConference(str(url), ('audio')) @objc.IBAction def orderFrontAboutPanel_(self, sender): if not self.aboutPanel: NSBundle.loadNibNamed_owner_("About", self) self.aboutVersion.setStringValue_(self.about_version) self.aboutSlogan.setStringValue_(self.about_slogan) self.aboutIcon.setImage_(NSImage.imageNamed_(self.about_image)) self.aboutCopyright.setStringValue_(self.about_copyright) self.aboutPanel.makeKeyAndOrderFront_(None) @objc.python_method def normalizeExternalURL(self, url): return external_url_pattern.sub("", url) def getURL_withReplyEvent_(self, event, replyEvent): participants = set() media_type = set() url = event.descriptorForKeyword_(fourcharToInt('----')).stringValue() url = self.normalizeExternalURL(url) BlinkLogger().log_info("Will start outgoing session from external link: %s" % url) url = urllib.parse.unquote(url).replace(" ", "") _split = url.split(';') _url = [] for item in _split[:]: if item.startswith("participant="): puri = item.split("=")[1] participants.add(puri) elif item.startswith("media_type="): m = item.split("=")[1] media_type.add(m) else: _url.append(item) _split.remove(item) url = ";".join(_url) if not self.ready: self.urisToOpen.append((str(url), list(media_type), list(participants))) else: self.contactsWindowController.joinConference(str(url), list(media_type), list(participants)) @objc.python_method def registerURLHandler(self): event_class = event_id = fourcharToInt("GURL") event_manager = NSAppleEventManager.sharedAppleEventManager() event_manager.setEventHandler_andSelector_forEventClass_andEventID_(self, "getURL:withReplyEvent:", event_class, event_id) bundleID = NSBundle.mainBundle().bundleIdentifier() LaunchServices.LSSetDefaultHandlerForURLScheme("sip", bundleID) LaunchServices.LSSetDefaultHandlerForURLScheme("tel", bundleID)
def applicationDidFinishLaunching_(self, sender): BlinkLogger().log_debug("Application launched") branding_file = NSBundle.mainBundle().infoDictionary().objectForKey_("BrandingFile") try: branding = __import__(branding_file) except ImportError: try: import branding except ImportError: branding = Null branding.setup(self) if self.updater and self.sp_update_url is not None: self.updater.sp.setFeedURL_(NSURL.URLWithString_(self.sp_update_url)) self.blinkMenu.setTitle_(self.applicationNamePrint) config_file = ApplicationData.get('config') self.icloud_manager = iCloudManager() self.backend = SIPManager() self.contactsWindowController.setup(self.backend) while True: try: first_run = not os.path.exists(config_file) self.contactsWindowController.first_run = first_run self.backend.init() self.backend.fetch_account() accounts = AccountManager().get_accounts() if not accounts or (first_run and accounts == [BonjourAccount()]): self.wait_for_enrollment = True self.enroll() break except FileParserError as exc: BlinkLogger().log_warning("Error parsing configuration file: %s" % exc) if NSRunAlertPanel(NSLocalizedString("Error", "Window title"), NSLocalizedString("The configuration file is corrupted. You will need to replace it and re-enter your account information. \n\nYour current configuration file will be backed up to %s.corrupted. ", "Label") % config_file, NSLocalizedString("Replace", "Button title"), NSLocalizedString("Quit", "Button title"), None) != NSAlertDefaultReturn: NSApp.terminate_(None) return os.rename(config_file, config_file+".corrupted") BlinkLogger().log_info("Renamed configuration file to %s" % config_file+".corrupted") except BaseException as exc: import traceback print(traceback.print_exc()) NSRunAlertPanel(NSLocalizedString("Error", "Window title"), NSLocalizedString("There was an error during startup of core functionality:\n%s", "Label") % exc, NSLocalizedString("Quit", "Button title"), None, None) NSApp.terminate_(None) return # window should be shown only after enrollment check if self.wait_for_enrollment: BlinkLogger().log_info('Starting User Interface') self.contactsWindowController.model.moveBonjourGroupFirst() self.contactsWindowController.showWindow_(None) self.wait_for_enrollment = False self.contactsWindowController.setupFinished() SMSWindowManager.SMSWindowManager().setOwner_(self.contactsWindowController) self.debugWindow = DebugWindow.alloc().init() self.chatWindowController = ChatWindowController.ChatWindowController.alloc().init()
def validateAddAccountButton(self): if self.addButton: self.addButton.setEnabled_(SIPManager().validateAddAccountAction())
def createNewAccount(self): sip_address = None display_name = str(self.newDisplayNameText.stringValue().strip()) username = str(self.newUsernameText.stringValue().strip()) password = str(self.newPasswordText.stringValue().strip()) email = str(self.newEmailText.stringValue()) self.progressIndicator.setHidden_(False) self.domainButton.setHidden_(True) self.progressText.setHidden_(False) self.progressIndicator.setUsesThreadedAnimation_(True) self.progressIndicator.startAnimation_(None) self.window.display() url = SIPSimpleSettings().server.enrollment_url sip_address = None tzname = datetime.datetime.now(tzlocal()).tzname() or "" if not tzname: BlinkLogger().log_warning("Unable to determine timezone") values = {'password' : password.encode("utf8"), 'username' : username.encode("utf8"), 'email' : email.encode("utf8"), 'display_name' : display_name.encode("utf8"), 'tzinfo' : tzname } BlinkLogger().log_info("Requesting creation of a new SIP account at %s" % url) data = urllib.parse.urlencode(values) req = urllib.request.Request(url, data.encode("utf-8")) try: raw_response = urllib.request.urlopen(req) except urllib.error.URLError as e: error_message = NSLocalizedString("Cannot connect to enrollment server: %s", "Enrollment panel label") % e except urllib.error.HTTPError as e: error_message = NSLocalizedString("Error from enrollment server: %s", "Enrollment panel label") % e else: raw_data = raw_response.read().decode().replace('\\/', '/') try: json_data = json.loads(raw_data) except (TypeError, json.decoder.JSONDecodeError): error_message = NSLocalizedString("Cannot decode data from enrollment server", "Enrollment panel label") else: try: success = json_data["success"] except (TypeError, KeyError): success = False if not success: BlinkLogger().log_info("Enrollment Server failed to create SIP account") try: error_message = json_data["error_message"] except (TypeError, KeyError): error_message == 'Cannot read server response' else: BlinkLogger().log_info("Enrollment Server successfully created SIP account") data = defaultdict(lambda: None, json_data) tls_path = None if data['passport'] is None else SIPManager().save_certificates(data) sip_address = data['sip_address'] try: outbound_proxy = data['outbound_proxy'] except KeyError: outbound_proxy = None try: xcap_root = data['xcap_root'] except KeyError: xcap_root = None try: msrp_relay = data['msrp_relay'] except KeyError: msrp_relay = None try: settings_url = data['settings_url'] except KeyError: settings_url = None try: web_alert_url = data['web_alert_url'] except KeyError: web_alert_url = None try: web_password = data['web_password'] except KeyError: web_password = None try: conference_server = data['conference_server'] except KeyError: conference_server = None try: ldap_hostname = data['ldap_hostname'] except KeyError: ldap_hostname = None try: ldap_transport = data['ldap_transport'] except KeyError: ldap_transport = None try: ldap_port = data['ldap_port'] except KeyError: ldap_port = None try: ldap_username = data['ldap_username'] except KeyError: ldap_username = None try: ldap_password = data['ldap_password'] except KeyError: ldap_password = None try: ldap_dn = data['ldap_dn'] except KeyError: ldap_dn = None self.progressIndicator.stopAnimation_(None) self.progressIndicator.setHidden_(True) self.progressText.setHidden_(True) self.domainButton.setHidden_(False) if sip_address is None: BlinkLogger().log_info(error_message) NSRunAlertPanel(NSLocalizedString("Sign Up to SIP Account", "Window title"), NSLocalizedString("Error creating SIP account: %s", "Label") % error_message, NSLocalizedString("OK", "Button title"), None, None) return False try: account = Account(str(sip_address)) except ValueError as e: NSRunAlertPanel(NSLocalizedString("Sign Up to SIP Account", "Window title"), NSLocalizedString("Cannot add SIP Account: %s", "Label") % e, NSLocalizedString("OK", "Button title"), None, None) return False else: NSApp.delegate().contactsWindowController.created_accounts.add(account.id) account.display_name = display_name account.auth.password = password account.nat_traversal.use_ice = True account.rtp.srtp_encryption = 'optional' if tls_path: account.tls.certificate = tls_path account.sip.outbound_proxy = outbound_proxy account.xcap.xcap_root = xcap_root account.nat_traversal.msrp_relay = msrp_relay if settings_url: account.server.settings_url = settings_url if web_alert_url: account.web_alert.alert_url = web_alert_url if web_password: account.server.web_password = web_password if conference_server: account.conference.server_address = conference_server if ldap_hostname: account.ldap.enabled = True account.ldap.hostname = ldap_hostname account.ldap.dn = ldap_dn account.ldap.username = ldap_username if ldap_password: account.ldap.password = ldap_password if ldap_transport: account.ldap.transport = ldap_transport if ldap_port: account.ldap.port = ldap_port sync_with_icloud = bool(self.syncWithiCloudCheckbox.state()) account.gui.sync_with_icloud = sync_with_icloud account.save() NSRunAlertPanel(NSLocalizedString("SIP Account Created", "Window title"), NSLocalizedString("Your new SIP Address is:\n\n%s", "Label") % sip_address, NSLocalizedString("Continue", "Button title"), None, None) # enable account only after Continue pressed to give server time to update account.enabled = True account.save() AccountManager().default_account = account return True
class BlinkAppDelegate(NSObject): '''Responsable for starting and stoping the application Register URL types handled by Blink Updating the dock icon with missed calls Migrating data from one version to another Start enrollment if run first time Calling Initial SIP URL if necessary Handle wakeup from sleep Show about panel''' implements(IObserver) contactsWindowController = objc.IBOutlet() aboutPanel = objc.IBOutlet() migrationPanel = objc.IBOutlet() migrationText = objc.IBOutlet() migrationProgressWheel = objc.IBOutlet() aboutVersion = objc.IBOutlet() aboutBundle = objc.IBOutlet() aboutSlogan = objc.IBOutlet() aboutCopyright = objc.IBOutlet() aboutzRTPIcon = objc.IBOutlet() ui_notification_center = None application_will_end = False wake_up_timestamp = None debug = False blinkMenu = objc.IBOutlet() ready = False missedCalls = 0 missedChats = 0 urisToOpen = [] wait_for_enrollment = False updater = None def init(self): self = super(BlinkAppDelegate, self).init() if self: self.applicationName = str(NSBundle.mainBundle().infoDictionary().objectForKey_("CFBundleExecutable")) self.applicationNamePrint = str(NSBundle.mainBundle().infoDictionary().objectForKey_("CFBundleName")) build = str(NSBundle.mainBundle().infoDictionary().objectForKey_("CFBundleVersion")) date = str(NSBundle.mainBundle().infoDictionary().objectForKey_("BlinkVersionDate")) BlinkLogger().log_info(u"Starting %s build %s from %s" % (self.applicationNamePrint, build, date)) self.registerURLHandler() NSWorkspace.sharedWorkspace().notificationCenter().addObserver_selector_name_object_(self, "computerDidWake:", NSWorkspaceDidWakeNotification, None) NSWorkspace.sharedWorkspace().notificationCenter().addObserver_selector_name_object_(self, "computerWillSleep:", NSWorkspaceWillSleepNotification, None) NSDistributedNotificationCenter.defaultCenter().addObserver_selector_name_object_suspensionBehavior_(self, "callFromAddressBook:", "CallTelephoneNumberWithBlinkFromAddressBookNotification", "AddressBook", NSNotificationSuspensionBehaviorDeliverImmediately) NSDistributedNotificationCenter.defaultCenter().addObserver_selector_name_object_suspensionBehavior_(self, "callFromAddressBook:", "CallSipAddressWithBlinkFromAddressBookNotification", "AddressBook", NSNotificationSuspensionBehaviorDeliverImmediately) NotificationCenter().add_observer(self, name="CFGSettingsObjectDidChange") NotificationCenter().add_observer(self, name="SIPApplicationDidStart") NotificationCenter().add_observer(self, name="SIPApplicationWillEnd") NotificationCenter().add_observer(self, name="SIPApplicationDidEnd") NotificationCenter().add_observer(self, name="SystemIPAddressDidChange") NotificationCenter().add_observer(self, name="NetworkConditionsDidChange") NotificationCenter().add_observer(self, name="SIPEngineTransportDidDisconnect") NotificationCenter().add_observer(self, name="SIPEngineTransportDidConnect") NotificationCenter().add_observer(self, name="DNSNameserversDidChange") # remove obsolete settings userdef = NSUserDefaults.standardUserDefaults() userdef.removeObjectForKey_('SIPTrace') userdef.removeObjectForKey_('MSRPTrace') userdef.removeObjectForKey_('XCAPTrace') userdef.removeObjectForKey_('EnablePJSIPTrace') userdef.removeObjectForKey_('EnableNotificationsTrace') try: from Updater import Updater except ImportError: pass else: self.updater = Updater() call_in_thread('file-io', self.purge_temporary_files) return self def purge_temporary_files(self): for dir in ('.tmp_screenshots', '.tmp_snapshots', '.tmp_file_transfers'): folder = ApplicationData.get(dir) if os.path.exists(folder): try: shutil.rmtree(folder) except EnvironmentError: pass def gui_notify(self, title, body, subtitle=None): if self.application_will_end: return major, minor = platform.mac_ver()[0].split('.')[0:2] if (int(major) == 10 and int(minor) >= 8) or int(major) > 10: if self.ui_notification_center is None: self.ui_notification_center = Foundation.NSUserNotificationCenter.defaultUserNotificationCenter() self.ui_notification_center.setDelegate_(self) notification = Foundation.NSUserNotification.alloc().init() notification.setTitle_(title) if subtitle is not None: notification.setSubtitle_(subtitle) notification.setInformativeText_(body) self.ui_notification_center.scheduleNotification_(notification) def userNotificationCenter_didDeliverNotification_(self, center, notification): pass def userNotificationCenter_didActivateNotification_(self, center, notification): pass def userNotificationCenter_shouldPresentNotification_(self, center, notification): return True # Needed by run_in_gui_thread and call_in_gui_thread def callObject_(self, callable): try: callable() except: log.err() def enroll(self): enroll = EnrollmentController.alloc().init() enroll.setCreateAccount() enroll.runModal() def updateDockTile(self): if self.missedCalls > 0 or self.missedChats > 0: icon = NSImage.imageNamed_("Blink") image = NSImageView.alloc().initWithFrame_(NSMakeRect(0, 0, 32, 32)) image.setImage_(icon) if self.missedCalls > 0 and self.missedChats > 0: NSApp.dockTile().setBadgeLabel_("%i / %i" % (self.missedCalls, self.missedChats)) else: NSApp.dockTile().setBadgeLabel_("%i" % (self.missedCalls + self.missedChats)) NSApp.dockTile().setContentView_(image) else: NSApp.dockTile().setBadgeLabel_("") NSApp.dockTile().setContentView_(None) icon = None NSApp.setApplicationIconImage_(icon) NSApp.dockTile().display() def noteNewMessage(self, window): if not NSApp.isActive(): self.missedChats += 1 self.updateDockTile() def noteMissedCall(self): self.missedCalls += 1 self.updateDockTile() NSApp.requestUserAttention_(NSInformationalRequest) def applicationShouldHandleReopen_hasVisibleWindows_(self, sender, flag): if not flag: self.contactsWindowController.showWindow_(None) self.missedCalls = 0 self.missedChats = 0 self.updateDockTile() return False def applicationDidBecomeActive_(self, notif): self.missedCalls = 0 self.missedChats = 0 self.updateDockTile() def applicationDidFinishLaunching_(self, sender): self.blinkMenu.setTitle_(self.applicationNamePrint) config_file = ApplicationData.get('config') self.icloud_manager = iCloudManager() self.backend = SIPManager() self.contactsWindowController.setup(self.backend) while True: try: first_run = not os.path.exists(config_file) self.contactsWindowController.first_run = first_run self.backend.init() self.backend.fetch_account() accounts = AccountManager().get_accounts() if not accounts or (first_run and accounts == [BonjourAccount()]): self.wait_for_enrollment = True self.enroll() break except FileParserError, exc: BlinkLogger().log_warning(u"Error parsing configuration file: %s" % exc) if NSRunAlertPanel(NSLocalizedString("Error", "Window title"), NSLocalizedString("The configuration file is corrupted. You will need to replace it and re-enter your account information. \n\nYour current configuration file will be backed up to %s.corrupted. ", "Label") % config_file, NSLocalizedString("Replace", "Button title"), NSLocalizedString("Quit", "Button title"), None) != NSAlertDefaultReturn: NSApp.terminate_(None) return os.rename(config_file, config_file+".corrupted") BlinkLogger().log_info(u"Renamed configuration file to %s" % config_file+".corrupted") except BaseException, exc: import traceback print traceback.print_exc() NSRunAlertPanel(NSLocalizedString("Error", "Window title"), NSLocalizedString("There was an error during startup of core functionality:\n%s", "Label") % exc, NSLocalizedString("Quit", "Button title"), None, None) NSApp.terminate_(None) return
def createNewAccount(self): display_name = unicode(self.newDisplayNameText.stringValue()) username = unicode(self.newUsernameText.stringValue()) password = unicode(self.newPasswordText.stringValue()) email = unicode(self.newEmailText.stringValue()) self.progressIndicator.setHidden_(False) self.progressText.setHidden_(False) self.progressIndicator.setUsesThreadedAnimation_(True) self.progressIndicator.startAnimation_(None) self.window.display() url = SIPSimpleSettings().server.enrollment_url tzname = datetime.datetime.now(tzlocal()).tzname() or "" if not tzname: BlinkLogger().log_warning(u"Unable to determine timezone") values = { 'password': password.encode("utf8"), 'username': username.encode("utf8"), 'email': email.encode("utf8"), 'display_name': display_name.encode("utf8"), 'tzinfo': tzname } BlinkLogger().log_info( u"Requesting creation of a new SIP account at %s" % url) data = urllib.urlencode(values) req = urllib2.Request(url, data) raw_response = urllib2.urlopen(req) json_data = raw_response.read() try: response = cjson.decode(json_data.replace('\\/', '/')) except TypeError: error_message = 'Cannot decode json data from enrollment server' if response: if not response["success"]: BlinkLogger().log_info( u"Enrollment Server failed to create SIP account: %(error_message)s" % response) error_message = response["error_message"] else: BlinkLogger().log_info( u"Enrollment Server successfully created SIP account %(sip_address)s" % response) data = defaultdict(lambda: None, response) tls_path = None if data['passport'] is None else SIPManager( ).save_certificates(data) try: sip_address = data['sip_address'] try: outbound_proxy = data['outbound_proxy'] except KeyError: outbound_proxy = None try: xcap_root = data['xcap_root'] except KeyError: xcap_root = None try: msrp_relay = data['msrp_relay'] except KeyError: msrp_relay = None try: settings_url = data['settings_url'] except KeyError: settings_url = None try: web_alert_url = data['web_alert_url'] except KeyError: web_alert_url = None try: web_password = data['web_password'] except KeyError: web_password = None try: conference_server = data['conference_server'] except KeyError: conference_server = None try: ldap_hostname = data['ldap_hostname'] except KeyError: ldap_hostname = None try: ldap_transport = data['ldap_transport'] except KeyError: ldap_transport = None try: ldap_port = data['ldap_port'] except KeyError: ldap_port = None try: ldap_username = data['ldap_username'] except KeyError: ldap_username = None try: ldap_password = data['ldap_password'] except KeyError: ldap_password = None try: ldap_dn = data['ldap_dn'] except KeyError: ldap_dn = None except KeyError: sip_address = None else: sip_address = None error_message = "No response received from %s" % url self.progressIndicator.stopAnimation_(None) self.progressIndicator.setHidden_(True) self.progressText.setHidden_(True) if not sip_address: NSRunAlertPanel("Sign Up to SIP Account", "Error creating account: %s" % error_message, "OK", None, None) return False try: account = Account(str(sip_address)) except ValueError, e: NSRunAlertPanel("Sign Up to SIP Account", "Cannot add SIP Account: %s" % str(e), "OK", None, None) return False
def unMuteAfterSpeechDidEnd(self): if self.muted_by_synthesizer and SIPManager().is_muted(): NSApp.delegate().contactsWindowController.muteClicked_(None) self.muted_by_synthesizer = False if self.speech_recognizer: self.speech_recognizer.startListening()