示例#1
0
    def show(self, position=1):
        from blink import Blink
        blink = Blink()
        screen_geometry = blink.desktop().screenGeometry(self)
        available_geometry = blink.desktop().availableGeometry(self)
        main_window_geometry = blink.main_window.geometry()
        main_window_framegeometry = blink.main_window.frameGeometry()

        horizontal_decorations = main_window_framegeometry.width() - main_window_geometry.width()
        vertical_decorations = main_window_framegeometry.height() - main_window_geometry.height()
        width = limit(self.sizeHint().width(), min=self.minimumSize().width(), max=min(self.maximumSize().width(), available_geometry.width()-horizontal_decorations))
        height = limit(self.sizeHint().height(), min=self.minimumSize().height(), max=min(self.maximumSize().height(), available_geometry.height()-vertical_decorations))
        total_width = width + horizontal_decorations
        total_height = height + vertical_decorations
        x = limit(screen_geometry.center().x() - total_width/2, min=available_geometry.left(), max=available_geometry.right()-total_width)
        if position is None:
            y = -1
        elif position % 2 == 0:
            y = screen_geometry.center().y() + (position-1)*total_height/2
        else:
            y = screen_geometry.center().y() - position*total_height/2
        if available_geometry.top() <= y <= available_geometry.bottom() - total_height:
            self.setGeometry(x, y, width, height)
        else:
            self.resize(width, height)

        self.position = position
        super(PendingWatcherDialog, self).show()
 def __new__(cls, value):
     if isinstance(value, (int, long)):
         return log.NamedLevel(limit(value, min=log.level.ALL, max=log.level.NONE))
     elif not isinstance(value, basestring):
         raise TypeError("value must be a string, int or long")
     log_level = value.upper()
     names = [attr.name for attr in log.level.__class__.__dict__.itervalues() if type(attr) is log.NamedLevel]
     if log_level in names:
         return getattr(log.level, log_level)
     try:
         return log.NamedLevel(limit(int(log_level), min=log.level.ALL, max=log.level.NONE))
     except ValueError:
         raise ValueError("invalid log level: %s" % value)
示例#3
0
    def qColor(self):
        r = fmod(self.h, 1.0)
        h = r+1.0 if r < 0.0 else r
        c = limit(self.c, min=0.0, max=1.0)
        y = limit(self.y, min=0.0, max=1.0)

        hs = h * 6.0
        if hs < 1.0:
            th = hs
            tm = self.luma_r + self.luma_g * th
        elif hs < 2.0:
            th = 2.0 - hs
            tm = self.luma_g + self.luma_r * th
        elif hs < 3.0:
            th = hs - 2.0
            tm = self.luma_g + self.luma_b * th
        elif hs < 4.0:
            th = 4.0 - hs
            tm = self.luma_b + self.luma_g * th
        elif hs < 5.0:
            th = hs - 4.0
            tm = self.luma_b + self.luma_r * th
        else:
            th = 6.0 - hs
            tm = self.luma_r + self.luma_b * th

        # calculate RGB channels in the sorted order
        if tm >= y:
            tp = y + y * c * (1.0 - tm) / tm
            to = y + y * c * (th - tm) / tm
            tn = y - (y * c)
        else:
            tp = y + (1.0 - y) * c
            to = y + (1.0 - y) * c * (th - tm) / (1.0 - tm)
            tn = y - (1.0 - y) * c * tm / (1.0 - tm)

        # return RGB channels in the appropriate order
        if hs < 1.0:
            return QColor.fromRgbF(self._igamma(tp), self._igamma(to), self._igamma(tn), self.a)
        elif hs < 2.0:
            return QColor.fromRgbF(self._igamma(to), self._igamma(tp), self._igamma(tn), self.a)
        elif hs < 3.0:
            return QColor.fromRgbF(self._igamma(tn), self._igamma(tp), self._igamma(to), self.a)
        elif hs < 4.0:
            return QColor.fromRgbF(self._igamma(tn), self._igamma(to), self._igamma(tp), self.a)
        elif hs < 5.0:
            return QColor.fromRgbF(self._igamma(to), self._igamma(tn), self._igamma(tp), self.a)
        else:
            return QColor.fromRgbF(self._igamma(tp), self._igamma(tn), self._igamma(to), self.a)
示例#4
0
 def __init__(self, account, uri, display_name, parent=None):
     super(PendingWatcherDialog, self).__init__(parent)
     self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
     self.setAttribute(Qt.WA_DeleteOnClose)
     with Resources.directory:
         self.setupUi(self)
     default_font_size = self.uri_label.fontInfo().pointSizeF()
     name_font_size = limit(default_font_size + 3, max=14)
     font = self.name_label.font()
     font.setPointSizeF(name_font_size)
     self.name_label.setFont(font)
     addressbook_manager = addressbook.AddressbookManager()
     try:
         self.contact = next(contact for contact in addressbook_manager.get_contacts() if uri in (addr.uri for addr in contact.uris))
     except StopIteration:
         self.contact = None
     else:
         display_name = self.contact.name
         icon_manager = IconManager()
         icon = icon_manager.get(self.contact.id)
         if icon is not None:
             self.user_icon.setPixmap(icon.pixmap(48))
     self.description_label.setText(u'Wants to subscribe to your availability information at {}'.format(account.id))
     self.name_label.setText(display_name or uri)
     self.uri_label.setText(uri)
     self.accept_button.released.connect(self._accept_watcher)
     self.block_button.released.connect(self._block_watcher)
     self.position = None
     self.timer = QTimer()
     self.timer.timeout.connect(self._SH_TimerFired)
     self.timer.start(60000)
    def initiate_file_transfer(self):
        notification_center = NotificationCenter()
        notification_center.add_observer(self, sender=self)

        try:
            self.file_selector = FileSelector.for_file(self.file_path.encode('utf-8'), hash=None)
        except IOError:
            notification_center.post_notification('BlinkFileTransferDidNotComputeHash', sender=self, data=NotificationData(reason='Cannot open file'))
            return

        self.ft_info.file_size = self.file_size
        # compute the file hash first
        self.ft_info.status = "preparing"
        self.status = "Computing checksum..."
        hash = hashlib.sha1()
        pos = progress = 0
        chunk_size = limit(self.file_selector.size/100, min=65536, max=1048576)
        notification_center.post_notification('BlinkFileTransferHashUpdate', sender=self, data=NotificationData(progress=0))
        while not self.stop_event.isSet():
            content = self.file_selector.fd.read(chunk_size)
            if not content:
                break
            hash.update(content)
            pos += len(content)
            old_progress, progress = progress, int(float(pos)/self.file_selector.size*100)
            if old_progress != progress:
                notification_center.post_notification('BlinkFileTransferHashUpdate', sender=self, data=NotificationData(progress=progress))
        else:
            self.file_selector.fd.close()
            notification_center.post_notification('BlinkFileTransferDidNotComputeHash', sender=self, data=NotificationData(reason='Cancelled computing checksum'))
            return
        self.file_selector.fd.seek(0)
        self.file_selector.hash = hash
        notification_center.post_notification('BlinkFileTransferDidComputeHash', sender=self)
