예제 #1
0
def createLabelAndList(labelText):
    widget, label = _createLabelInWidget(labelText, QGridLayout)
    buttonGroup = QButtonGroup(widget)
    buttonGroup.setObjectName('buttonGroup')
    buttonGroup.setExclusive(False)
    return (widget, label, buttonGroup)
예제 #2
0
class AddAccountDialog(base_class, ui_class):
    __metaclass__ = QSingleton

    implements(IObserver)

    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))
        font = self.title_label.font()
        font.setPointSizeF(self.info_label.fontInfo().pointSizeF() + 3)
        font.setFamily("Sans Serif")
        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 _get_display_name(self):
        if self.panel_view.currentWidget() is self.add_account_panel:
            return unicode(self.display_name_editor.text())
        else:
            return unicode(self.name_editor.text())

    def _set_display_name(self, value):
        self.display_name_editor.setText(value)
        self.name_editor.setText(value)

    def _get_username(self):
        return unicode(self.username_editor.text())

    def _set_username(self, value):
        self.username_editor.setText(value)

    def _get_sip_address(self):
        return unicode(self.sip_address_editor.text())

    def _set_sip_address(self, value):
        self.sip_address_editor.setText(value)

    def _get_password(self):
        if self.panel_view.currentWidget() is self.add_account_panel:
            return unicode(self.password_editor.text())
        else:
            return unicode(self.new_password_editor.text())

    def _set_password(self, value):
        self.password_editor.setText(value)
        self.new_password_editor.setText(value)

    def _get_verify_password(self):
        return unicode(self.verify_password_editor.text())

    def _set_verify_password(self, value):
        self.verify_password_editor.setText(value)

    def _get_email_address(self):
        return unicode(self.email_address_editor.text())

    def _set_email_address(self, value):
        self.email_address_editor.setText(value)

    display_name = property(_get_display_name, _set_display_name)
    username = property(_get_username, _set_username)
    sip_address = property(_get_sip_address, _set_sip_address)
    password = property(_get_password, _set_password)
    verify_password = property(_get_verify_password, _set_verify_password)
    email_address = property(_get_email_address, _set_email_address)

    del _get_display_name, _set_display_name, _get_username, _set_username
    del _get_sip_address, _set_sip_address, _get_email_address, _set_email_address
    del _get_password, _set_password, _get_verify_password, _set_verify_password

    def _SH_AcceptButtonClicked(self):
        if self.panel_view.currentWidget() is self.add_account_panel:
            account = Account(self.sip_address)
            account.enabled = True
            account.display_name = self.display_name
            account.auth.password = self.password
            call_in_auxiliary_thread(account.save)
            account_manager = AccountManager()
            account_manager.default_account = account
            self.accept()
        else:
            self.setEnabled(False)
            self.create_status_label.value = Status("Creating account on server...")
            self._create_sip_account(self.username, self.password, self.email_address, self.display_name)

    def _SH_PanelChangeRequest(self, index):
        self.panel_view.setCurrentIndex(index)
        if self.panel_view.currentWidget() is self.add_account_panel:
            inputs = [self.display_name_editor, self.sip_address_editor, self.password_editor]
        else:
            inputs = [
                self.name_editor,
                self.username_editor,
                self.new_password_editor,
                self.verify_password_editor,
                self.email_address_editor,
            ]
        self.accept_button.setEnabled(all(input.text_valid for input in inputs))

    def _SH_PasswordTextChanged(self, text):
        self.verify_password_editor.regexp = re.compile(u"^%s$" % re.escape(unicode(text)))

    def _SH_ValidityStatusChanged(self):
        red = "#cc0000"
        # validate the add panel
        if not self.display_name_editor.text_valid:
            self.add_status_label.value = Status("Display name cannot be empty", color=red)
        elif not self.sip_address_editor.text_correct:
            self.add_status_label.value = Status("SIP address should be specified as user@domain", color=red)
        elif not self.sip_address_editor.text_allowed:
            self.add_status_label.value = Status("An account with this SIP address was already added", color=red)
        elif not self.password_editor.text_valid:
            self.add_status_label.value = Status("Password cannot be empty", color=red)
        else:
            self.add_status_label.value = None
        # validate the create panel
        if not self.name_editor.text_valid:
            self.create_status_label.value = Status("Name cannot be empty", color=red)
        elif not self.username_editor.text_correct:
            self.create_status_label.value = Status(
                "Username should have 5 to 32 characters, start with a letter or non-zero digit, contain only letters, digits or .-_ and end with a letter or digit",
                color=red,
            )
        elif not self.username_editor.text_allowed:
            self.create_status_label.value = Status(
                "The username you requested is already taken. Please choose another one and try again.", color=red
            )
        elif not self.new_password_editor.text_valid:
            self.create_status_label.value = Status("Password should contain at least 8 characters", color=red)
        elif not self.verify_password_editor.text_valid:
            self.create_status_label.value = Status("Passwords do not match", color=red)
        elif not self.email_address_editor.text_valid:
            self.create_status_label.value = Status("E-mail address should be specified as user@domain", color=red)
        else:
            self.create_status_label.value = None
        # enable the accept button if everything is valid in the current panel
        if self.panel_view.currentWidget() is self.add_account_panel:
            inputs = [self.display_name_editor, self.sip_address_editor, self.password_editor]
        else:
            inputs = [
                self.name_editor,
                self.username_editor,
                self.new_password_editor,
                self.verify_password_editor,
                self.email_address_editor,
            ]
        self.accept_button.setEnabled(all(input.text_valid for input in inputs))

    def _initialize(self):
        self.display_name = user_info.fullname
        self.username = user_info.username.lower().replace(" ", ".")
        self.sip_address = u""
        self.password = u""
        self.verify_password = u""
        self.email_address = u""

    @run_in_auxiliary_thread
    def _create_sip_account(self, username, password, email_address, display_name, timezone=None):
        red = "#cc0000"
        if timezone is None and sys.platform != "win32":
            try:
                timezone = open("/etc/timezone").read().strip()
            except (OSError, IOError):
                try:
                    timezone = "/".join(os.readlink("/etc/localtime").split("/")[-2:])
                except (OSError, IOError):
                    pass
        enrollment_data = dict(
            username=username.lower().encode("utf-8"),
            password=password.encode("utf-8"),
            email=email_address.encode("utf-8"),
            display_name=display_name.encode("utf-8"),
            tzinfo=timezone,
        )
        try:
            settings = SIPSimpleSettings()
            response = urllib2.urlopen(settings.server.enrollment_url, urllib.urlencode(dict(enrollment_data)))
            response_data = cjson.decode(response.read().replace(r"\/", "/"))
            response_data = defaultdict(lambda: None, response_data)
            if response_data["success"]:
                from blink import Blink

                try:
                    certificate_path = None
                    passport = response_data["passport"]
                    if passport is not None:
                        certificate_path = Blink().save_certificates(
                            response_data["sip_address"], passport["crt"], passport["key"], passport["ca"]
                        )
                except (GNUTLSError, IOError, OSError):
                    pass
                account_manager = AccountManager()
                try:
                    account = Account(response_data["sip_address"])
                except AccountExists:
                    account = account_manager.get_account(response_data["sip_address"])
                account.enabled = True
                account.display_name = display_name
                account.auth.password = password
                account.sip.outbound_proxy = response_data["outbound_proxy"]
                account.nat_traversal.msrp_relay = response_data["msrp_relay"]
                account.xcap.xcap_root = response_data["xcap_root"]
                account.tls.certificate = certificate_path
                account.server.settings_url = response_data["settings_url"]
                account.save()
                account_manager.default_account = account
                call_in_gui_thread(self.accept)
            elif response_data["error"] == "user_exists":
                call_in_gui_thread(self.username_editor.addException, username)
            else:
                call_in_gui_thread(
                    setattr, self.create_status_label, "value", Status(response_data["error_message"], color=red)
                )
        except (cjson.DecodeError, KeyError):
            call_in_gui_thread(setattr, self.create_status_label, "value", Status("Illegal server response", color=red))
        except urllib2.URLError, e:
            call_in_gui_thread(
                setattr, self.create_status_label, "value", Status("Failed to contact server: %s" % e.reason, color=red)
            )
        finally:
예제 #3
0
class AddAccountDialog(base_class, ui_class):
    __metaclass__ = QSingleton

    implements(IObserver)

    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))
        font = self.title_label.font()
        font.setPointSizeF(self.info_label.fontInfo().pointSizeF() + 3)
        font.setFamily("Sans Serif")
        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 _get_display_name(self):
        if self.panel_view.currentWidget() is self.add_account_panel:
            return self.display_name_editor.text()
        else:
            return self.name_editor.text()

    def _set_display_name(self, value):
        self.display_name_editor.setText(value)
        self.name_editor.setText(value)

    def _get_username(self):
        return self.username_editor.text()

    def _set_username(self, value):
        self.username_editor.setText(value)

    def _get_sip_address(self):
        return self.sip_address_editor.text()

    def _set_sip_address(self, value):
        self.sip_address_editor.setText(value)

    def _get_password(self):
        if self.panel_view.currentWidget() is self.add_account_panel:
            return self.password_editor.text()
        else:
            return self.new_password_editor.text()

    def _set_password(self, value):
        self.password_editor.setText(value)
        self.new_password_editor.setText(value)

    def _get_verify_password(self):
        return self.verify_password_editor.text()

    def _set_verify_password(self, value):
        self.verify_password_editor.setText(value)

    def _get_email_address(self):
        return self.email_address_editor.text()

    def _set_email_address(self, value):
        self.email_address_editor.setText(value)

    display_name = property(_get_display_name, _set_display_name)
    username = property(_get_username, _set_username)
    sip_address = property(_get_sip_address, _set_sip_address)
    password = property(_get_password, _set_password)
    verify_password = property(_get_verify_password, _set_verify_password)
    email_address = property(_get_email_address, _set_email_address)

    del _get_display_name, _set_display_name, _get_username, _set_username
    del _get_sip_address, _set_sip_address, _get_email_address, _set_email_address
    del _get_password, _set_password, _get_verify_password, _set_verify_password

    def _SH_AcceptButtonClicked(self):
        if self.panel_view.currentWidget() is self.add_account_panel:
            account = Account(self.sip_address)
            account.enabled = True
            account.display_name = self.display_name or None
            account.auth.password = self.password
            account.save()
            account_manager = AccountManager()
            account_manager.default_account = account
            self.accept()
        else:
            self.setEnabled(False)
            self.create_status_label.value = Status(
                'Creating account on server...')
            self._create_sip_account(self.username, self.password,
                                     self.email_address, self.display_name)

    def _SH_PanelChangeRequest(self, index):
        self.panel_view.setCurrentIndex(index)
        if self.panel_view.currentWidget() is self.add_account_panel:
            inputs = [
                self.display_name_editor, self.sip_address_editor,
                self.password_editor
            ]
        else:
            inputs = [
                self.name_editor, self.username_editor,
                self.new_password_editor, self.verify_password_editor,
                self.email_address_editor
            ]
        self.accept_button.setEnabled(all(input.text_valid
                                          for input in inputs))

    def _SH_PasswordTextChanged(self, text):
        self.verify_password_editor.regexp = re.compile(u'^%s$' %
                                                        re.escape(text))

    def _SH_ValidityStatusChanged(self):
        red = '#cc0000'
        # validate the add panel
        if not self.display_name_editor.text_valid:
            self.add_status_label.value = Status(
                "Display name cannot be empty", color=red)
        elif not self.sip_address_editor.text_correct:
            self.add_status_label.value = Status(
                "SIP address should be specified as user@domain", color=red)
        elif not self.sip_address_editor.text_allowed:
            self.add_status_label.value = Status(
                "An account with this SIP address was already added",
                color=red)
        elif not self.password_editor.text_valid:
            self.add_status_label.value = Status("Password cannot be empty",
                                                 color=red)
        else:
            self.add_status_label.value = None
        # validate the create panel
        if not self.name_editor.text_valid:
            self.create_status_label.value = Status("Name cannot be empty",
                                                    color=red)
        elif not self.username_editor.text_correct:
            self.create_status_label.value = Status(
                "Username should have 5 to 32 characters, start with a letter or non-zero digit, contain only letters, digits or .-_ and end with a letter or digit",
                color=red)
        elif not self.username_editor.text_allowed:
            self.create_status_label.value = Status(
                "The username you requested is already taken. Please choose another one and try again.",
                color=red)
        elif not self.new_password_editor.text_valid:
            self.create_status_label.value = Status(
                "Password should contain at least 8 characters", color=red)
        elif not self.verify_password_editor.text_valid:
            self.create_status_label.value = Status("Passwords do not match",
                                                    color=red)
        elif not self.email_address_editor.text_valid:
            self.create_status_label.value = Status(
                "E-mail address should be specified as user@domain", color=red)
        else:
            self.create_status_label.value = None
        # enable the accept button if everything is valid in the current panel
        if self.panel_view.currentWidget() is self.add_account_panel:
            inputs = [
                self.display_name_editor, self.sip_address_editor,
                self.password_editor
            ]
        else:
            inputs = [
                self.name_editor, self.username_editor,
                self.new_password_editor, self.verify_password_editor,
                self.email_address_editor
            ]
        self.accept_button.setEnabled(all(input.text_valid
                                          for input in inputs))

    def _initialize(self):
        self.display_name = user_info.fullname
        self.username = user_info.username.lower().replace(u' ', u'.')
        self.sip_address = u''
        self.password = u''
        self.verify_password = u''
        self.email_address = u''

    @run_in_thread('network-io')
    def _create_sip_account(self,
                            username,
                            password,
                            email_address,
                            display_name,
                            timezone=None):
        red = '#cc0000'
        if timezone is None and sys.platform != 'win32':
            try:
                timezone = open('/etc/timezone').read().strip()
            except (OSError, IOError):
                try:
                    timezone = '/'.join(
                        os.readlink('/etc/localtime').split('/')[-2:])
                except (OSError, IOError):
                    pass
        enrollment_data = dict(username=username.lower().encode('utf-8'),
                               password=password.encode('utf-8'),
                               email=email_address.encode('utf-8'),
                               display_name=display_name.encode('utf-8'),
                               tzinfo=timezone)
        try:
            settings = SIPSimpleSettings()
            response = urllib2.urlopen(settings.server.enrollment_url,
                                       urllib.urlencode(dict(enrollment_data)))
            response_data = cjson.decode(response.read().replace(r'\/', '/'))
            response_data = defaultdict(lambda: None, response_data)
            if response_data['success']:
                from blink import Blink
                try:
                    certificate_path = None
                    passport = response_data['passport']
                    if passport is not None:
                        certificate_path = Blink().save_certificates(
                            response_data['sip_address'], passport['crt'],
                            passport['key'], passport['ca'])
                except (GNUTLSError, IOError, OSError):
                    pass
                account_manager = AccountManager()
                try:
                    account = Account(response_data['sip_address'])
                except DuplicateIDError:
                    account = account_manager.get_account(
                        response_data['sip_address'])
                account.enabled = True
                account.display_name = display_name or None
                account.auth.password = password
                account.sip.outbound_proxy = response_data['outbound_proxy']
                account.nat_traversal.msrp_relay = response_data['msrp_relay']
                account.xcap.xcap_root = response_data['xcap_root']
                account.tls.certificate = certificate_path
                account.server.conference_server = response_data[
                    'conference_server']
                account.server.settings_url = response_data['settings_url']
                account.save()
                account_manager.default_account = account
                call_in_gui_thread(self.accept)
            elif response_data['error'] == 'user_exists':
                call_in_gui_thread(self.username_editor.addException, username)
            else:
                call_in_gui_thread(
                    setattr, self.create_status_label, 'value',
                    Status(response_data['error_message'], color=red))
        except (cjson.DecodeError, KeyError):
            call_in_gui_thread(setattr, self.create_status_label, 'value',
                               Status('Illegal server response', color=red))
        except urllib2.URLError, e:
            call_in_gui_thread(
                setattr, self.create_status_label, 'value',
                Status('Failed to contact server: %s' % e.reason, color=red))
        finally: