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
c50e8d0d
Commit
c50e8d0d
authored
Jul 07, 2023
by
Tijmen de Mes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added support for filetransfer messages
parent
7b3177e6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
349 additions
and
7 deletions
+349
-7
chatwindow.py
blink/chatwindow.py
+233
-5
messages.py
blink/messages.py
+115
-1
message.py
blink/streams/message.py
+1
-1
No files found.
blink/chatwindow.py
View file @
c50e8d0d
...
...
@@ -6,13 +6,13 @@ import re
import
uuid
from
PyQt5
import
uic
from
PyQt5.QtCore
import
Qt
,
QBuffer
,
QEasingCurve
,
QEvent
,
QPoint
,
QPointF
,
QPropertyAnimation
,
QRect
,
QRectF
,
QSettings
,
QSize
,
QSizeF
,
QTimer
,
QUrl
,
pyqtSignal
from
PyQt5.QtCore
import
Qt
,
QBuffer
,
QEasingCurve
,
QEvent
,
QPoint
,
QPointF
,
QPropertyAnimation
,
QRect
,
QRectF
,
QSettings
,
QSize
,
QSizeF
,
QTimer
,
QUrl
,
pyqtSignal
,
QFileInfo
from
PyQt5.QtGui
import
QBrush
,
QColor
,
QIcon
,
QImageReader
,
QKeyEvent
,
QLinearGradient
,
QPainter
,
QPalette
,
QPen
,
QPixmap
,
QPolygonF
,
QTextCharFormat
,
QTextCursor
,
QTextDocument
from
PyQt5.QtGui
import
QDesktopServices
from
PyQt5.QtWebKit
import
QWebSettings
from
PyQt5.QtWebKitWidgets
import
QWebPage
,
QWebView
from
PyQt5.QtWidgets
import
QApplication
,
QAction
,
QLabel
,
QListView
,
QMenu
,
QStyle
,
QStyleOption
,
QStylePainter
,
QTextEdit
,
QToolButton
from
PyQt5.QtWidgets
import
QFileDialog
from
PyQt5.QtWidgets
import
QFileDialog
,
QFileIconProvider
from
abc
import
ABCMeta
,
abstractmethod
from
application.notification
import
IObserver
,
NotificationCenter
,
ObserverWeakrefProxy
,
NotificationData
...
...
@@ -34,17 +34,19 @@ from sipsimple.account import AccountManager
from
sipsimple.application
import
SIPApplication
from
sipsimple.audio
import
WavePlayer
from
sipsimple.configuration.settings
import
SIPSimpleSettings
from
sipsimple.payloads
import
ParserError
from
sipsimple.payloads.rcsfthttp
import
FTHTTPDocument
from
sipsimple.streams.msrp.chat
import
OTRState
from
sipsimple.threading
import
run_in_thread
from
sipsimple.util
import
ISOTimestamp
from
blink.configuration.datatypes
import
FileURL
,
GraphTimeScale
from
blink.configuration.datatypes
import
File
,
File
URL
,
GraphTimeScale
from
blink.configuration.settings
import
BlinkSettings
from
blink.contacts
import
URIUtils
from
blink.history
import
HistoryManager
from
blink.messages
import
MessageManager
,
BlinkMessage
from
blink.resources
import
IconManager
,
Resources
from
blink.sessions
import
ChatSessionModel
,
ChatSessionListView
,
SessionManager
,
StreamDescription
from
blink.sessions
import
ChatSessionModel
,
ChatSessionListView
,
SessionManager
,
StreamDescription
,
FileSizeFormatter
from
blink.util
import
run_in_gui_thread
,
call_later
,
translate
,
copy_transfer_file
from
blink.widgets.color
import
ColorHelperMixin
from
blink.widgets.graph
import
Graph
...
...
@@ -580,6 +582,28 @@ class ChatTextInput(QTextEdit):
self
.
setTextCursor
(
cursor
)
class
FileIcon
(
object
):
def
__new__
(
cls
,
filename
):
icon
=
QFileIconProvider
()
.
icon
(
QFileInfo
(
filename
))
image
=
icon
.
pixmap
(
32
)
image_buffer
=
QBuffer
()
image_format
=
'png'
if
image
.
hasAlphaChannel
()
else
'jpeg'
image
.
save
(
image_buffer
,
image_format
)
image_data
=
image_buffer
.
data
()
instance
=
super
(
FileIcon
,
cls
)
.
__new__
(
cls
)
instance
.
__dict__
[
'data'
]
=
image_data
instance
.
__dict__
[
'type'
]
=
'image/{}'
.
format
(
image_format
)
return
instance
@
property
def
data
(
self
):
return
self
.
__dict__
[
'data'
]
@
property
def
type
(
self
):
return
self
.
__dict__
[
'type'
]
class
IconDescriptor
(
object
):
def
__init__
(
self
,
filename
):
self
.
filename
=
filename
...
...
@@ -598,6 +622,16 @@ class IconDescriptor(object):
raise
AttributeError
(
"attribute cannot be deleted"
)
class
AudioDescriptor
(
object
):
def
__new__
(
cls
,
filename
):
basename
=
os
.
path
.
basename
(
filename
)
if
basename
.
startswith
(
'sylk-audio-recording'
):
instance
=
super
(
AudioDescriptor
,
cls
)
.
__new__
(
cls
)
else
:
instance
=
None
return
instance
class
Thumbnail
(
object
):
def
__new__
(
cls
,
filename
):
image_reader
=
QImageReader
(
filename
)
...
...
@@ -664,7 +698,6 @@ ui_class, base_class = uic.loadUiType(Resources.get('chat_widget.ui'))
@
implementer
(
IObserver
)
class
ChatWidget
(
base_class
,
ui_class
):
default_user_icon
=
IconDescriptor
(
Resources
.
get
(
'icons/default-avatar.png'
))
checkmark_icon
=
IconDescriptor
(
Resources
.
get
(
'icons/checkmark.svg'
))
warning_icon
=
IconDescriptor
(
Resources
.
get
(
'icons/warning.svg'
))
...
...
@@ -1693,6 +1726,8 @@ class ChatWindow(base_class, ui_class, ColorHelperMixin):
self
.
pending_displayed_notifications
=
{}
self
.
render_after_load
=
[]
self
.
fetch_afer_load
=
deque
()
notification_center
=
NotificationCenter
()
notification_center
.
add_observer
(
self
,
name
=
'SIPApplicationDidStart'
)
notification_center
.
add_observer
(
self
,
name
=
'BlinkSessionNewIncoming'
)
...
...
@@ -1725,6 +1760,8 @@ class ChatWindow(base_class, ui_class, ColorHelperMixin):
notification_center
.
add_observer
(
self
,
name
=
'MessageStreamPGPKeysDidLoad'
)
notification_center
.
add_observer
(
self
,
name
=
'PGPMessageDidDecrypt'
)
notification_center
.
add_observer
(
self
,
name
=
'PGPMessageDidNotDecrypt'
)
notification_center
.
add_observer
(
self
,
name
=
'PGPFileDidDecrypt'
)
notification_center
.
add_observer
(
self
,
name
=
'BlinkHTTPFileTransferDidEnd'
)
# self.splitter.splitterMoved.connect(self._SH_SplitterMoved) # check this and decide on what size to have in the window (see Notes) -Dan
...
...
@@ -1784,6 +1821,7 @@ class ChatWindow(base_class, ui_class, ColorHelperMixin):
self
.
mute_button
.
setIcon
(
svg_icon
(
Resources
.
get
(
'icons/mic-on.svg'
),
Resources
.
get
(
'icons/mic-off.svg'
)))
self
.
hold_button
.
setIcon
(
svg_icon
(
Resources
.
get
(
'icons/pause.svg'
),
Resources
.
get
(
'icons/paused.svg'
)))
self
.
record_button
.
setIcon
(
svg_icon
(
Resources
.
get
(
'icons/record.svg'
),
Resources
.
get
(
'icons/recording.svg'
)))
self
.
control_button
.
setIcon
(
self
.
control_icon
)
self
.
control_menu
=
QMenu
(
self
.
control_button
)
...
...
@@ -2487,6 +2525,120 @@ class ChatWindow(base_class, ui_class, ColorHelperMixin):
def
_NH_ChatSessionItemDidChange
(
self
,
notification
):
self
.
_update_widgets_for_session
()
def
_parse_fthttp
(
self
,
blink_session
,
message
,
from_history
=
False
):
session
=
blink_session
.
items
.
chat
try
:
document
=
FTHTTPDocument
.
parse
(
message
.
content
)
except
ParserError
as
e
:
raise
ParserError
#log.warning('Failed to parse FT HTTP payload: %s' % str(e))
for
info
in
document
:
try
:
hash
=
info
.
hash
.
value
except
AttributeError
:
hash
=
None
if
from_history
:
id
=
message
.
message_id
else
:
id
=
message
.
id
file
=
File
(
info
.
file_name
.
value
,
info
.
file_size
.
value
,
blink_session
.
contact
,
hash
,
id
,
info
.
data
.
until
if
info
.
data
.
until
else
None
,
url
=
info
.
data
.
url
,
type
=
info
.
content_type
.
value
)
file
.
name
=
HistoryManager
()
.
get_decrypted_filename
(
file
)
is_audio_message
=
AudioDescriptor
(
info
.
file_name
.
value
)
try
:
if
info
.
data
.
until
<
datetime
.
now
(
timezone
.
utc
):
# session.chat_widget.add_message(ChatStatus(translate('chat_window', 'File transfer is expired: %s') % os.path.basename(info.file_name.value)))
if
not
file
.
already_exists
:
return
None
except
AttributeError
:
pass
if
not
info
.
content_type
.
value
.
startswith
(
'image/'
)
and
not
is_audio_message
:
icon
=
FileIcon
(
file
.
decrypted_filename
)
icon_data
=
base64
.
b64encode
(
icon
.
data
)
.
decode
()
content
=
'''<img src="data:{};base64,{}" class="scaled-to-fit" />'''
.
format
(
icon
.
type
,
icon_data
)
if
from_history
:
NotificationCenter
()
.
post_notification
(
'BlinkSessionDidShareFile'
,
sender
=
blink_session
,
data
=
NotificationData
(
file
=
file
,
direction
=
message
.
direction
))
return
'''<a href='
%
s#
%
s' style='text-decoration: none !important'><div style="display: flex;">
<div>
%
s</div>
<div style="display: flex; align-items: center;">
<div>
<div style="padding-left: 4px; font-size: 14px; font-weight: 400;">
%
s</div>
<div style="padding-left: 4px;">
%
s</div>
</div>
</div>
</div></a>'''
%
(
file
.
decrypted_filename
,
id
,
content
,
os
.
path
.
basename
(
file
.
decrypted_filename
),
FileSizeFormatter
.
format
(
file
.
size
))
if
message
.
direction
==
'outgoing'
:
if
is_audio_message
:
text
=
translate
(
'chat_window'
,
'You sent an audio message. Fetching and processing...'
)
else
:
text
=
translate
(
'chat_window'
,
'You sent an image:
%
s. Fetching and processing...'
%
file
.
decrypted_filename
)
else
:
if
is_audio_message
:
text
=
translate
(
'chat_window'
,
'Sent you an audio message. Processing...'
)
else
:
text
=
translate
(
'chat_window'
,
'Sent you an image:
%
s. Processing...'
%
file
.
decrypted_filename
)
content
=
f
'<img src={session.chat_widget.encrypted_icon.filename} class="inline-message-icon">{text}'
if
not
file
.
already_exists
:
if
file
.
encrypted
and
not
blink_session
.
fake_streams
.
get
(
'messages'
)
.
can_decrypt
:
content
=
translate
(
'chat_window'
,
"
%
s can't be decrypted. PGP is disabled"
%
(
os
.
path
.
basename
(
file
.
decrypted_filename
)))
return
content
if
from_history
:
self
.
fetch_afer_load
.
append
((
blink_session
,
file
,
message
,
info
))
NotificationCenter
()
.
post_notification
(
'BlinkSessionDidShareFile'
,
sender
=
blink_session
,
data
=
NotificationData
(
file
=
file
,
direction
=
message
.
direction
))
return
content
if
hash
:
SessionManager
()
.
get_file
(
blink_session
.
contact
,
blink_session
.
contact_uri
,
file
.
name
,
file
.
hash
,
file
.
id
,
account
=
blink_session
.
account
,
conference_file
=
False
)
else
:
SessionManager
()
.
get_file_from_url
(
blink_session
,
file
)
return
content
if
is_audio_message
:
return
f
'''<div><audio controls style="height: 35px; width: 350px"><source src="{file.decrypted_filename}" type={file.type}></audio></div>'''
file_descriptors
=
[
FileDescriptor
(
file
.
decrypted_filename
)]
image_descriptors
=
[
descriptor
for
descriptor
in
file_descriptors
if
descriptor
.
thumbnail
is
not
None
]
if
not
image_descriptors
:
session
.
chat_widget
.
add_message
(
ChatStatus
(
translate
(
'chat_window'
,
'Error: image can not be rendered:
%
s'
)
%
os
.
path
.
basename
(
file
.
decrypted_filename
)))
return
None
for
image
in
image_descriptors
:
image_data
=
base64
.
b64encode
(
image
.
thumbnail
.
data
)
.
decode
()
content
=
'''<a href="{}" style='display: flex; border: 0 !important'><img src="data:{};base64,{}" class="scaled-to-fit" /></a>'''
.
format
(
image
.
fileurl
,
image
.
thumbnail
.
type
,
image_data
)
if
from_history
:
NotificationCenter
()
.
post_notification
(
'BlinkSessionDidShareFile'
,
sender
=
blink_session
,
data
=
NotificationData
(
file
=
file
,
direction
=
message
.
direction
))
return
content
def
_NH_BlinkGotMessage
(
self
,
notification
):
blink_session
=
notification
.
sender
session
=
blink_session
.
items
.
chat
...
...
@@ -2521,6 +2673,13 @@ class ChatWindow(base_class, ui_class, ColorHelperMixin):
else
:
content
=
message
.
content
content
=
HtmlProcessor
.
autolink
(
content
if
message
.
content_type
==
'text/html'
else
QTextDocument
(
content
)
.
toHtml
())
elif
message
.
content_type
.
lower
()
==
FTHTTPDocument
.
content_type
:
try
:
content
=
self
.
_parse_fthttp
(
blink_session
,
message
)
except
ParserError
:
return
if
content
is
None
:
return
else
:
return
...
...
@@ -2640,6 +2799,56 @@ class ChatWindow(base_class, ui_class, ColorHelperMixin):
return
session
.
chat_widget
.
add_message
(
ChatStatus
(
translate
(
'chat_window'
,
f
'Decryption failed: {notification.data.error}'
)))
def
_NH_BlinkHTTPFileTranfserDidEnd
(
self
,
notification
):
blink_session
=
notification
.
sender
if
blink_session
is
None
:
return
if
AudioDescriptor
(
notification
.
data
.
filename
):
content
=
f
'''<div><audio controls style="height: 35px; width: 350px" src="{notification.data.filename}"></audio></div>'''
blink_session
.
items
.
chat
.
chat_widget
.
update_message_text
(
notification
.
data
.
file
.
id
,
content
)
return
file_descriptors
=
[
FileDescriptor
(
notification
.
data
.
file
.
name
)]
image_descriptors
=
[
descriptor
for
descriptor
in
file_descriptors
if
descriptor
.
thumbnail
is
not
None
]
for
image
in
image_descriptors
:
image_data
=
base64
.
b64encode
(
image
.
thumbnail
.
data
)
.
decode
()
content
=
'''<a href="{}"><img src="data:{};base64,{}" class="scaled-to-fit" /></a>'''
.
format
(
image
.
fileurl
,
image
.
thumbnail
.
type
,
image_data
)
blink_session
.
items
.
chat
.
chat_widget
.
update_message_text
(
notification
.
data
.
file
.
id
,
content
)
def
_NH_PGPFileDidDecrypt
(
self
,
notification
):
transfer_session
=
notification
.
sender
blink_session
=
next
(
session
.
blink_session
for
session
in
self
.
session_model
.
sessions
if
session
.
blink_session
.
contact
.
settings
is
transfer_session
.
contact
.
settings
)
if
blink_session
is
None
:
return
if
AudioDescriptor
(
notification
.
data
.
filename
):
content
=
f
'''<div><audio controls style="height: 35px; width: 350px" src="{notification.data.filename}"></audio></div>'''
blink_session
.
items
.
chat
.
chat_widget
.
update_message_text
(
transfer_session
.
id
,
content
)
return
file_descriptors
=
[
FileDescriptor
(
notification
.
data
.
filename
)]
image_descriptors
=
[
descriptor
for
descriptor
in
file_descriptors
if
descriptor
.
thumbnail
is
not
None
]
for
image
in
image_descriptors
:
image_data
=
base64
.
b64encode
(
image
.
thumbnail
.
data
)
.
decode
()
content
=
'''<a href="{}"><img src="data:{};base64,{}" class="scaled-to-fit" /></a>'''
.
format
(
image
.
fileurl
,
image
.
thumbnail
.
type
,
image_data
)
blink_session
.
items
.
chat
.
chat_widget
.
update_message_text
(
transfer_session
.
id
,
content
)
def
_NH_PGPFileDidNotDecrypt
(
self
,
notification
):
transfer_session
=
notification
.
sender
blink_session
=
next
(
session
.
blink_session
for
session
in
self
.
session_model
.
sessions
if
session
.
blink_session
.
contact
.
settings
is
transfer_session
.
contact
.
settings
)
if
blink_session
is
None
:
return
session
.
chat_widget
.
replace_message
(
transfer_session
.
id
,
ChatStatus
(
translate
(
'chat_window'
,
f
'File decryption failed: {notification.data.error}'
)))
def
_NH_MessageStreamPGPKeysDidLoad
(
self
,
notification
):
stream
=
notification
.
sender
blink_session
=
stream
.
blink_session
...
...
@@ -2683,8 +2892,18 @@ class ChatWindow(base_class, ui_class, ColorHelperMixin):
else
:
content
=
message
.
content
content
=
HtmlProcessor
.
autolink
(
content
if
message
.
content_type
==
'text/html'
else
QTextDocument
(
content
)
.
toHtml
())
elif
message
.
content_type
.
lower
()
==
FTHTTPDocument
.
content_type
:
try
:
content
=
self
.
_parse_fthttp
(
blink_session
,
message
,
from_history
=
True
)
except
ParserError
as
e
:
continue
if
not
content
:
timestamp
=
message
.
timestamp
.
replace
(
tzinfo
=
timezone
.
utc
)
.
astimezone
(
tzlocal
())
continue
else
:
continue
# message.sender = SIPURI.parse(f'sip:{message.remote_uri}')
if
message
.
direction
==
'outgoing'
:
message
.
sender
=
blink_session
.
account
...
...
@@ -2731,6 +2950,14 @@ class ChatWindow(base_class, ui_class, ColorHelperMixin):
session
.
chat_widget
.
add_message
(
message
)
else
:
self
.
render_after_load
.
append
((
found_session
,
message
))
while
self
.
fetch_afer_load
:
(
blink_session
,
file
,
message
,
info
)
=
self
.
fetch_afer_load
.
popleft
()
if
file
.
hash
is
not
None
:
SessionManager
()
.
get_file
(
blink_session
.
contact
,
blink_session
.
contact_uri
,
file
.
original_name
,
file
.
hash
,
file
.
id
,
account
=
blink_session
.
account
,
conference_file
=
False
)
else
:
SessionManager
()
.
get_file_from_url
(
blink_session
,
file
)
session
.
chat_widget
.
show_loading_screen
(
False
)
def
_NH_BlinkMessageHistoryLoadDidFail
(
self
,
notification
):
...
...
@@ -2990,6 +3217,7 @@ class ChatWindow(base_class, ui_class, ColorHelperMixin):
self
.
tab_widget
.
setCurrentWidget
(
self
.
selected_session
.
chat_widget
)
# why do we switch the tab here, but do everything else in the selected_session property setter? -Dan
self
.
session_details
.
setCurrentWidget
(
self
.
selected_session
.
active_panel
)
self
.
participants_list
.
setModel
(
self
.
selected_session
.
participants_model
)
self
.
files_list
.
setModel
(
self
.
selected_session
.
files_model
)
self
.
control_button
.
setEnabled
(
True
)
if
not
self
.
isMinimized
():
self
.
send_pending_imdn_messages
(
self
.
selected_session
)
...
...
blink/messages.py
View file @
c50e8d0d
...
...
@@ -20,7 +20,7 @@ from application.notification import IObserver, NotificationCenter, Notification
from
application.python
import
Null
from
application.system
import
makedirs
from
application.python.types
import
Singleton
from
datetime
import
timezone
from
datetime
import
datetime
,
timezone
,
timedelta
from
dateutil.tz
import
tzlocal
,
tzutc
from
urllib.parse
import
urlsplit
,
urlunsplit
,
quote
from
zope.interface
import
implementer
...
...
@@ -34,10 +34,12 @@ from sipsimple.lookup import DNSLookup
from
sipsimple.payloads
import
ParserError
from
sipsimple.payloads.iscomposing
import
IsComposingDocument
,
IsComposingMessage
,
State
,
LastActive
,
Refresh
,
ContentType
from
sipsimple.payloads.imdn
import
IMDNDocument
,
DeliveryNotification
,
DisplayNotification
from
sipsimple.payloads.rcsfthttp
import
FTHTTPDocument
,
FileInfo
from
sipsimple.streams.msrp.chat
import
CPIMPayload
,
CPIMParserError
,
CPIMNamespace
,
CPIMHeader
,
ChatIdentity
,
Message
as
MSRPChatMessage
,
SimplePayload
from
sipsimple.threading
import
run_in_thread
from
sipsimple.util
import
ISOTimestamp
from
blink.configuration.datatypes
import
File
from
blink.logging
import
MessagingTrace
as
log
from
blink.resources
import
Resources
from
blink.sessions
import
SessionManager
,
StreamDescription
,
IncomingDialogBase
...
...
@@ -803,6 +805,75 @@ class MessageManager(object, metaclass=Singleton):
elif
content_type
==
'text/pgp-public-key'
:
if
message
[
'contact'
]
!=
account
.
id
:
self
.
_save_pgp_key
(
message
[
'content'
],
message
[
'contact'
])
elif
content_type
==
'application/sylk-file-transfer'
:
try
:
document
=
json
.
loads
(
message
[
'content'
])
except
Exception
as
e
:
log
.
warning
(
'Failed to parse file transfer history message:
%
s'
%
str
(
e
))
continue
from
blink.contacts
import
URIUtils
contact
,
contact_uri
=
URIUtils
.
find_contact
(
message
[
'contact'
])
try
:
until
=
document
[
'until'
]
except
KeyError
:
until
=
str
(
ISOTimestamp
(
datetime
.
now
()
+
timedelta
(
days
=
30
)))
try
:
hash
=
document
[
'hash'
]
except
KeyError
:
hash
=
None
new_body
=
FTHTTPDocument
.
create
(
file
=
[
FileInfo
(
file_size
=
document
[
'filesize'
],
file_name
=
document
[
'filename'
],
content_type
=
document
[
'filetype'
],
url
=
document
[
'url'
],
until
=
until
,
hash
=
hash
)])
sender
=
account
if
message
[
'direction'
]
==
'incoming'
:
sender
=
ChatIdentity
(
SIPURI
.
parse
(
f
'sip:{contact.uri.uri}'
),
contact
.
name
)
timestamp
=
ISOTimestamp
(
message
[
'timestamp'
])
.
replace
(
tzinfo
=
timezone
.
utc
)
.
astimezone
(
tzlocal
())
try
:
is_secure
=
document
[
'filename'
]
.
endswith
(
'.asc'
)
except
AttributeError
:
is_secure
=
False
history_message
=
BlinkMessage
(
new_body
.
decode
(),
FTHTTPDocument
.
content_type
,
sender
,
timestamp
=
timestamp
,
id
=
message
[
'message_id'
],
disposition
=
message
[
'disposition'
],
direction
=
message
[
'direction'
],
is_secure
=
is_secure
)
history_message_data
=
NotificationData
(
remote_uri
=
contact
.
uri
.
uri
,
message
=
history_message
,
state
=
'accepted'
,
encryption
=
'OpenPGP'
if
is_secure
else
None
)
notification_center
.
post_notification
(
'BlinkGotHistoryMessage'
,
sender
=
account
,
data
=
history_message_data
)
try
:
blink_session
=
next
(
session
for
session
in
self
.
sessions
if
session
.
contact
.
settings
is
contact
.
settings
)
except
StopIteration
:
continue
notification_center
.
post_notification
(
'BlinkGotMessage'
,
sender
=
blink_session
,
data
=
NotificationData
(
message
=
history_message
,
history
=
True
,
account
=
account
))
file
=
File
(
document
[
'filename'
],
document
[
'filesize'
],
contact
,
document
[
'hash'
],
message
[
'message_id'
],
ISOTimestamp
(
until
),
document
[
'url'
])
notification_center
.
post_notification
(
'BlinkSessionDidShareFile'
,
sender
=
blink_session
,
data
=
NotificationData
(
file
=
file
,
direction
=
message
[
'direction'
]))
elif
content_type
.
startswith
(
'text/'
):
if
message
[
'contact'
]
is
None
:
continue
...
...
@@ -1133,6 +1204,49 @@ class MessageManager(object, metaclass=Singleton):
notification_center
.
post_notification
(
'BlinkGotComposingIndication'
,
sender
=
blink_session
,
data
=
data
)
return
if
content_type
.
lower
()
==
FTHTTPDocument
.
content_type
:
log
.
info
(
"Messge is a filetransfer message"
)
try
:
document
=
FTHTTPDocument
.
parse
(
body
)
except
ParserError
as
e
:
log
.
warning
(
'Failed to parse FT HTTP payload:
%
s'
%
str
(
e
))
else
:
for
info
in
document
:
try
:
until
=
document
[
'until'
]
except
KeyError
:
until
=
ISOTimestamp
(
datetime
.
now
()
+
timedelta
(
days
=
30
))
try
:
hash
=
info
.
hash
.
value
except
AttributeError
:
hash
=
None
file
=
File
(
info
.
file_name
.
value
,
info
.
file_size
.
value
,
contact
,
hash
,
message_id
,
until
,
info
.
data
.
url
)
message
.
is_secure
=
info
.
file_name
.
value
.
endswith
(
'.asc'
)
notification_center
.
post_notification
(
'BlinkGotMessage'
,
sender
=
blink_session
,
data
=
NotificationData
(
message
=
message
,
account
=
account
))
history_message_data
=
NotificationData
(
remote_uri
=
contact
.
uri
.
uri
,
message
=
message
,
state
=
'accepted'
,
encryption
=
'OpenPGP'
if
file
.
encrypted
else
None
)
notification_center
.
post_notification
(
'BlinkGotHistoryMessage'
,
sender
=
account
,
data
=
history_message_data
)
notification
.
center
.
post_notification
(
'BlinkSessionDidShareFile'
,
sender
=
blink_session
,
data
=
NotificationData
(
file
=
file
,
direction
=
message
.
direction
))
if
not
content_type
.
lower
()
.
startswith
(
'text'
):
return
...
...
blink/streams/message.py
View file @
c50e8d0d
...
...
@@ -336,7 +336,7 @@ class MessageStream(object, metaclass=MediaStreamType):
log
.
info
(
f
'File saved: {full_decrypted_filepath}'
)
unlink
(
filename
)
notification_center
.
post_notification
(
'PGPFileDidDecrypt'
,
sender
=
session
,
data
=
NotificationData
(
filename
=
full_decrypted_filepath
,
account
=
account
,
id
=
transfer_session
.
id
))
notification_center
.
post_notification
(
'PGPFileDidDecrypt'
,
sender
=
session
,
data
=
NotificationData
(
filename
=
full_decrypted_filepath
,
account
=
account
))
return
log
.
warning
(
f
'-- Decryption failed for {filename}, error: {error}'
)
...
...
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