Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Robert Maerkisch
kaidan
Commits
b72c72a3
Verified
Commit
b72c72a3
authored
Jun 20, 2018
by
Linus Jahn
Committed by
Linus Jahn
Sep 15, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
media-sharing: Generate, send and receive image thumbnails
parent
007ba433
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
129 additions
and
33 deletions
+129
-33
src/MessageHandler.cpp
src/MessageHandler.cpp
+56
-29
src/MessageHandler.h
src/MessageHandler.h
+6
-0
src/UploadHandler.cpp
src/UploadHandler.cpp
+54
-4
src/UploadHandler.h
src/UploadHandler.h
+13
-0
No files found.
src/MessageHandler.cpp
View file @
b72c72a3
...
...
@@ -47,6 +47,7 @@
#include "gloox-extensions/reference.h"
#include "gloox-extensions/sims.h"
#include "gloox-extensions/jinglefile.h"
#include "gloox-extensions/bitsofbinarydata.h"
// Kaidan
#include "MessageModel.h"
#include "Notifications.h"
...
...
@@ -124,35 +125,8 @@ void MessageHandler::handleMessage(const gloox::Message &stanza, gloox::MessageS
msg
.
message
=
body
;
msg
.
type
=
MessageType
::
MessageText
;
// only text, no media
//
// Get media sharing (SIMS) information
//
const
gloox
::
Reference
*
ref
=
message
->
findExtension
<
gloox
::
Reference
>
(
gloox
::
EXT_REFERENCES
);
if
(
ref
&&
ref
->
getEmbeddedSIMS
())
{
gloox
::
SIMS
*
sims
=
ref
->
getEmbeddedSIMS
();
gloox
::
StringList
sources
=
sims
->
sources
();
for
(
auto
&
source
:
sources
)
{
if
(
source
.
rfind
(
"https://"
,
0
)
==
0
||
source
.
rfind
(
"http://"
,
0
)
==
0
)
{
msg
.
mediaUrl
=
QString
::
fromStdString
(
source
);
break
;
}
}
gloox
::
Jingle
::
File
*
file
=
sims
->
file
();
if
(
file
&&
file
->
valid
())
{
msg
.
message
=
QString
::
fromStdString
(
file
->
desc
());
msg
.
mediaSize
=
file
->
size
();
msg
.
mediaContentType
=
QString
::
fromStdString
(
file
->
mediaType
());
msg
.
mediaLastModified
=
stringToQDateTime
(
file
->
date
()).
toTime_t
();
QMimeType
mimeType
=
QMimeDatabase
().
mimeTypeForName
(
msg
.
mediaContentType
);
msg
.
type
=
getMessageType
(
mimeType
);
for
(
gloox
::
Hash
&
hash
:
file
->
hashes
())
msg
.
mediaHashes
.
append
(
QString
::
fromStdString
(
hash
.
tag
()
->
xml
()));
}
}
// handle media sharing (SIMS) content
handleMediaSharing
(
const_cast
<
gloox
::
Message
*>
(
message
),
&
msg
);
//
// If it is a delayed delivery (containing a timestamp), use its timestamp
...
...
@@ -203,6 +177,59 @@ void MessageHandler::handleMessage(const gloox::Message &stanza, gloox::MessageS
handleReceiptMessage
(
message
,
isCarbonMessage
);
}
void
MessageHandler
::
handleMediaSharing
(
const
gloox
::
Message
*
message
,
MessageModel
::
Message
*
msg
)
{
//
// Get media sharing (SIMS) information
//
const
gloox
::
Reference
*
ref
=
message
->
findExtension
<
gloox
::
Reference
>
(
gloox
::
EXT_REFERENCES
);
if
(
ref
&&
ref
->
getEmbeddedSIMS
())
{
gloox
::
SIMS
*
sims
=
ref
->
getEmbeddedSIMS
();
gloox
::
StringList
sources
=
sims
->
sources
();
for
(
auto
&
source
:
sources
)
{
if
(
source
.
rfind
(
"https://"
,
0
)
==
0
||
source
.
rfind
(
"http://"
,
0
)
==
0
)
{
msg
->
mediaUrl
=
QString
::
fromStdString
(
source
);
break
;
}
}
gloox
::
Jingle
::
File
*
file
=
sims
->
file
();
if
(
file
&&
file
->
valid
())
{
msg
->
message
=
QString
::
fromStdString
(
file
->
desc
());
msg
->
mediaSize
=
file
->
size
();
msg
->
mediaContentType
=
QString
::
fromStdString
(
file
->
mediaType
());
msg
->
mediaLastModified
=
stringToQDateTime
(
file
->
date
()).
toTime_t
();
QMimeType
mimeType
=
QMimeDatabase
().
mimeTypeForName
(
msg
->
mediaContentType
);
msg
->
type
=
getMessageType
(
mimeType
);
for
(
gloox
::
Hash
&
hash
:
file
->
hashes
())
msg
->
mediaHashes
.
append
(
QString
::
fromStdString
(
hash
.
tag
()
->
xml
()));
// extract thumbnail
const
gloox
::
Jingle
::
Thumb
*
thumb
=
file
->
thumb
();
if
(
thumb
&&
thumb
->
valid
())
{
// check if uri is valid (it is a BoB content id [cid])
std
::
string
uri
=
thumb
->
uri
();
if
(
uri
.
rfind
(
"cid:"
,
0
)
==
0
)
{
const
gloox
::
BitsOfBinaryData
*
thumbData
=
message
->
findExtension
<
gloox
::
BitsOfBinaryData
>
(
gloox
::
EXT_BITSOFBINARY
);
// check if thumbnail uri matches the attached data uri
if
(
thumbData
&&
thumb
->
uri
()
==
uri
.
substr
(
4
,
uri
.
length
()
-
4
))
{
// save media thumbnail
msg
->
mediaThumb
=
QByteArray
::
fromBase64
(
QByteArray
::
fromStdString
(
thumbData
->
data
())
);
}
}
}
}
}
}
void
MessageHandler
::
handleReceiptMessage
(
const
gloox
::
Message
*
message
,
bool
isCarbonMessage
)
{
...
...
src/MessageHandler.h
View file @
b72c72a3
...
...
@@ -65,6 +65,12 @@ public:
virtual
void
handleMessage
(
const
gloox
::
Message
&
message
,
gloox
::
MessageSession
*
session
=
0
);
/**
* Handles and processes media sharing content of messages
*/
void
handleMediaSharing
(
const
gloox
::
Message
*
message
,
MessageModel
::
Message
*
msg
);
/**
* Handles a message with a possible receipt or receipt request
*/
...
...
src/UploadHandler.cpp
View file @
b72c72a3
...
...
@@ -33,16 +33,21 @@
#include "MessageHandler.h"
// gloox
#include <gloox/message.h>
#include <gloox/base64.h>
#include "gloox-extensions/httpuploadmanager.h"
#include "gloox-extensions/reference.h"
#include "gloox-extensions/sims.h"
#include "gloox-extensions/processinghints.h"
#include "gloox-extensions/jinglefile.h"
#include "gloox-extensions/hash.h"
#include "gloox-extensions/thumb.h"
#include "gloox-extensions/bitsofbinarydata.h"
// Qt
#include <QMimeDatabase>
#include <QMimeType>
#include <QDateTime>
#include <QBuffer>
#include <QImage>
#include <QDebug>
UploadHandler
::
UploadHandler
(
gloox
::
Client
*
client
,
MessageHandler
*
msgHandler
,
...
...
@@ -61,7 +66,6 @@ void UploadHandler::uploadFile(QString jid, QString filePath, QString message)
QMimeDatabase
mimeDb
;
QMimeType
mimeType
=
mimeDb
.
mimeTypeForFile
(
filePath
);
QString
mimeTypeStr
=
mimeType
.
name
();
qDebug
()
<<
filePath
;
int
id
=
manager
->
uploadFile
(
filePath
.
toStdString
(),
true
,
mimeTypeStr
.
toStdString
());
...
...
@@ -75,10 +79,11 @@ void UploadHandler::uploadFile(QString jid, QString filePath, QString message)
meta
.
jid
=
jid
;
meta
.
msgId
=
client
->
getID
();
meta
.
message
=
message
;
meta
.
filePath
=
filePath
;
meta
.
type
=
msgHandler
->
getMessageType
(
mimeType
);
mediaShares
[
id
]
=
meta
;
MessageType
type
=
msgHandler
->
getMessageType
(
mimeType
);
msgHandler
->
addMessageToDb
(
jid
,
message
,
QString
::
fromStdString
(
meta
.
msgId
),
MessageType
::
MessageFile
,
filePath
...
...
@@ -91,6 +96,8 @@ void UploadHandler::handleUploadFailed(int id, gloox::HttpUploadError error,
const
std
::
string
&
stamp
)
{
qDebug
()
<<
"[client] A file upload has failed."
;
// the media meta isn't needed anymore, so delete it
mediaShares
.
remove
(
id
);
}
void
UploadHandler
::
handleUploadFinished
(
int
id
,
std
::
string
&
name
,
...
...
@@ -105,7 +112,6 @@ void UploadHandler::handleUploadFinished(int id, std::string &name,
msg
.
mediaContentType
=
QString
::
fromStdString
(
contentType
);
msg
.
mediaSize
=
size
;
// TODO: generate thumbnail
// TODO: lastModified / date
// Hashes
...
...
@@ -120,10 +126,30 @@ void UploadHandler::handleUploadFinished(int id, std::string &name,
// last modified date
std
::
string
date
=
""
;
// thumbnail
QSize
thumbSize
=
generateMediaThumb
(
mediaShares
[
id
].
filePath
,
mediaShares
[
id
].
type
,
&
msg
.
mediaThumb
);
gloox
::
Jingle
::
Thumb
*
thumb
=
nullptr
;
gloox
::
BitsOfBinaryData
*
thumbBob
=
nullptr
;
if
(
!
msg
.
mediaThumb
.
isEmpty
())
{
// encode to base64
std
::
string
thumbData
=
gloox
::
Base64
::
encode64
(
std
::
string
(
msg
.
mediaThumb
.
constData
(),
msg
.
mediaThumb
.
length
())
);
// create BoB content identifier
std
::
string
thumbCid
=
gloox
::
BitsOfBinaryData
::
generateContentId
(
thumbData
);
// create BoB data object
thumbBob
=
new
gloox
::
BitsOfBinaryData
(
thumbData
,
thumbCid
,
"image/jpeg"
);
// create thumb object (links to BoB data)
thumb
=
new
gloox
::
Jingle
::
Thumb
(
"cid:"
+
thumbCid
,
thumbSize
.
width
(),
thumbSize
.
height
(),
"image/jpeg"
);
}
// file meta information
gloox
::
Jingle
::
File
*
fileInfo
=
new
gloox
::
Jingle
::
File
(
name
,
size
,
hashes
,
contentType
,
date
,
mediaShares
[
id
].
message
.
toStdString
()
mediaShares
[
id
].
message
.
toStdString
()
,
thumb
);
// list of sources for the file (TODO: jingle as fallback)
...
...
@@ -144,6 +170,8 @@ void UploadHandler::handleUploadFinished(int id, std::string &name,
gloox
::
Message
message
(
gloox
::
Message
::
Chat
,
to
.
bareJID
(),
msgBody
);
message
.
setID
(
mediaShares
[
id
].
msgId
);
message
.
addExtension
((
gloox
::
StanzaExtension
*
)
simsRef
);
if
(
thumbBob
)
message
.
addExtension
(
thumbBob
);
// thumbnail BoB data
client
->
send
(
message
);
...
...
@@ -173,3 +201,25 @@ void UploadHandler::handleUploadServiceAdded(const gloox::JID &jid,
void
UploadHandler
::
handleFileSizeLimitChanged
(
unsigned
long
maxFileSize
)
{
}
QSize
UploadHandler
::
generateMediaThumb
(
QString
&
filePath
,
MessageType
type
,
QByteArray
*
bytes
)
{
if
(
type
!=
MessageType
::
MessageImage
)
return
QSize
(
0
,
0
);
// results should be about 1-3 kB large
int
finalSize
=
40
;
QImage
img
(
filePath
);
// Qt::FastTransformation is used because quality doesn't matter at this
// size; you won't be able to really see a large difference
img
=
img
.
scaled
(
finalSize
,
finalSize
,
Qt
::
KeepAspectRatio
,
Qt
::
FastTransformation
);
// save image to byte array
QBuffer
buffer
(
bytes
);
buffer
.
open
(
QIODevice
::
WriteOnly
);
img
.
save
(
&
buffer
,
"JPEG"
,
90
);
return
img
.
size
();
}
src/UploadHandler.h
View file @
b72c72a3
...
...
@@ -37,6 +37,11 @@
// Qt
#include <QObject>
#include <QMap>
#include <QSize>
// Kaidan
#include "Enums.h"
using
namespace
Enums
;
namespace
gloox
{
class
Client
;
...
...
@@ -133,10 +138,18 @@ protected:
const
std
::
string
&
stamp
=
gloox
::
EmptyString
);
private:
/**
* Generates a media thumbnail (currently only image thumbs)
*/
QSize
generateMediaThumb
(
QString
&
filePath
,
MessageType
type
,
QByteArray
*
bytes
);
struct
MediaSharingMeta
{
QString
jid
;
std
::
string
msgId
;
QString
message
;
QString
filePath
;
MessageType
type
;
};
gloox
::
Client
*
client
;
...
...
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