示例#6
0
    def _CH_register(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._registration_timer is not None and self._registration_timer.active():
            self._registration_timer.cancel()
        self._registration_timer = None

        # Initialize the registration
        if self._registration is None:
            duration = command.refresh_interval or self.account.sip.register_interval
            self._registration = Registration(FromHeader(self.account.uri, self.account.display_name), credentials=self.account.credentials, duration=duration, extra_headers=[Header('Supported', 'gruu')])
            notification_center.add_observer(self, sender=self._registration)
            notification_center.post_notification('SIPAccountWillRegister', sender=self.account)
        else:
            notification_center.post_notification('SIPAccountRegistrationWillRefresh', sender=self.account)

        try:
            # Lookup routes
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in settings.sip.transport_list:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host, port=self.account.sip.outbound_proxy.port, parameters={'transport': self.account.sip.outbound_proxy.transport})
            else:
                uri = SIPURI(host=self.account.id.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(uri, settings.sip.transport_list).wait()
            except DNSLookupError, e:
                retry_after = random.uniform(self._dns_wait, 2*self._dns_wait)
                self._dns_wait = limit(2*self._dns_wait, max=30)
                raise RegistrationError('DNS lookup failed: %s' % e, retry_after=retry_after)
            else:
示例#7
0
 def __init__(self, account, uri, display_name, parent=None):
     super(PendingWatcherDialog, self).__init__(parent)
     self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
     self.setAttribute(Qt.WA_DeleteOnClose)
     with Resources.directory:
         self.setupUi(self)
     default_font_size = self.uri_label.fontInfo().pointSizeF()
     name_font_size = limit(default_font_size + 3, max=14)
     font = self.name_label.font()
     font.setPointSizeF(name_font_size)
     self.name_label.setFont(font)
     addressbook_manager = addressbook.AddressbookManager()
     try:
         self.contact = next(
             contact for contact in addressbook_manager.get_contacts()
             if uri in (addr.uri for addr in contact.uris))
     except StopIteration:
         self.contact = None
     else:
         display_name = self.contact.name
         icon_manager = IconManager()
         icon = icon_manager.get(self.contact.id)
         if icon is not None:
             self.user_icon.setPixmap(icon.pixmap(48))
     self.description_label.setText(
         'Wants to subscribe to your availability information at {}'.format(
             account.id))
     self.name_label.setText(display_name or uri)
     self.uri_label.setText(uri)
     self.accept_button.released.connect(self._accept_watcher)
     self.block_button.released.connect(self._block_watcher)
     self.position = None
     self.timer = QTimer()
     self.timer.timeout.connect(self._SH_TimerFired)
     self.timer.start(60000)
示例#8
0
 def run(self, func, *args, **kw):
     with self._lock:
         self._queue.put(CallFunctionEvent(func, args, kw))
         self.__dict__['jobs'] += 1
         if self._started and self.workers < limit(self.jobs,
                                                   max=self.max_threads):
             self._start_worker()
示例#9
0
 def compact(self):
     with self._lock:
         needed_workers = limit(self.jobs,
                                min=self.min_threads,
                                max=self.max_threads)
         while self.workers > needed_workers:
             self._stop_worker()
示例#10
0
    def _CH_publish(self, command):
        if command.state is None or self._publication is None and command.state is SameState:
            command.signal()
            return

        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._publication_timer is not None and self._publication_timer.active(
        ):
            self._publication_timer.cancel()
        self._publication_timer = None

        if self._publication is None:
            duration = command.refresh_interval or self.account.sip.publish_interval
            from_header = FromHeader(self.account.uri,
                                     self.account.display_name)
            self._publication = Publication(
                from_header,
                self.event,
                self.payload_type.content_type,
                credentials=self.account.credentials,
                duration=duration,
                extra_headers=self.extra_headers)
            notification_center.add_observer(self, sender=self._publication)
            notification_center.post_notification(
                self.__class__.__name__ + 'WillPublish',
                sender=self,
                data=NotificationData(state=command.state, duration=duration))
        else:
            notification_center.post_notification(
                self.__class__.__name__ + 'WillRefresh',
                sender=self,
                data=NotificationData(state=command.state))

        try:
            # Lookup routes
            valid_transports = self.__transports__.intersection(
                settings.sip.transport_list)
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in valid_transports:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                             port=self.account.sip.outbound_proxy.port,
                             parameters={
                                 'transport':
                                 self.account.sip.outbound_proxy.transport
                             })
            else:
                uri = SIPURI(host=self.account.id.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(uri, valid_transports).wait()
            except DNSLookupError, e:
                retry_after = random.uniform(self._dns_wait,
                                             2 * self._dns_wait)
                self._dns_wait = limit(2 * self._dns_wait, max=30)
                raise PublicationError('DNS lookup failed: %s' % e,
                                       retry_after=retry_after)
            else:
示例#11
0
 def start(self):
     with self._lock:
         if self._started:
             return
         self._started = True
         self._thread_id = count(1)
         needed_workers = limit(self.jobs, min=self.min_threads, max=self.max_threads)
         while self.workers < needed_workers:
             self._start_worker()
示例#12
0
    def show(self, position=1):
        from blink import Blink
        blink = Blink()
        screen_geometry = blink.desktop().screenGeometry(self)
        available_geometry = blink.desktop().availableGeometry(self)
        main_window_geometry = blink.main_window.geometry()
        main_window_framegeometry = blink.main_window.frameGeometry()

        horizontal_decorations = main_window_framegeometry.width(
        ) - main_window_geometry.width()
        vertical_decorations = main_window_framegeometry.height(
        ) - main_window_geometry.height()
        width = limit(self.sizeHint().width(),
                      min=self.minimumSize().width(),
                      max=min(
                          self.maximumSize().width(),
                          available_geometry.width() - horizontal_decorations))
        height = limit(self.sizeHint().height(),
                       min=self.minimumSize().height(),
                       max=min(
                           self.maximumSize().height(),
                           available_geometry.height() - vertical_decorations))
        total_width = width + horizontal_decorations
        total_height = height + vertical_decorations
        x = limit(screen_geometry.center().x() - total_width / 2,
                  min=available_geometry.left(),
                  max=available_geometry.right() - total_width)
        if position is None:
            y = -1
        elif position % 2 == 0:
            y = screen_geometry.center().y() + (position -
                                                1) * total_height / 2
        else:
            y = screen_geometry.center().y() - position * total_height / 2
        if available_geometry.top(
        ) <= y <= available_geometry.bottom() - total_height:
            self.setGeometry(x, y, width, height)
        else:
            self.resize(width, height)

        self.position = position
        super(PendingWatcherDialog, self).show()
示例#13
0
 def resize(self, min_threads=1, max_threads=10):
     assert 0 <= min_threads <= max_threads > 0, "invalid bounds"
     with self._lock:
         self.__dict__['min_threads'] = min_threads
         self.__dict__['max_threads'] = max_threads
         if self._started:
             needed_workers = limit(self.jobs, min=min_threads, max=max_threads)
             while self.workers > max_threads:  # compare against needed_workers to compact or against max_threads to not
                 self._stop_worker()
             while self.workers < needed_workers:
                 self._start_worker()
示例#14
0
 def start(self):
     with self._lock:
         if self._started:
             return
         self._started = True
         self._thread_id = count(1)
         needed_workers = limit(self.jobs,
                                min=self.min_threads,
                                max=self.max_threads)
         while self.workers < needed_workers:
             self._start_worker()
 def __new__(cls, value):
     if isinstance(value, basestring):
         value = value.upper()
     elif not isinstance(value, (int, long)):
         raise TypeError("value must be a string or number")
     named_levels = {level.name: level for level in log.level.named_levels}
     if value in named_levels:
         return named_levels[value]
     try:
         return log.NamedLevel(limit(int(value), min=log.level.NOTSET))
     except ValueError:
         raise ValueError('invalid log level: %s' % value)
示例#16
0
 def resize(self, min_threads=1, max_threads=10):
     assert 0 <= min_threads <= max_threads > 0, 'invalid bounds'
     with self._lock:
         self.__dict__['min_threads'] = min_threads
         self.__dict__['max_threads'] = max_threads
         if self._started:
             needed_workers = limit(self.jobs,
                                    min=min_threads,
                                    max=max_threads)
             while self.workers > max_threads:  # compare against needed_workers to compact or against max_threads to not
                 self._stop_worker()
             while self.workers < needed_workers:
                 self._start_worker()
示例#17
0
 def _NH_SIPAccountGotMessageSummary(self, notification):
     account = notification.sender
     summary = notification.data.message_summary
     action = next(action for action in self.voicemail_menu.actions() if action.data() is account)
     action.setEnabled(account.voicemail_uri is not None)
     if summary.messages_waiting:
         try:
             new_messages = limit(int(summary.summaries['voice-message']['new_messages']), min=0, max=11)
         except (KeyError, ValueError):
             new_messages = 0
     else:
         new_messages = 0
     action.setIcon(self.mwi_icons[new_messages])
示例#18
0
 def _NH_SIPAccountGotMessageSummary(self, notification):
     account = notification.sender
     summary = notification.data.message_summary
     action = (action for action in self.voicemail_menu.actions() if action.data() is account).next()
     action.setEnabled(account.voicemail_uri is not None)
     if summary.messages_waiting:
         try:
             new_messages = limit(int(summary.summaries['voice-message']['new_messages']), min=0, max=11)
         except (KeyError, ValueError):
             new_messages = 0
     else:
         new_messages = 0
     action.setIcon(self.mwi_icons[new_messages])
    def _CH_register(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._registration_timer is not None and self._registration_timer.active(
        ):
            self._registration_timer.cancel()
        self._registration_timer = None

        # Initialize the registration
        if self._registration is None:
            duration = command.refresh_interval or self.account.sip.register_interval
            self._registration = Registration(
                FromHeader(self.account.uri, self.account.display_name),
                credentials=self.account.credentials,
                duration=duration,
                extra_headers=[Header('Supported', 'gruu')])
            notification_center.add_observer(self, sender=self._registration)
            notification_center.post_notification('SIPAccountWillRegister',
                                                  sender=self.account)
        else:
            notification_center.post_notification(
                'SIPAccountRegistrationWillRefresh', sender=self.account)

        try:
            # Lookup routes
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in settings.sip.transport_list:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                             port=self.account.sip.outbound_proxy.port,
                             parameters={
                                 'transport':
                                 self.account.sip.outbound_proxy.transport
                             })
            else:
                uri = SIPURI(host=self.account.id.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(
                    uri, settings.sip.transport_list).wait()
            except DNSLookupError, e:
                retry_after = random.uniform(self._dns_wait,
                                             2 * self._dns_wait)
                self._dns_wait = limit(2 * self._dns_wait, max=30)
                raise RegistrationError('DNS lookup failed: %s' % e,
                                        retry_after=retry_after)
            else:
示例#20
0
    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)
示例#21
0
    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('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)
示例#22
0
    def initiate_file_transfer(self):
        notification_center = NotificationCenter()
        notification_center.add_observer(self, sender=self)

        self.file_selector = FileSelector.for_file(
            self.file_path.encode('utf-8'), hash=None)
        self.ft_info.file_size = self.file_size
        # compute the file hash first
        self.ft_info.status = "preparing"
        self.status = "Computing checksum..."
        hash = hashlib.sha1()
        pos = progress = 0
        chunk_size = limit(self.file_selector.size / 100,
                           min=65536,
                           max=1048576)
        notification_center.post_notification(
            'BlinkFileTransferHashUpdate',
            sender=self,
            data=TimestampedNotificationData(progress=0))
        while not self.stop_event.isSet():
            content = self.file_selector.fd.read(chunk_size)
            if not content:
                break
            hash.update(content)
            pos += len(content)
            old_progress, progress = progress, int(
                float(pos) / self.file_selector.size * 100)
            if old_progress != progress:
                notification_center.post_notification(
                    'BlinkFileTransferHashUpdate',
                    sender=self,
                    data=TimestampedNotificationData(progress=progress))
        else:
            notification_center.post_notification(
                'BlinkFileTransferDidNotComputeHash', sender=self)
            return
        self.file_selector.fd.seek(0)
        self.file_selector.hash = hash
        notification_center.post_notification(
            'BlinkFileTransferDidComputeHash',
            sender=self,
            data=TimestampedNotificationData())
示例#23
0
    def shade(color, role, contrast, chroma_adjust=0.0):
        contrast = limit(contrast, min=-1.0, max=1.0)
        y = ColorUtils.luma(color)
        yi = 1.0 - y

        # handle very dark colors (base, mid, dark, shadow == midlight, light)
        if y < 0.006:
            if role == ColorScheme.LightShade:
                return ColorUtils.shade(color, 0.05 + 0.95 * contrast, chroma_adjust)
            elif role == ColorScheme.MidShade:
                return ColorUtils.shade(color, 0.01 + 0.20 * contrast, chroma_adjust)
            elif role == ColorScheme.DarkShade:
                return ColorUtils.shade(color, 0.02 + 0.40 * contrast, chroma_adjust)
            else:
                return ColorUtils.shade(color, 0.03 + 0.60 * contrast, chroma_adjust)

        # handle very light colors (base, midlight, light == mid, dark, shadow)
        if y > 0.93:
            if role == ColorScheme.MidlightShade:
                return ColorUtils.shade(color, -0.02 - 0.20 * contrast, chroma_adjust)
            elif role == ColorScheme.DarkShade:
                return ColorUtils.shade(color, -0.06 - 0.60 * contrast, chroma_adjust)
            elif role == ColorScheme.ShadowShade:
                return ColorUtils.shade(color, -0.10 - 0.90 * contrast, chroma_adjust)
            else:
                return ColorUtils.shade(color, -0.04 - 0.40 * contrast, chroma_adjust)

        # handle everything else
        light_amount = (0.05 + y * 0.55) * (0.25 + contrast * 0.75)
        dark_amount  = (     - y       ) * (0.55 + contrast * 0.35)
        if role == ColorScheme.LightShade:
            return ColorUtils.shade(color, light_amount, chroma_adjust)
        elif role == ColorScheme.MidlightShade:
            return ColorUtils.shade(color, (0.15 + 0.35 * yi) * light_amount, chroma_adjust)
        elif role == ColorScheme.MidShade:
            return ColorUtils.shade(color, (0.35 + 0.15 * y) * dark_amount, chroma_adjust)
        elif role == ColorScheme.DarkShade:
            return ColorUtils.shade(color, dark_amount, chroma_adjust)
        else:
            return ColorUtils.darken(ColorUtils.shade(color, dark_amount, chroma_adjust), 0.5 + 0.3 * y)
示例#24
0
    def _CH_publish(self, command):
        if command.state is None or self._publication is None and command.state is SameState:
            command.signal()
            return

        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._publication_timer is not None and self._publication_timer.active():
            self._publication_timer.cancel()
        self._publication_timer = None

        if self._publication is None:
            duration = command.refresh_interval or self.account.sip.publish_interval
            from_header = FromHeader(self.account.uri, self.account.display_name)
            self._publication = Publication(from_header, self.event, self.payload_type.content_type, credentials=self.account.credentials, duration=duration, extra_headers=self.extra_headers)
            notification_center.add_observer(self, sender=self._publication)
            notification_center.post_notification(self.__class__.__name__ + 'WillPublish', sender=self, data=NotificationData(state=command.state, duration=duration))
        else:
            notification_center.post_notification(self.__class__.__name__ + 'WillRefresh', sender=self, data=NotificationData(state=command.state))

        try:
            # Lookup routes
            valid_transports = self.__transports__.intersection(settings.sip.transport_list)
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in valid_transports:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host, port=self.account.sip.outbound_proxy.port, parameters={'transport': self.account.sip.outbound_proxy.transport})
            else:
                uri = SIPURI(host=self.account.id.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(uri, valid_transports).wait()
            except DNSLookupError, e:
                retry_after = random.uniform(self._dns_wait, 2*self._dns_wait)
                self._dns_wait = limit(2*self._dns_wait, max=30)
                raise PublicationError('DNS lookup failed: %s' % e, retry_after=retry_after)
            else:
示例#25
0
    def _run(self):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        sender_uri = self.sender.uri.as_sip_uri()
        recipient_uri = self.recipient.uri.as_sip_uri()
        participant_uri = self.participant.uri.as_sip_uri()

        try:
            # Lookup routes
            account = DefaultAccount()
            if account.sip.outbound_proxy is not None and account.sip.outbound_proxy.transport in settings.sip.transport_list:
                uri = SIPURI(host=account.sip.outbound_proxy.host,
                             port=account.sip.outbound_proxy.port,
                             parameters={
                                 'transport':
                                 account.sip.outbound_proxy.transport
                             })
            elif account.sip.always_use_my_proxy:
                uri = SIPURI(host=account.id.domain)
            else:
                uri = SIPURI.new(recipient_uri)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(
                    uri, settings.sip.transport_list).wait()
            except DNSLookupError as e:
                raise ReferralError(error='DNS lookup failed: %s' % e)

            timeout = time() + 30
            for route in routes:
                self.route = route
                remaining_time = timeout - time()
                if remaining_time > 0:
                    transport = route.transport
                    parameters = {} if transport == 'udp' else {
                        'transport': transport
                    }
                    contact_uri = SIPURI(user=account.contact.username,
                                         host=SIPConfig.local_ip.normalized,
                                         port=getattr(Engine(),
                                                      '%s_port' % transport),
                                         parameters=parameters)
                    refer_to_header = ReferToHeader(str(participant_uri))
                    refer_to_header.parameters['method'] = 'INVITE'
                    referral = Referral(recipient_uri, FromHeader(sender_uri),
                                        ToHeader(recipient_uri),
                                        refer_to_header,
                                        ContactHeader(contact_uri),
                                        RouteHeader(route.uri),
                                        account.credentials)
                    notification_center.add_observer(self, sender=referral)
                    try:
                        referral.send_refer(
                            timeout=limit(remaining_time, min=1, max=5))
                    except SIPCoreError:
                        notification_center.remove_observer(self,
                                                            sender=referral)
                        timeout = 5
                        raise ReferralError(error='Internal error')
                    self._referral = referral
                    try:
                        while True:
                            notification = self._channel.wait()
                            if notification.name == 'SIPReferralDidStart':
                                break
                    except SIPReferralDidFail as e:
                        notification_center.remove_observer(self,
                                                            sender=referral)
                        self._referral = None
                        if e.data.code in (403, 405):
                            raise ReferralError(
                                error=sip_status_messages[e.data.code],
                                code=e.data.code)
                        else:
                            # Otherwise just try the next route
                            continue
                    else:
                        break
            else:
                self.route = None
                raise ReferralError(error='No more routes to try')
            # At this point it is subscribed. Handle notifications and ending/failures.
            try:
                self.active = True
                while True:
                    notification = self._channel.wait()
                    if notification.name == 'SIPReferralDidEnd':
                        break
            except SIPReferralDidFail as e:
                notification_center.remove_observer(self,
                                                    sender=self._referral)
                raise ReferralError(error=e.data.reason, code=e.data.code)
            else:
                notification_center.remove_observer(self,
                                                    sender=self._referral)
            finally:
                self.active = False
        except ReferralError as e:
            self._failure = MucInvitationFailure(e.code, e.error)
        finally:
            notification_center.remove_observer(
                self, name='NetworkConditionsDidChange')
            self._referral = None
            if self._failure is not None:
                notification_center.post_notification(
                    'X2SMucInvitationHandlerDidFail',
                    sender=self,
                    data=NotificationData(failure=self._failure))
            else:
                notification_center.post_notification(
                    'X2SMucInvitationHandlerDidEnd', sender=self)
示例#26
0
 def _gamma(value):
     return limit(value, 0.0, 1.0) ** 2.2
示例#27
0
 def lighten(color, amount=0.5, chroma_inverse_gain=1.0):
     color = HCYColor(color)
     color.y = 1.0 - limit((1.0 - color.y) * (1.0 - amount),      min=0.0, max=1.0)
     color.c = 1.0 - limit((1.0 - color.c) * chroma_inverse_gain, min=0.0, max=1.0)
     return color.qColor()
示例#28
0
 def compact(self):
     with self._lock:
         needed_workers = limit(self.jobs, min=self.min_threads, max=self.max_threads)
         while self.workers > needed_workers:
             self._stop_worker()
示例#29
0
 def run(self, func, *args, **kw):
     with self._lock:
         self._queue.put(CallFunctionEvent(func, args, kw))
         self.__dict__['jobs'] += 1
         if self._started and self.workers < limit(self.jobs, max=self.max_threads):
             self._start_worker()
示例#30
0
 def darken(color, amount=0.5, chroma_gain=1.0):
     color = HCYColor(color)
     color.y = limit(color.y * (1.0 - amount), min=0.0, max=1.0)
     color.c = limit(color.c * chroma_gain,    min=0.0, max=1.0)
     return color.qColor()
示例#31
0
    def _CH_register(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._registration_timer is not None and self._registration_timer.active(
        ):
            self._registration_timer.cancel()
        self._registration_timer = None

        # Initialize the registration
        if self._registration is None:
            duration = command.refresh_interval or self.account.sip.register_interval
            self._registration = Registration(
                FromHeader(self.account.uri, self.account.display_name),
                credentials=self.account.credentials,
                duration=duration,
                extra_headers=[Header('Supported', 'gruu')])
            notification_center.add_observer(self, sender=self._registration)
            notification_center.post_notification('SIPAccountWillRegister',
                                                  sender=self.account)
        else:
            notification_center.post_notification(
                'SIPAccountRegistrationWillRefresh', sender=self.account)

        try:
            # Lookup routes
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in settings.sip.transport_list:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                             port=self.account.sip.outbound_proxy.port,
                             parameters={
                                 'transport':
                                 self.account.sip.outbound_proxy.transport
                             })
            else:
                uri = SIPURI(host=self.account.id.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(
                    uri, settings.sip.transport_list).wait()
            except DNSLookupError as e:
                retry_after = random.uniform(self._dns_wait,
                                             2 * self._dns_wait)
                self._dns_wait = limit(2 * self._dns_wait, max=30)
                raise RegistrationError('DNS lookup failed: %s' % e,
                                        retry_after=retry_after)
            else:
                self._dns_wait = 1

            # Register by trying each route in turn
            register_timeout = time() + 30
            for route in routes:
                remaining_time = register_timeout - time()
                if remaining_time > 0:
                    try:
                        contact_uri = self.account.contact[NoGRUU, route]
                    except KeyError:
                        continue
                    contact_header = ContactHeader(contact_uri)
                    contact_header.parameters[
                        '+sip.instance'] = '"<%s>"' % settings.instance_id
                    if self.account.nat_traversal.use_ice:
                        contact_header.parameters['+sip.ice'] = None
                    route_header = RouteHeader(route.uri)
                    try:
                        self._registration.register(contact_header,
                                                    route_header,
                                                    timeout=limit(
                                                        remaining_time,
                                                        min=1,
                                                        max=10))
                    except SIPCoreError:
                        raise RegistrationError('Internal error',
                                                retry_after=5)
                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.name == 'SIPRegistrationDidSucceed':
                                break
                            if notification.name == 'SIPRegistrationDidEnd':
                                raise RegistrationError(
                                    'Registration expired', retry_after=0
                                )  # registration expired while we were trying to re-register
                    except SIPRegistrationDidFail as e:
                        notification_data = NotificationData(
                            code=e.data.code,
                            reason=e.data.reason,
                            registration=self._registration,
                            registrar=route)
                        notification_center.post_notification(
                            'SIPAccountRegistrationGotAnswer',
                            sender=self.account,
                            data=notification_data)
                        if e.data.code == 401:
                            # Authentication failed, so retry the registration in some time
                            raise RegistrationError('Authentication failed',
                                                    retry_after=random.uniform(
                                                        60, 120))
                        elif e.data.code == 423:
                            # Get the value of the Min-Expires header
                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.register_interval:
                                refresh_interval = e.data.min_expires
                            else:
                                refresh_interval = None
                            raise RegistrationError(
                                'Interval too short',
                                retry_after=random.uniform(60, 120),
                                refresh_interval=refresh_interval)
                        else:
                            # Otherwise just try the next route
                            continue
                    else:
                        notification_data = NotificationData(
                            code=notification.data.code,
                            reason=notification.data.reason,
                            registration=self._registration,
                            registrar=route)
                        notification_center.post_notification(
                            'SIPAccountRegistrationGotAnswer',
                            sender=self.account,
                            data=notification_data)
                        self.registered = True
                        # Save GRUU
                        try:
                            header = next(
                                header for header in
                                notification.data.contact_header_list
                                if header.parameters.get('+sip.instance', '').
                                strip('"<>') == settings.instance_id)
                        except StopIteration:
                            self.account.contact.public_gruu = None
                            self.account.contact.temporary_gruu = None
                        else:
                            public_gruu = header.parameters.get(
                                'pub-gruu', None)
                            temporary_gruu = header.parameters.get(
                                'temp-gruu', None)
                            try:
                                self.account.contact.public_gruu = SIPURI.parse(
                                    public_gruu.strip('"'))
                            except (AttributeError, SIPCoreError):
                                self.account.contact.public_gruu = None
                            try:
                                self.account.contact.temporary_gruu = SIPURI.parse(
                                    temporary_gruu.strip('"'))
                            except (AttributeError, SIPCoreError):
                                self.account.contact.temporary_gruu = None
                        notification_data = NotificationData(
                            contact_header=notification.data.contact_header,
                            contact_header_list=notification.data.
                            contact_header_list,
                            expires=notification.data.expires_in,
                            registrar=route)
                        notification_center.post_notification(
                            'SIPAccountRegistrationDidSucceed',
                            sender=self.account,
                            data=notification_data)
                        self._register_wait = 1
                        command.signal()
                        break
            else:
                # There are no more routes to try, reschedule the registration
                retry_after = random.uniform(self._register_wait,
                                             2 * self._register_wait)
                self._register_wait = limit(self._register_wait * 2, max=30)
                raise RegistrationError('No more routes to try',
                                        retry_after=retry_after)
        except RegistrationError as e:
            self.registered = False
            notification_center.remove_observer(self,
                                                sender=self._registration)
            notification_center.post_notification(
                'SIPAccountRegistrationDidFail',
                sender=self.account,
                data=NotificationData(error=e.error,
                                      retry_after=e.retry_after))

            def register():
                if self.active:
                    self._command_channel.send(
                        Command('register',
                                command.event,
                                refresh_interval=e.refresh_interval))
                self._registration_timer = None

            self._registration_timer = reactor.callLater(
                e.retry_after, register)
            self._registration = None
            self.account.contact.public_gruu = None
            self.account.contact.temporary_gruu = None
示例#32
0
    def paintEvent(self, event):
        option = QStyleOption()
        option.initFrom(self)

        contents_rect = self.style().subElementRect(QStyle.SE_FrameContents, option, self) or self.contentsRect() # the SE_FrameContents rect is Null unless the stylesheet defines decorations

        if self.graphStyle == self.BarStyle:
            graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width()) / self.horizontalPixelsPerUnit))
        else:
            graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width() - 1) / self.horizontalPixelsPerUnit) + 1)

        max_value = self.__dict__['max_value'] = max(chain([0], *(islice(reversed(graph.data), graph_width) for graph in self.graphs if graph.enabled)))

        if self.graphHeight == self.AutomaticHeight or self.graphHeight < 0:
            graph_height = self.__dict__['graph_height'] = max(self.scaler.get_height(max_value), self.minHeight)
        else:
            graph_height = self.__dict__['graph_height'] = max(self.graphHeight, self.minHeight)

        if self.graphStyle == self.BarStyle:
            height_scaling = float(contents_rect.height()) / graph_height
        else:
            height_scaling = float(contents_rect.height() - self.lineThickness) / graph_height

        painter = QStylePainter(self)
        painter.drawPrimitive(QStyle.PE_Widget, option)

        painter.setClipRect(contents_rect)

        painter.save()
        painter.translate(contents_rect.x() + contents_rect.width() - 1, contents_rect.y() + contents_rect.height() - 1)
        painter.scale(-1, -1)

        painter.setRenderHint(QStylePainter.Antialiasing, self.graphStyle != self.BarStyle)

        for graph in (graph for graph in self.graphs if graph.enabled and graph.data):
            if self.boundary is not None and 0 < self.boundary < graph_height:
                boundary_width = min(5.0/height_scaling, self.boundary-0, graph_height-self.boundary)
                pen_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling)
                pen_color.setColorAt(0, graph.color)
                pen_color.setColorAt(1, graph.over_boundary_color)
                brush_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling)
                brush_color.setColorAt(0, self.color_with_alpha(graph.color, self.fillTransparency))
                brush_color.setColorAt(1, self.color_with_alpha(graph.over_boundary_color, self.fillTransparency))
            else:
                pen_color = graph.color
                brush_color = self.color_with_alpha(graph.color, self.fillTransparency)
            dataset = islice(reversed(graph.data), graph_width)
            if self.graphStyle == self.BarStyle:
                lines = [QLine(x*self.horizontalPixelsPerUnit, 0, x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)]
                painter.setPen(QPen(pen_color, self.lineThickness))
                painter.drawLines(lines)
            else:
                painter.translate(0, +self.lineThickness/2 - 1)

                if self.smoothEnvelope and self.smoothFactor > 0:
                    min_value = 0
                    max_value = graph_height * height_scaling
                    cx_offset = self.horizontalPixelsPerUnit / 3.0
                    smoothness = self.smoothFactor

                    last_values = deque(3*[dataset.next() * height_scaling], maxlen=3) # last 3 values: 0 last, 1 previous, 2 previous previous

                    envelope = QPainterPath()
                    envelope.moveTo(0, last_values[0])
                    for x, y in enumerate(dataset, 1):
                        x = x * self.horizontalPixelsPerUnit
                        y = y * height_scaling * (1 - smoothness) + last_values[0] * smoothness
                        last_values.appendleft(y)
                        c1x = x - cx_offset * 2
                        c2x = x - cx_offset
                        c1y = limit((1 + smoothness) * last_values[1] - smoothness * last_values[2], min_value, max_value) # same gradient as previous previous value to previous value
                        c2y = limit((1 - smoothness) * last_values[0] + smoothness * last_values[1], min_value, max_value) # same gradient as previous value to last value
                        envelope.cubicTo(c1x, c1y, c2x, c2y, x, y)
                else:
                    envelope = QPainterPath()
                    envelope.addPolygon(QPolygonF([QPointF(x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)]))

                if self.fillEnvelope or graph.fill_envelope:
                    first_element = envelope.elementAt(0)
                    last_element = envelope.elementAt(envelope.elementCount() - 1)
                    fill_path = QPainterPath()
                    fill_path.moveTo(last_element.x, last_element.y)
                    fill_path.lineTo(last_element.x + 1, last_element.y)
                    fill_path.lineTo(last_element.x + 1, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, first_element.y)
                    fill_path.connectPath(envelope)
                    painter.fillPath(fill_path, brush_color)

                painter.strokePath(envelope, QPen(pen_color, self.lineThickness, join=Qt.RoundJoin))

                painter.translate(0, -self.lineThickness/2 + 1)

        if self.boundary is not None and self.boundaryColor:
            painter.setRenderHint(QStylePainter.Antialiasing, False)
            painter.setPen(QPen(self.boundaryColor, 1.0))
            painter.drawLine(0, self.boundary*height_scaling, contents_rect.width(), self.boundary*height_scaling)

        painter.restore()

        # queue the 'updated' signal to be emited after returning to the main loop
        QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection)
 if remaining_time > 0:
     try:
         contact_uri = self.account.contact[NoGRUU, route]
     except KeyError:
         continue
     contact_header = ContactHeader(contact_uri)
     contact_header.parameters[
         '+sip.instance'] = '"<%s>"' % settings.instance_id
     if self.account.nat_traversal.use_ice:
         contact_header.parameters['+sip.ice'] = None
     route_header = RouteHeader(route.uri)
     try:
         self._registration.register(contact_header,
                                     route_header,
                                     timeout=limit(
                                         remaining_time,
                                         min=1,
                                         max=10))
     except SIPCoreError:
         raise RegistrationError('Internal error',
                                 retry_after=5)
     try:
         while True:
             notification = self._data_channel.wait()
             if notification.name == 'SIPRegistrationDidSucceed':
                 break
             if notification.name == 'SIPRegistrationDidEnd':
                 raise RegistrationError(
                     'Registration expired', retry_after=0
                 )  # registration expired while we were trying to re-register
     except SIPRegistrationDidFail, e:
         notification_data = NotificationData(
示例#34
0
                retry_after = random.uniform(self._dns_wait, 2*self._dns_wait)
                self._dns_wait = limit(2*self._dns_wait, max=30)
                raise PublicationError('DNS lookup failed: %s' % e, retry_after=retry_after)
            else:
                self._dns_wait = 1

            body = None if command.state is SameState else command.state.toxml()

            # Publish by trying each route in turn
            publish_timeout = time() + 30
            for route in routes:
                remaining_time = publish_timeout-time()
                if remaining_time > 0:
                    try:
                        try:
                            self._publication.publish(body, RouteHeader(route.uri), timeout=limit(remaining_time, min=1, max=10))
                        except ValueError as e:  # this happens for an initial PUBLISH with body=None
                            raise PublicationError(str(e), retry_after=0)
                        except PublicationETagError:
                            state = self.state # access self.state only once to avoid race conditions
                            if state is not None:
                                self._publication.publish(state.toxml(), RouteHeader(route.uri), timeout=limit(remaining_time, min=1, max=10))
                            else:
                                command.signal()
                                return
                    except SIPCoreError:
                        raise PublicationError('Internal error', retry_after=5)

                    try:
                        while True:
                            notification = self._data_channel.wait()
示例#35
0
 def put(self, key, value):
     expiration = value.expiration - time()
     if expiration > 0:
         self.data[key] = value
         reactor.callLater(limit(expiration, max=3600), self.data.pop, key,
                           None)
示例#36
0
    def _subscription_handler(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        subscription_uri = self.subscription_uri
        refresh_interval = command.refresh_interval or self.account.sip.subscribe_interval
        valid_transports = self.__transports__.intersection(
            settings.sip.transport_list)

        try:
            if Host.default_ip is None:
                raise SubscriptionError('No IP address', retry_after=60)

            # Lookup routes
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in valid_transports:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host,
                             port=self.account.sip.outbound_proxy.port,
                             parameters={
                                 'transport':
                                 self.account.sip.outbound_proxy.transport
                             })
            elif self.account.sip.always_use_my_proxy:
                uri = SIPURI(host=self.account.id.domain)
            else:
                uri = SIPURI(host=subscription_uri.domain)

            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(
                    uri, valid_transports,
                    tls_name=self.account.sip.tls_name).wait()
            except DNSLookupError as e:
                raise SubscriptionError('DNS lookup failed: %s' % e,
                                        retry_after=random.uniform(15, 30))

            subscription_uri = SIPURI(user=subscription_uri.username,
                                      host=subscription_uri.domain)
            content = self.content

            timeout = time() + 30
            for route in routes:
                if Host.default_ip is None:
                    raise SubscriptionError('No IP address', retry_after=60)

                remaining_time = timeout - time()
                if remaining_time > 0:
                    try:
                        contact_uri = self.account.contact[NoGRUU, route]
                    except KeyError:
                        continue
                    subscription = Subscription(
                        subscription_uri,
                        FromHeader(self.account.uri,
                                   self.account.display_name),
                        ToHeader(subscription_uri),
                        ContactHeader(contact_uri),
                        self.event.encode(),
                        RouteHeader(route.uri),
                        credentials=self.account.credentials,
                        refresh=refresh_interval)
                    notification_center.add_observer(self, sender=subscription)
                    try:
                        subscription.subscribe(
                            body=content.body,
                            content_type=content.type,
                            extra_headers=self.extra_headers,
                            timeout=limit(remaining_time, min=1, max=5))
                    except SIPCoreError:
                        notification_center.remove_observer(
                            self, sender=subscription)
                        raise SubscriptionError('Internal error',
                                                retry_after=5)
                    self._subscription = subscription
                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.name == 'SIPSubscriptionDidStart':
                                break
                    except SIPSubscriptionDidFail as e:
                        notification_center.remove_observer(
                            self, sender=subscription)
                        self._subscription = None
                        if e.data.code == 407:
                            # Authentication failed, so retry the subscription in some time
                            raise SubscriptionError('Authentication failed',
                                                    retry_after=random.uniform(
                                                        60, 120))
                        elif e.data.code == 423:
                            # Get the value of the Min-Expires header
                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.subscribe_interval:
                                refresh_interval = e.data.min_expires
                            else:
                                refresh_interval = None
                            raise SubscriptionError(
                                'Interval too short',
                                retry_after=random.uniform(60, 120),
                                refresh_interval=refresh_interval)
                        elif e.data.code in (405, 406, 489):
                            raise SubscriptionError(
                                'Method or event not supported',
                                retry_after=3600)
                        elif e.data.code == 1400:
                            raise SubscriptionError(e.data.reason,
                                                    retry_after=3600)
                        else:
                            # Otherwise just try the next route
                            continue
                    else:
                        self.subscribed = True
                        command.signal()
                        break
            else:
                # There are no more routes to try, reschedule the subscription
                raise SubscriptionError('No more routes to try',
                                        retry_after=random.uniform(60, 180))
            # At this point it is subscribed. Handle notifications and ending/failures.
            notification_center.post_notification(self.__nickname__ +
                                                  'SubscriptionDidStart',
                                                  sender=self)
            try:
                while True:
                    notification = self._data_channel.wait()
                    if notification.name == 'SIPSubscriptionGotNotify':
                        notification_center.post_notification(
                            self.__nickname__ + 'SubscriptionGotNotify',
                            sender=self,
                            data=notification.data)
                    elif notification.name == 'SIPSubscriptionDidEnd':
                        notification_center.post_notification(
                            self.__nickname__ + 'SubscriptionDidEnd',
                            sender=self,
                            data=NotificationData(originator='remote'))
                        if self.active:
                            self._command_channel.send(Command('subscribe'))
                        break
            except SIPSubscriptionDidFail:
                notification_center.post_notification(self.__nickname__ +
                                                      'SubscriptionDidFail',
                                                      sender=self)
                if self.active:
                    self._command_channel.send(Command('subscribe'))
            notification_center.remove_observer(self,
                                                sender=self._subscription)
        except InterruptSubscription as e:
            if not self.subscribed:
                command.signal(e)
            if self._subscription is not None:
                notification_center.remove_observer(self,
                                                    sender=self._subscription)
                try:
                    self._subscription.end(timeout=2)
                except SIPCoreError:
                    pass
                finally:
                    notification_center.post_notification(
                        self.__nickname__ + 'SubscriptionDidEnd',
                        sender=self,
                        data=NotificationData(originator='local'))
        except TerminateSubscription as e:
            if not self.subscribed:
                command.signal(e)
            if self._subscription is not None:
                try:
                    self._subscription.end(timeout=2)
                except SIPCoreError:
                    pass
                else:
                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.name == 'SIPSubscriptionDidEnd':
                                break
                    except SIPSubscriptionDidFail:
                        pass
                finally:
                    notification_center.remove_observer(
                        self, sender=self._subscription)
                    notification_center.post_notification(
                        self.__nickname__ + 'SubscriptionDidEnd',
                        sender=self,
                        data=NotificationData(originator='local'))
        except SubscriptionError as e:

            def subscribe(e):
                if self.active:
                    self._command_channel.send(
                        Command('subscribe',
                                command.event,
                                refresh_interval=e.refresh_interval))
                self._subscription_timer = None

            self._subscription_timer = reactor.callLater(
                e.retry_after, subscribe, e)
            notification_center.post_notification(self.__nickname__ +
                                                  'SubscriptionDidFail',
                                                  sender=self)
        finally:
            self.subscribed = False
            self._subscription = None
            self._subscription_proc = None
示例#37
0
    def _subscription_handler(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        subscription_uri = self.subscription_uri
        refresh_interval = command.refresh_interval or self.account.sip.subscribe_interval
        valid_transports = self.__transports__.intersection(settings.sip.transport_list)

        try:
            # Lookup routes
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in valid_transports:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host, port=self.account.sip.outbound_proxy.port, parameters={'transport': self.account.sip.outbound_proxy.transport})
            elif self.account.sip.always_use_my_proxy:
                uri = SIPURI(host=self.account.id.domain)
            else:
                uri = SIPURI(host=subscription_uri.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(uri, valid_transports).wait()
            except DNSLookupError, e:
                raise SubscriptionError('DNS lookup failed: %s' % e, retry_after=random.uniform(15, 30))

            subscription_uri = SIPURI(user=subscription_uri.username, host=subscription_uri.domain)
            content = self.content

            timeout = time() + 30
            for route in routes:
                remaining_time = timeout - time()
                if remaining_time > 0:
                    try:
                        contact_uri = self.account.contact[NoGRUU, route]
                    except KeyError:
                        continue
                    subscription = Subscription(subscription_uri, FromHeader(self.account.uri, self.account.display_name),
                                                ToHeader(subscription_uri),
                                                ContactHeader(contact_uri),
                                                self.event,
                                                RouteHeader(route.uri),
                                                credentials=self.account.credentials,
                                                refresh=refresh_interval)
                    notification_center.add_observer(self, sender=subscription)
                    try:
                        subscription.subscribe(body=content.body, content_type=content.type, extra_headers=self.extra_headers, timeout=limit(remaining_time, min=1, max=5))
                    except SIPCoreError:
                        notification_center.remove_observer(self, sender=subscription)
                        raise SubscriptionError('Internal error', retry_after=5)
                    self._subscription = subscription
                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.name == 'SIPSubscriptionDidStart':
                                break
                    except SIPSubscriptionDidFail, e:
                        notification_center.remove_observer(self, sender=subscription)
                        self._subscription = None
                        if e.data.code == 407:
                            # Authentication failed, so retry the subscription in some time
                            raise SubscriptionError('Authentication failed', retry_after=random.uniform(60, 120))
                        elif e.data.code == 423:
                            # Get the value of the Min-Expires header
                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.subscribe_interval:
                                refresh_interval = e.data.min_expires
                            else:
                                refresh_interval = None
                            raise SubscriptionError('Interval too short', retry_after=random.uniform(60, 120), refresh_interval=refresh_interval)
                        elif e.data.code in (405, 406, 489):
                            raise SubscriptionError('Method or event not supported', retry_after=3600)
                        elif e.data.code == 1400:
                            raise SubscriptionError(e.data.reason, retry_after=3600)
                        else:
                            # Otherwise just try the next route
                            continue
                    else:
                        self.subscribed = True
                        command.signal()
                        break
示例#38
0
    def _subscription_handler(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        subscription_uri = self.subscription_uri
        refresh_interval = command.refresh_interval or self.account.sip.subscribe_interval
        valid_transports = self.__transports__.intersection(settings.sip.transport_list)

        try:
            # Lookup routes
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in valid_transports:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host, port=self.account.sip.outbound_proxy.port, parameters={'transport': self.account.sip.outbound_proxy.transport})
            elif self.account.sip.always_use_my_proxy:
                uri = SIPURI(host=self.account.id.domain)
            else:
                uri = SIPURI(host=subscription_uri.domain)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(uri, valid_transports).wait()
            except DNSLookupError, e:
                raise SubscriptionError('DNS lookup failed: %s' % e, retry_after=random.uniform(15, 30))

            subscription_uri = SIPURI(user=subscription_uri.username, host=subscription_uri.domain)
            content = self.content

            timeout = time() + 30
            for route in routes:
                remaining_time = timeout - time()
                if remaining_time > 0:
                    try:
                        contact_uri = self.account.contact[NoGRUU, route]
                    except KeyError:
                        continue
                    subscription = Subscription(subscription_uri, FromHeader(self.account.uri, self.account.display_name),
                                                ToHeader(subscription_uri),
                                                ContactHeader(contact_uri),
                                                self.event,
                                                RouteHeader(route.uri),
                                                credentials=self.account.credentials,
                                                refresh=refresh_interval)
                    notification_center.add_observer(self, sender=subscription)
                    try:
                        subscription.subscribe(body=content.body, content_type=content.type, extra_headers=self.extra_headers, timeout=limit(remaining_time, min=1, max=5))
                    except SIPCoreError:
                        notification_center.remove_observer(self, sender=subscription)
                        raise SubscriptionError('Internal error', retry_after=5)
                    self._subscription = subscription
                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.name == 'SIPSubscriptionDidStart':
                                break
                    except SIPSubscriptionDidFail, e:
                        notification_center.remove_observer(self, sender=subscription)
                        self._subscription = None
                        if e.data.code == 407:
                            # Authentication failed, so retry the subscription in some time
                            raise SubscriptionError('Authentication failed', retry_after=random.uniform(60, 120))
                        elif e.data.code == 423:
                            # Get the value of the Min-Expires header
                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.subscribe_interval:
                                refresh_interval = e.data.min_expires
                            else:
                                refresh_interval = None
                            raise SubscriptionError('Interval too short', retry_after=random.uniform(60, 120), refresh_interval=refresh_interval)
                        elif e.data.code in (405, 406, 489):
                            raise SubscriptionError('Method or event not supported', retry_after=3600)
                        elif e.data.code == 1400:
                            raise SubscriptionError(e.data.reason, retry_after=3600)
                        else:
                            # Otherwise just try the next route
                            continue
                    else:
                        self.subscribed = True
                        command.signal()
                        break
示例#39
0
 def shade(color, luma_amount, chroma_amount=0.0):
     color = HCYColor(color)
     color.y = limit(color.y + luma_amount,   min=0.0, max=1.0)
     color.c = limit(color.c + chroma_amount, min=0.0, max=1.0)
     return color.qColor()
示例#40
0
 def put(self, key, value):
     expiration = value.expiration-time()
     if expiration > 0:
         self.data[key] = value
         reactor.callLater(limit(expiration, max=3600), self.data.pop, key, None)
示例#41
0
 def _igamma(value):
     return limit(value, 0.0, 1.0) ** (1.0 / 2.2)
示例#42
0
    def _sip_subscription_handler(self, command):
        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        account = DefaultAccount()
        refresh_interval = getattr(command, "refresh_interval", None) or account.sip.subscribe_interval

        try:
            # Lookup routes
            if account.sip.outbound_proxy is not None:
                uri = SIPURI(
                    host=account.sip.outbound_proxy.host,
                    port=account.sip.outbound_proxy.port,
                    parameters={"transport": account.sip.outbound_proxy.transport},
                )
            else:
                uri = SIPURI(host=self.sip_identity.uri.as_sip_uri().host)
            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(uri, settings.sip.transport_list).wait()
            except DNSLookupError, e:
                timeout = random.uniform(15, 30)
                raise SubscriptionError(error="DNS lookup failed: %s" % e, timeout=timeout)

            timeout = time() + 30
            for route in routes:
                remaining_time = timeout - time()
                if remaining_time > 0:
                    transport = route.transport
                    parameters = {} if transport == "udp" else {"transport": transport}
                    contact_uri = SIPURI(
                        user=account.contact.username,
                        host=SIPConfig.local_ip.normalized,
                        port=getattr(Engine(), "%s_port" % transport),
                        parameters=parameters,
                    )
                    subscription_uri = self.sip_identity.uri.as_sip_uri()
                    subscription = Subscription(
                        subscription_uri,
                        FromHeader(self.xmpp_identity.uri.as_sip_uri()),
                        ToHeader(subscription_uri),
                        ContactHeader(contact_uri),
                        "presence",
                        RouteHeader(route.uri),
                        refresh=refresh_interval,
                    )
                    notification_center.add_observer(self, sender=subscription)
                    try:
                        subscription.subscribe(timeout=limit(remaining_time, min=1, max=5))
                    except SIPCoreError:
                        notification_center.remove_observer(self, sender=subscription)
                        raise SubscriptionError(error="Internal error", timeout=5)
                    self._sip_subscription = subscription
                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.sender is subscription and notification.name == "SIPSubscriptionDidStart":
                                break
                    except SIPSubscriptionDidFail, e:
                        notification_center.remove_observer(self, sender=subscription)
                        self._sip_subscription = None
                        if e.data.code == 407:
                            # Authentication failed, so retry the subscription in some time
                            raise SubscriptionError(error="Authentication failed", timeout=random.uniform(60, 120))
                        elif e.data.code == 403:
                            # Forbidden
                            raise SubscriptionError(error="Forbidden", timeout=None, fatal=True)
                        elif e.data.code == 423:
                            # Get the value of the Min-Expires header
                            if e.data.min_expires is not None and e.data.min_expires > refresh_interval:
                                interval = e.data.min_expires
                            else:
                                interval = None
                            raise SubscriptionError(
                                error="Interval too short", timeout=random.uniform(60, 120), refresh_interval=interval
                            )
                        elif e.data.code in (405, 406, 489):
                            raise SubscriptionError(error="Method or event not supported", timeout=None, fatal=True)
                        elif e.data.code == 1400:
                            raise SubscriptionError(error=e.data.reason, timeout=None, fatal=True)
                        else:
                            # Otherwise just try the next route
                            continue
                    else:
                        self.subscribed = True
                        command.signal()
                        break
示例#43
0
                retry_after = random.uniform(self._dns_wait, 2*self._dns_wait)
                self._dns_wait = limit(2*self._dns_wait, max=30)
                raise PublicationError('DNS lookup failed: %s' % e, retry_after=retry_after)
            else:
                self._dns_wait = 1

            body = None if command.state is SameState else command.state.toxml()

            # Publish by trying each route in turn
            publish_timeout = time() + 30
            for route in routes:
                remaining_time = publish_timeout-time()
                if remaining_time > 0:
                    try:
                        try:
                            self._publication.publish(body, RouteHeader(route.uri), timeout=limit(remaining_time, min=1, max=10))
                        except PublicationETagError:
                            state = self.state # access self.state only once to avoid race conditions
                            if state is not None:
                                self._publication.publish(state.toxml(), RouteHeader(route.uri), timeout=limit(remaining_time, min=1, max=10))
                            else:
                                command.signal()
                                return
                    except SIPCoreError:
                        raise PublicationError('Internal error', retry_after=5)

                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.name == 'SIPPublicationDidSucceed':
                                break
示例#44
0
    def paintEvent(self, event):
        option = QStyleOption()
        option.initFrom(self)

        contents_rect = self.style().subElementRect(QStyle.SE_FrameContents, option, self) or self.contentsRect()  # the SE_FrameContents rect is Null unless the stylesheet defines decorations

        if self.graphStyle == self.BarStyle:
            graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width()) / self.horizontalPixelsPerUnit))
        else:
            graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width() - 1) / self.horizontalPixelsPerUnit) + 1)

        max_value = self.__dict__['max_value'] = max(chain([0], *(islice(reversed(graph.data), graph_width) for graph in self.graphs if graph.enabled)))

        if self.graphHeight == self.AutomaticHeight or self.graphHeight < 0:
            graph_height = self.__dict__['graph_height'] = max(self.scaler.get_height(max_value), self.minHeight)
        else:
            graph_height = self.__dict__['graph_height'] = max(self.graphHeight, self.minHeight)

        if self.graphStyle == self.BarStyle:
            height_scaling = float(contents_rect.height()) / graph_height
        else:
            height_scaling = float(contents_rect.height() - self.lineThickness) / graph_height

        painter = QStylePainter(self)
        painter.drawPrimitive(QStyle.PE_Widget, option)

        painter.setClipRect(contents_rect)

        painter.save()
        painter.translate(contents_rect.x() + contents_rect.width() - 1, contents_rect.y() + contents_rect.height() - 1)
        painter.scale(-1, -1)

        painter.setRenderHint(QStylePainter.Antialiasing, self.graphStyle != self.BarStyle)

        for graph in (graph for graph in self.graphs if graph.enabled and graph.data):
            if self.boundary is not None and 0 < self.boundary < graph_height:
                boundary_width = min(5.0/height_scaling, self.boundary-0, graph_height-self.boundary)
                pen_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling)
                pen_color.setColorAt(0, graph.color)
                pen_color.setColorAt(1, graph.over_boundary_color)
                brush_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling)
                brush_color.setColorAt(0, self.color_with_alpha(graph.color, self.fillTransparency))
                brush_color.setColorAt(1, self.color_with_alpha(graph.over_boundary_color, self.fillTransparency))
            else:
                pen_color = graph.color
                brush_color = self.color_with_alpha(graph.color, self.fillTransparency)
            dataset = islice(reversed(graph.data), graph_width)
            if self.graphStyle == self.BarStyle:
                lines = [QLineF(x*self.horizontalPixelsPerUnit, 0, x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)]
                painter.setPen(QPen(pen_color, self.lineThickness))
                painter.drawLines(lines)
            else:
                painter.translate(0, +self.lineThickness/2 - 1)

                if self.smoothEnvelope and self.smoothFactor > 0:
                    min_value = 0
                    max_value = graph_height * height_scaling
                    cx_offset = self.horizontalPixelsPerUnit / 3.0
                    smoothness = self.smoothFactor

                    last_values = deque(3*[next(dataset) * height_scaling], maxlen=3)  # last 3 values: 0 last, 1 previous, 2 previous previous

                    envelope = QPainterPath()
                    envelope.moveTo(0, last_values[0])
                    for x, y in enumerate(dataset, 1):
                        x = x * self.horizontalPixelsPerUnit
                        y = y * height_scaling * (1 - smoothness) + last_values[0] * smoothness
                        last_values.appendleft(y)
                        c1x = x - cx_offset * 2
                        c2x = x - cx_offset
                        c1y = limit((1 + smoothness) * last_values[1] - smoothness * last_values[2], min_value, max_value)  # same gradient as previous previous value to previous value
                        c2y = limit((1 - smoothness) * last_values[0] + smoothness * last_values[1], min_value, max_value)  # same gradient as previous value to last value
                        envelope.cubicTo(c1x, c1y, c2x, c2y, x, y)
                else:
                    envelope = QPainterPath()
                    envelope.addPolygon(QPolygonF([QPointF(x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)]))

                if self.fillEnvelope or graph.fill_envelope:
                    first_element = envelope.elementAt(0)
                    last_element = envelope.elementAt(envelope.elementCount() - 1)
                    fill_path = QPainterPath()
                    fill_path.moveTo(last_element.x, last_element.y)
                    fill_path.lineTo(last_element.x + 1, last_element.y)
                    fill_path.lineTo(last_element.x + 1, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, first_element.y)
                    fill_path.connectPath(envelope)
                    painter.fillPath(fill_path, brush_color)

                painter.strokePath(envelope, QPen(pen_color, self.lineThickness, join=Qt.RoundJoin))

                painter.translate(0, -self.lineThickness/2 + 1)

        if self.boundary is not None and self.boundaryColor:
            painter.setRenderHint(QStylePainter.Antialiasing, False)
            painter.setPen(QPen(self.boundaryColor, 1.0))
            painter.drawLine(0, self.boundary*height_scaling, contents_rect.width(), self.boundary*height_scaling)

        painter.restore()

        # queue the 'updated' signal to be emitted after returning to the main loop
        QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection)
示例#45
0
 # Register by trying each route in turn
 register_timeout = time() + 30
 for route in routes:
     remaining_time = register_timeout-time()
     if remaining_time > 0:
         try:
             contact_uri = self.account.contact[NoGRUU, route]
         except KeyError:
             continue
         contact_header = ContactHeader(contact_uri)
         contact_header.parameters['+sip.instance'] = '"<%s>"' % settings.instance_id
         if self.account.nat_traversal.use_ice:
             contact_header.parameters['+sip.ice'] = None
         route_header = RouteHeader(route.uri)
         try:
             self._registration.register(contact_header, route_header, timeout=limit(remaining_time, min=1, max=10))
         except SIPCoreError:
             raise RegistrationError('Internal error', retry_after=5)
         try:
             while True:
                 notification = self._data_channel.wait()
                 if notification.name == 'SIPRegistrationDidSucceed':
                     break
                 if notification.name == 'SIPRegistrationDidEnd':
                     raise RegistrationError('Registration expired', retry_after=0)  # registration expired while we were trying to re-register
         except SIPRegistrationDidFail, e:
             notification_data = NotificationData(code=e.data.code, reason=e.data.reason, registration=self._registration, registrar=route)
             notification_center.post_notification('SIPAccountRegistrationGotAnswer', sender=self.account, data=notification_data)
             if e.data.code == 401:
                 # Authentication failed, so retry the registration in some time
                 raise RegistrationError('Authentication failed', retry_after=random.uniform(60, 120))
