Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vmj-qt
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kulya
vmj-qt
Commits
2b5865e1
Commit
2b5865e1
authored
Apr 23, 2013
by
Saul Ibarra
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added initial history manager
parent
1f797630
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
182 additions
and
9 deletions
+182
-9
history.py
blink/history.py
+144
-0
mainwindow.py
blink/mainwindow.py
+35
-0
blink.ui
resources/blink.ui
+3
-9
No files found.
blink/history.py
0 → 100644
View file @
2b5865e1
# Copyright (C) 2013 AG Projects. See LICENSE for details.
#
__all__
=
[
'HistoryManager'
]
import
cPickle
as
pickle
from
application.notification
import
IObserver
,
NotificationCenter
from
application.python
import
Null
from
application.python.types
import
Singleton
from
collections
import
deque
from
datetime
import
datetime
from
zope.interface
import
implements
from
sipsimple.account
import
BonjourAccount
from
sipsimple.addressbook
import
AddressbookManager
from
sipsimple.threading
import
run_in_thread
from
blink.resources
import
ApplicationData
from
blink.util
import
run_in_gui_thread
class
HistoryManager
(
object
):
__metaclass__
=
Singleton
implements
(
IObserver
)
def
__init__
(
self
):
try
:
data
=
pickle
.
load
(
open
(
ApplicationData
.
get
(
'calls_history'
)))
except
Exception
:
self
.
missed_calls
=
deque
(
maxlen
=
10
)
self
.
placed_calls
=
deque
(
maxlen
=
10
)
self
.
received_calls
=
deque
(
maxlen
=
10
)
else
:
self
.
missed_calls
,
self
.
placed_calls
,
self
.
received_calls
=
data
notification_center
=
NotificationCenter
()
notification_center
.
add_observer
(
self
,
name
=
'SIPSessionDidEnd'
)
notification_center
.
add_observer
(
self
,
name
=
'SIPSessionDidFail'
)
@
run_in_thread
(
'file-io'
)
def
save
(
self
):
with
open
(
ApplicationData
.
get
(
'calls_history'
),
'wb+'
)
as
f
:
pickle
.
dump
((
self
.
missed_calls
,
self
.
placed_calls
,
self
.
received_calls
),
f
)
@
run_in_gui_thread
def
handle_notification
(
self
,
notification
):
handler
=
getattr
(
self
,
'_NH_
%
s'
%
notification
.
name
,
Null
)
handler
(
notification
)
def
_NH_SIPSessionDidEnd
(
self
,
notification
):
if
notification
.
sender
.
account
is
BonjourAccount
():
return
session
=
notification
.
sender
entry
=
HistoryEntry
.
from_session
(
session
)
if
session
.
direction
==
'incoming'
:
self
.
received_calls
.
append
(
entry
)
else
:
self
.
placed_calls
.
append
(
entry
)
self
.
save
()
def
_NH_SIPSessionDidFail
(
self
,
notification
):
if
notification
.
sender
.
account
is
BonjourAccount
():
return
session
=
notification
.
sender
entry
=
HistoryEntry
.
from_session
(
session
)
if
session
.
direction
==
'incoming'
:
if
notification
.
data
.
code
==
487
and
notification
.
data
.
failure_reason
==
'Call completed elsewhere'
:
self
.
received_calls
.
append
(
entry
)
else
:
self
.
missed_calls
.
append
(
entry
)
else
:
if
notification
.
data
.
code
==
487
:
entry
.
reason
=
'cancelled'
else
:
entry
.
reason
=
'
%
s (
%
s)'
%
(
notification
.
data
.
reason
or
notification
.
data
.
failure_reason
,
notification
.
data
.
code
)
self
.
placed_calls
.
append
(
entry
)
self
.
save
()
class
HistoryEntry
(
object
):
def
__init__
(
self
,
remote_identity
,
target_uri
,
account_id
,
call_time
,
duration
,
reason
=
None
):
self
.
remote_identity
=
remote_identity
self
.
target_uri
=
target_uri
self
.
account_id
=
account_id
self
.
call_time
=
call_time
self
.
duration
=
duration
self
.
reason
=
reason
@
classmethod
def
from_session
(
cls
,
session
):
if
session
.
start_time
is
None
and
session
.
end_time
is
not
None
:
# Session may have anded before it fully started
session
.
start_time
=
session
.
end_time
call_time
=
session
.
start_time
or
datetime
.
now
()
if
session
.
start_time
and
session
.
end_time
:
duration
=
session
.
end_time
-
session
.
start_time
else
:
duration
=
None
remote_identity
=
session
.
remote_identity
remote_uri_str
=
'
%
s@
%
s'
%
(
remote_identity
.
uri
.
user
,
remote_identity
.
uri
.
host
)
try
:
contact
=
next
(
contact
for
contact
in
AddressbookManager
()
.
get_contacts
()
if
remote_uri_str
in
(
addr
.
uri
for
addr
in
contact
.
uris
))
except
StopIteration
:
display_name
=
remote_identity
.
display_name
else
:
display_name
=
contact
.
name
if
display_name
:
remote_identity_str
=
'
%
s <
%
s>'
%
(
display_name
,
remote_uri_str
)
else
:
remote_identity_str
=
remote_uri_str
return
cls
(
remote_identity_str
,
remote_uri_str
,
unicode
(
session
.
account
.
id
),
call_time
,
duration
)
def
__unicode__
(
self
):
if
self
.
call_time
:
time
=
'
%
s'
%
format_date
(
self
.
call_time
)
else
:
time
=
''
if
self
.
duration
:
duration
=
' for '
if
self
.
duration
.
days
>
0
or
self
.
duration
.
seconds
>
3600
:
duration
+=
'
%
i hours, '
%
(
self
.
duration
.
days
*
3600
*
24
+
int
(
self
.
duration
.
seconds
/
3600
))
secs
=
self
.
duration
.
seconds
%
3600
duration
+=
'
%02
i:
%02
i'
%
(
int
(
secs
/
60
),
secs
%
60
)
else
:
duration
=
''
reason
=
'
%
s'
%
self
.
reason
.
title
()
if
self
.
reason
else
''
return
u'
%
s
%
s
%
s
%
s'
%
(
self
.
remote_identity
,
time
,
duration
,
reason
)
def
format_date
(
dt
):
now
=
datetime
.
now
()
delta
=
now
-
dt
if
(
dt
.
year
,
dt
.
month
,
dt
.
day
)
==
(
now
.
year
,
now
.
month
,
now
.
day
):
return
dt
.
strftime
(
"at
%
H:
%
M"
)
elif
delta
.
days
<=
1
:
return
"Yesterday at
%
s"
%
dt
.
strftime
(
"
%
H:
%
M"
)
elif
delta
.
days
<
7
:
return
dt
.
strftime
(
"on
%
A"
)
elif
delta
.
days
<
300
:
return
dt
.
strftime
(
"on
%
B
%
d"
)
else
:
return
dt
.
strftime
(
"on
%
Y-
%
m-
%
d"
)
blink/mainwindow.py
View file @
2b5865e1
...
...
@@ -21,6 +21,7 @@ from sipsimple.configuration.settings import SIPSimpleSettings
from
blink.aboutpanel
import
AboutPanel
from
blink.accounts
import
AccountModel
,
ActiveAccountModel
,
ServerToolsAccountModel
,
ServerToolsWindow
from
blink.contacts
import
BonjourNeighbour
,
Contact
,
Group
,
ContactEditorDialog
,
ContactModel
,
ContactSearchModel
,
GoogleContactsDialog
from
blink.history
import
HistoryManager
from
blink.preferences
import
PreferencesWindow
from
blink.sessions
import
ConferenceDialog
,
SessionManager
,
SessionModel
from
blink.configuration.datatypes
import
InvalidToken
...
...
@@ -155,6 +156,13 @@ class MainWindow(base_class, ui_class):
self
.
alert_devices_group
.
triggered
.
connect
(
self
.
_AH_AudioAlertDeviceChanged
)
# History menu actions
self
.
history_manager
=
HistoryManager
()
self
.
missed_calls_menu
.
aboutToShow
.
connect
(
self
.
_SH_MissedCallsMenuShown
)
self
.
missed_calls_menu
.
triggered
.
connect
(
self
.
_AH_HistoryEntryClicked
)
self
.
placed_calls_menu
.
aboutToShow
.
connect
(
self
.
_SH_PlacedCallsMenuShown
)
self
.
placed_calls_menu
.
triggered
.
connect
(
self
.
_AH_HistoryEntryClicked
)
self
.
received_calls_menu
.
aboutToShow
.
connect
(
self
.
_SH_ReceivedCallsMenuShown
)
self
.
received_calls_menu
.
triggered
.
connect
(
self
.
_AH_HistoryEntryClicked
)
# Tools menu actions
self
.
answering_machine_action
.
triggered
.
connect
(
self
.
_AH_EnableAnsweringMachineTriggered
)
...
...
@@ -328,6 +336,15 @@ class MainWindow(base_class, ui_class):
account
=
action
.
data
()
SessionManager
()
.
start_call
(
"Voicemail"
,
account
.
voicemail_uri
,
account
=
account
)
def
_AH_HistoryEntryClicked
(
self
,
action
):
account_manager
=
AccountManager
()
session_manager
=
SessionManager
()
try
:
account
=
account_manager
.
get_account
(
action
.
entry
.
account_id
)
except
KeyError
:
account
=
None
session_manager
.
start_call
(
None
,
action
.
entry
.
target_uri
,
account
=
account
)
def
_SH_AccountStateChanged
(
self
,
action
):
self
.
activity_note
.
setText
(
action
.
note
)
self
.
saved_account_state
=
None
...
...
@@ -510,6 +527,24 @@ class MainWindow(base_class, ui_class):
def
_SH_SwitchViewButtonChangedView
(
self
,
view
):
self
.
main_view
.
setCurrentWidget
(
self
.
contacts_panel
if
view
is
SwitchViewButton
.
ContactView
else
self
.
sessions_panel
)
def
_SH_MissedCallsMenuShown
(
self
):
self
.
missed_calls_menu
.
clear
()
for
entry
in
reversed
(
self
.
history_manager
.
missed_calls
):
action
=
self
.
missed_calls_menu
.
addAction
(
unicode
(
entry
))
action
.
entry
=
entry
def
_SH_PlacedCallsMenuShown
(
self
):
self
.
placed_calls_menu
.
clear
()
for
entry
in
reversed
(
self
.
history_manager
.
placed_calls
):
action
=
self
.
placed_calls_menu
.
addAction
(
unicode
(
entry
))
action
.
entry
=
entry
def
_SH_ReceivedCallsMenuShown
(
self
):
self
.
received_calls_menu
.
clear
()
for
entry
in
reversed
(
self
.
history_manager
.
received_calls
):
action
=
self
.
received_calls_menu
.
addAction
(
unicode
(
entry
))
action
.
entry
=
entry
@
run_in_gui_thread
def
handle_notification
(
self
,
notification
):
handler
=
getattr
(
self
,
'_NH_
%
s'
%
notification
.
name
,
Null
)
...
...
resources/blink.ui
View file @
2b5865e1
...
...
@@ -961,9 +961,6 @@ padding: 2px;</string>
<string>
&
History
</string>
</property>
<widget
class=
"QMenu"
name=
"missed_calls_menu"
>
<property
name=
"enabled"
>
<bool>
false
</bool>
</property>
<property
name=
"title"
>
<string>
&
Missed calls
</string>
</property>
...
...
@@ -973,9 +970,6 @@ padding: 2px;</string>
</property>
</widget>
<widget
class=
"QMenu"
name=
"placed_calls_menu"
>
<property
name=
"enabled"
>
<bool>
false
</bool>
</property>
<property
name=
"title"
>
<string>
&
Placed calls
</string>
</property>
...
...
@@ -985,9 +979,6 @@ padding: 2px;</string>
</property>
</widget>
<widget
class=
"QMenu"
name=
"received_calls_menu"
>
<property
name=
"enabled"
>
<bool>
false
</bool>
</property>
<property
name=
"title"
>
<string>
&
Received calls
</string>
</property>
...
...
@@ -1265,6 +1256,9 @@ padding: 2px;</string>
<property
name=
"shortcutContext"
>
<enum>
Qt::ApplicationShortcut
</enum>
</property>
<property
name=
"visible"
>
<bool>
false
</bool>
</property>
</action>
<action
name=
"manage_accounts_action"
>
<property
name=
"text"
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment