+ use an svg for the default avatar + When we accept a watcher and add it as a contact, it has no display name. We can take it from offline/online presence info instead + When a contact is removed and it had "Exchange presence info" enabled, we should remove its uris from the allowed contact list and add them to the blocked contact list (actually check if this is what we want) + When "Exchange availability information" is disabled, we still get presence updates until blink is restarted + If a uri was blocked then later added to a contact, it will still retain an addressbook policy with policy=blocked, even if "Exchange availability information" is enabled. Despite this, the accounts seem to exchange presence info without problems. + Add the ability to merge contacts ZRTP ---- - decide between separate checkbox to enable/disable RTP encryption vs having "Disabled" integrated in the combobox - key negotiation notes label in preferences Video fixes ----------- - consider if we should always show the mute/hold/close buttons (even in attached mode)? - run the preview at the normal framerate before we connect (while big)? - hide scrollbar in chat widget when video is overlayed on it? - right click on camera preview bring up context menu to select camera - make detaching animation have a duration that is proportional with the distance traveled, so that it appears to be similarly fast no matter how far it detaches - maybe don't show the camera preview if the video device is None - hide preview (and buttons?) while we animate? - preview limited to parent (resize still has issues) - double click to restore default size for preview? (might be problematic) - if audio is removed blink-qt puts the session on hold 5 seconds later when the AudioSessionItem is destroyed - custom icons for each window (chat, video, file transfer, ...) Code refactoring ---------------- + adjust web view spacing and margins for widgets (relative to window borders) + do not kill greenlets but interrupt commands instead (sipsimple) - refactor how models/dialogs/windows are created and where are they kept Issues ------ - tls cert text editors have the clear button cover the text - have a random conference room be joined if no room is specified - raise publish/subscribe intervals to 3600? what about register? - review the change to only play a hangup tone when session has audio/video - apply the default font/size from the theme to the input textbox? - in Smooth Operator check if the src attribute is still needed in elements that have the x-color class. there used to be a rule that matched elements with an x-color class which also had a src attribute pointing to a particular image, but since that was removed, no other rule matching an element with the x-color class cares for the src attribute. check if the src attribute on a span tag means anything, if not it can probably be safely removed from message.html and message_continuation.html - don't show selected audio device on the incoming dialog for chat - reconsider the busy button on the incoming dialog (replace with ignore?) - when a session is closed the chat window shows: "Disconnected: Connection was closed cleanly", but when calling oneself and a loop is detected is only says "Disconnected". It should actually only say Disconnected when the connection is ended normally and show the failure reason if not. Also when a connection is ended voluntarily it should not care if there is a failure while stopping the streams. - decide what to do about having keyboard shortcuts for hold/hangup in the chat window (list may not be visible all the time and here we also differentiate between hangup and delete session) - move tray icon from the main window to Blink? - there are session transitions that do not change the state (for example a stream that is removed, either by local or remote, never switches the state to sent/received_proposal and back. this means that one cannot rely on BlinkSessionDidChangeState alone to handle session transitions, but instead needs to also listed to BlinkSessionDidRemoveStream. - I got an incoming call and the contact was found as a google contact, but in history I have no name and the original uri. if I dial back, it doesn't find the contact and says number@domain for the name. - not sure about passing a Contact object to the session instead of contact.settings. - the DummyContact should follow the other contact APIs (have an id, ...) in order to be usable in their place. - have a contact.default_streams that returns a list of StreamDescription? - have a contact.account property that returns the best account for outgoing? Ideas: ------ - chat window alternate minimum sizes: 900x550 (230 splitter), 925x550 (240 splitter), 950x550 (250 splitter) CPU usage increases for video: ------------------------------ painting camera preview @10fps (static image no producer connected) in chat: +4-5% detached: +3-4% fullscren: +4-7% producer @25fps connected, not painting in chat: +8-9% detached: +8-9% fullscreen: +6-7% producer @25fps connected, painting @10fps in chat: +13-14% detached: +12% fullscreen: +12-15% - exceptions: Unhandled Error Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 754, in run self.__target(*self.__args, **self.__kwargs) File "/home/dan/work/voip/python-sipsimple/sipsimple/application.py", line 141, in _run_reactor reactor.run(installSignalHandlers=False) File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1199, in run self.mainLoop() File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1208, in mainLoop self.runUntilCurrent() --- <exception caught here> --- File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 828, in runUntilCurrent call.func(*call.args, **call.kw) File "/usr/lib/python2.7/dist-packages/eventlib/api.py", line 241, in _spawn g.switch() File "/usr/lib/python2.7/dist-packages/eventlib/api.py", line 237, in _spawn_startup return cb(*args, **kw) File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 380, in add_participant referral_handler.start() File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 181, in start if not self.session.remote_focus: exceptions.AttributeError: 'ReferralHandler' object has no attribute 'session' Traceback (most recent call last): File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 5015, in dropEvent if model.handleDroppedData(event.mimeData(), event.dropAction(), self.indexAt(event.pos())): File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 4840, in handleDroppedData return handler(mime_data, action, index) File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 4850, in _DH_ApplicationXBlinkContactList self.session.server_conference.add_participant(contact, contact.uri) File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 1410, in add_participant if contact_uri.uri in self.participants: AttributeError: 'NoneType' object has no attribute 'uri' Unhandled Error Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 754, in run self.__target(*self.__args, **self.__kwargs) File "/home/dan/work/voip/python-sipsimple/sipsimple/application.py", line 141, in _run_reactor reactor.run(installSignalHandlers=False) File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1199, in run self.mainLoop() File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1208, in mainLoop self.runUntilCurrent() --- <exception caught here> --- File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 828, in runUntilCurrent call.func(*call.args, **call.kw) File "/usr/lib/python2.7/dist-packages/eventlib/api.py", line 241, in _spawn g.switch() File "/usr/lib/python2.7/dist-packages/eventlib/api.py", line 237, in _spawn_startup return cb(*args, **kw) File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 380, in add_participant referral_handler.start() File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 181, in start if not self.session.remote_focus: exceptions.AttributeError: 'ReferralHandler' object has no attribute 'session' Unhandled Error Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 754, in run self.__target(*self.__args, **self.__kwargs) File "/home/dan/work/voip/python-sipsimple/sipsimple/application.py", line 141, in _run_reactor reactor.run(installSignalHandlers=False) File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1199, in run self.mainLoop() File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1208, in mainLoop self.runUntilCurrent() --- <exception caught here> --- File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 828, in runUntilCurrent call.func(*call.args, **call.kw) File "/usr/lib/python2.7/dist-packages/eventlib/api.py", line 241, in _spawn g.switch() File "/usr/lib/python2.7/dist-packages/eventlib/api.py", line 237, in _spawn_startup return cb(*args, **kw) File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 380, in add_participant referral_handler.start() File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 181, in start if not self.session.remote_focus: exceptions.AttributeError: 'ReferralHandler' object has no attribute 'session' Traceback (most recent call last): File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 5015, in dropEvent if model.handleDroppedData(event.mimeData(), event.dropAction(), self.indexAt(event.pos())): File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 4840, in handleDroppedData return handler(mime_data, action, index) File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 4850, in _DH_ApplicationXBlinkContactList self.session.server_conference.add_participant(contact, contact.uri) File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 1410, in add_participant if contact_uri.uri in self.participants: AttributeError: 'NoneType' object has no attribute 'uri' error: Exception occured while calling function handle_notification in the GUI thread Traceback (most recent call last): File "/home/dan/work/voip/blink-qt/blink/__init__.py", line 278, in _EH_CallFunctionEvent event.function(*event.args, **event.kw) File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 5531, in handle_notification handler(notification) File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 5589, in _NH_SIPSessionNewIncoming session.send_ring_indication() File "<string>", line 1, in send_ring_indication File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 118, in wrapper raise IllegalStateError('cannot call %s in %s state' % (func.__name__, obj.state)) IllegalStateError: cannot call send_ring_indication in terminated state error: Exception occured in observer <blink.chatwindow.ChatWindow object at 0xab33d5cc> while handling notification 'BlinkSessionInfoUpdated' Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/application/notification.py", line 216, in post_notification observer.handle_notification(notification) File "<string>", line 1, in handle_notification File "/home/dan/work/voip/blink-qt/blink/util.py", line 36, in wrapper function(*args, **kw) File "/home/dan/work/voip/blink-qt/blink/chatwindow.py", line 1653, in handle_notification handler(notification) File "/home/dan/work/voip/blink-qt/blink/chatwindow.py", line 1767, in _NH_BlinkSessionInfoUpdated self._update_session_info_panel(elements=notification.data.elements) File "/home/dan/work/voip/blink-qt/blink/chatwindow.py", line 1481, in _update_session_info_panel self.video_value_label.setText(video_info.codec or 'N/A') File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 158, in codec return '{0.codec_name} {0.framerate:.3g}fps'.format(self) if self.codec_name else None ValueError: Unknown format code 'g' for object of type 'str' error: Exception occured in observer <blink.sessions.AudioSessionListView object at 0xab545464> while handling notification 'BlinkActiveSessionDidChange' Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/application/notification.py", line 216, in post_notification observer.handle_notification(notification) File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 2632, in handle_notification handler(notification) File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 2646, in _NH_BlinkActiveSessionDidChange position = model.sessions.index(notification.data.active_session.items.audio) ValueError: None is not in list error: Exception occured in observer <sipsimple.streams.msrp.ScreenSharingStream object at 0x7fa65c2a3550> while handling notification 'MediaStreamWillEnd' Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/application/notification.py", line 216, in post_notification observer.handle_notification(notification) File "/home/saghul/work/ag-projects/video/python-sipsimple/sipsimple/streams/msrp.py", line 280, in handle_notification handler(notification) File "/home/saghul/work/ag-projects/video/python-sipsimple/sipsimple/streams/msrp.py", line 1050, in _NH_MediaStreamWillEnd notification.center.remove_observer(self, sender=self.handler) File "/usr/lib/python2.7/dist-packages/application/notification.py", line 163, in remove_observer raise KeyError("observer %r not registered for %r events from %r" % (observer, name, sender)) KeyError: 'observer <sipsimple.streams.msrp.ScreenSharingStream object at 0x7fa65c2a3550> not registered for Any events from <blink.sessions.ExternalVNCServerHandler object at 0x7fa65c2a3dd0>' Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 824, in runUntilCurrent call.func(*call.args, **call.kw) File "/usr/lib/python2.7/dist-packages/eventlib/coros.py", line 253, in _do_acquire waiter.switch() File "/usr/lib/python2.7/dist-packages/eventlib/api.py", line 235, in _spawn_startup return cb(*args, **kw) File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 1809, in hold self._send_hold() File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 1986, in _send_hold notification = self._channel.wait() File "/usr/lib/python2.7/dist-packages/eventlib/coros.py", line 478, in wait api.getcurrent().throw(*exc) MediaStreamDidFailError Traceback (most recent call last): File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 1130, in _SH_HangupButtonClicked self.end() File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 1102, in end self.blink_session.remove_stream(self.audio_stream) File "/home/dan/work/voip/blink-qt/blink/sessions.py", line 592, in remove_stream self.sip_session.remove_stream(stream) File "<string>", line 1, in remove_stream File "/home/dan/work/voip/python-sipsimple/sipsimple/session.py", line 100, in wrapper raise IllegalStateError('cannot call %s in %s state' % (func.__name__, obj.state)) sipsimple.session.IllegalStateError: cannot call remove_stream in sending_proposal state Presence -------- - Is picking the most recent timestamp a good winning method? - Calculate user idleness - Add a GUI element for the offline note - Delete own icon if we don't get anything back from XCAP? - Unify settings for inbound and outbound presence