示例#46
0
    def _CH_publish(self, command):
        if command.state is None or self._publication is None and command.state is SameState:
            command.signal()
            return

        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()

        if self._publication_timer is not None and self._publication_timer.active():
            self._publication_timer.cancel()
        self._publication_timer = None

        if self._publication is None:
            duration = command.refresh_interval or self.account.sip.publish_interval
            from_header = FromHeader(self.account.uri, self.account.display_name)
            self._publication = Publication(from_header, self.event, self.payload_type.content_type, credentials=self.account.credentials, duration=duration, extra_headers=self.extra_headers)
            notification_center.add_observer(self, sender=self._publication)
            notification_center.post_notification(self.__class__.__name__ + 'WillPublish', sender=self, data=NotificationData(state=command.state, duration=duration))
        else:
            notification_center.post_notification(self.__class__.__name__ + 'WillRefresh', sender=self, data=NotificationData(state=command.state))

        try:
            if Host.default_ip is None:
                raise PublicationError('No IP address', retry_after=60)

            # Lookup routes
            valid_transports = self.__transports__.intersection(settings.sip.transport_list)
            if self.account.sip.outbound_proxy is not None and self.account.sip.outbound_proxy.transport in valid_transports:
                uri = SIPURI(host=self.account.sip.outbound_proxy.host, port=self.account.sip.outbound_proxy.port, parameters={'transport': self.account.sip.outbound_proxy.transport})
            else:
                uri = SIPURI(host=self.account.id.domain)

            lookup = DNSLookup()
            try:
                routes = lookup.lookup_sip_proxy(uri, valid_transports, tls_name=self.account.sip.tls_name).wait()
            except DNSLookupError as e:
                retry_after = random.uniform(self._dns_wait, 2*self._dns_wait)
                self._dns_wait = limit(2*self._dns_wait, max=30)
                raise PublicationError('DNS lookup failed: %s' % e, retry_after=retry_after)
            else:
                self._dns_wait = 1

            body = None if command.state is SameState else command.state.toxml()

            # Publish by trying each route in turn
            publish_timeout = time() + 30
            for route in routes:
                if Host.default_ip is None:
                    raise PublicationError('No IP address', retry_after=60)

                remaining_time = publish_timeout-time()
                if remaining_time > 0:
                    try:
                        try:
                            self._publication.publish(body, RouteHeader(route.uri), timeout=limit(remaining_time, min=1, max=10))
                        except ValueError as e:  # this happens for an initial PUBLISH with body=None
                            raise PublicationError(str(e), retry_after=0)
                        except PublicationETagError:
                            state = self.state # access self.state only once to avoid race conditions
                            if state is not None:
                                self._publication.publish(state.toxml(), RouteHeader(route.uri), timeout=limit(remaining_time, min=1, max=10))
                            else:
                                command.signal()
                                return
                    except SIPCoreError:
                        raise PublicationError('Internal error', retry_after=5)

                    try:
                        while True:
                            notification = self._data_channel.wait()
                            if notification.name == 'SIPPublicationDidSucceed':
                                break
                            if notification.name == 'SIPPublicationDidEnd':
                                raise PublicationError('Publication expired', retry_after=random.uniform(60, 120))  # publication expired while we were trying to re-publish
                    except SIPPublicationDidFail as e:
                        if e.data.code == 407:
                            # Authentication failed, so retry the publication in some time
                            raise PublicationError('Authentication failed', retry_after=random.uniform(60, 120))
                        elif e.data.code == 412:
                            raise PublicationError('Conditional request failed', retry_after=0)
                        elif e.data.code == 423:
                            # Get the value of the Min-Expires header
                            if e.data.min_expires is not None and e.data.min_expires > self.account.sip.publish_interval:
                                refresh_interval = e.data.min_expires
                            else:
                                refresh_interval = None
                            raise PublicationError('Interval too short', retry_after=random.uniform(60, 120), refresh_interval=refresh_interval)
                        elif e.data.code in (405, 406, 489):
                            raise PublicationError('Method or event not supported', retry_after=3600)
                        else:
                            # Otherwise just try the next route
                            continue
                    else:
                        self.publishing = True
                        self._publish_wait = 1
                        command.signal()
                        break
            else:
                # There are no more routes to try, reschedule the publication
                retry_after = random.uniform(self._publish_wait, 2*self._publish_wait)
                self._publish_wait = limit(self._publish_wait*2, max=30)
                raise PublicationError('No more routes to try', retry_after=retry_after)
        except PublicationError as e:
            self.publishing = False
            notification_center.remove_observer(self, sender=self._publication)
            def publish(e):
                if self.active:
                    self._command_channel.send(Command('publish', event=command.event, state=self.state, refresh_interval=e.refresh_interval))
                else:
                    command.signal()
                self._publication_timer = None
            self._publication_timer = reactor.callLater(e.retry_after, publish, e)
            self._publication = None
            notification_center.post_notification(self.__nickname__ + 'PublicationDidFail', sender=self, data=NotificationData(reason=e.error))
        else:
            notification_center.post_notification(self.__nickname__ + 'PublicationDidSucceed', sender=self)
示例#47
0
                self._dns_wait = 1

            body = None if command.state is SameState else command.state.toxml(
            )

            # Publish by trying each route in turn
            publish_timeout = time() + 30
            for route in routes:
                remaining_time = publish_timeout - time()
                if remaining_time > 0:
                    try:
                        try:
                            self._publication.publish(body,
                                                      RouteHeader(route.uri),
                                                      timeout=limit(
                                                          remaining_time,
                                                          min=1,
                                                          max=10))
                        except ValueError as e:  # this happens for an initial PUBLISH with body=None
                            raise PublicationError(str(e), retry_after=0)
                        except PublicationETagError:
                            state = self.state  # access self.state only once to avoid race conditions
                            if state is not None:
                                self._publication.publish(
                                    state.toxml(),
                                    RouteHeader(route.uri),
                                    timeout=limit(remaining_time,
                                                  min=1,
                                                  max=10))
                            else:
                                command.signal()
                                return