Support avatar images for contacts.
This commit is contained in:
parent
1644625480
commit
225957b2f6
|
@ -6,10 +6,16 @@
|
||||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#include <libsupport/Base64.h>
|
#include <Directory.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
#include <CayaProtocolMessages.h>
|
#include <CayaProtocolMessages.h>
|
||||||
|
|
||||||
|
#include <libsupport/SHA1.h>
|
||||||
|
|
||||||
#include "JabberHandler.h"
|
#include "JabberHandler.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +37,7 @@ JabberHandler::JabberHandler()
|
||||||
fClient(NULL),
|
fClient(NULL),
|
||||||
fVCardManager(NULL)
|
fVCardManager(NULL)
|
||||||
{
|
{
|
||||||
|
fAvatars = new BList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,6 +45,11 @@ JabberHandler::~JabberHandler()
|
||||||
{
|
{
|
||||||
fVCardManager->cancelVCardOperations(this);
|
fVCardManager->cancelVCardOperations(this);
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
|
||||||
|
BString* item = NULL;
|
||||||
|
for (int32 i = 0; (item = (BString*)fAvatars->ItemAt(i)); i++)
|
||||||
|
delete item;
|
||||||
|
delete fAvatars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,6 +216,138 @@ JabberHandler::_MessageSent(const char* id, const char* subject,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JabberHandler::_SetupAvatarCache()
|
||||||
|
{
|
||||||
|
if (fAvatarCachePath.InitCheck() == B_OK)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
BPath path;
|
||||||
|
|
||||||
|
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
path.Append("Caya");
|
||||||
|
path.Append("Cache");
|
||||||
|
path.Append(kProtocolSignature);
|
||||||
|
|
||||||
|
if (create_directory(path.Path(), 0755) != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
fCachePath = path;
|
||||||
|
|
||||||
|
path.Append("avatar-cache");
|
||||||
|
|
||||||
|
BFile file(path.Path(), B_READ_ONLY);
|
||||||
|
fAvatarCache.Unflatten(&file);
|
||||||
|
|
||||||
|
fAvatarCachePath = path;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JabberHandler::_SaveAvatarCache()
|
||||||
|
{
|
||||||
|
if (fAvatarCachePath.InitCheck() != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
BFile file(fAvatarCachePath.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE);
|
||||||
|
return fAvatarCache.Flatten(&file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
JabberHandler::_CacheAvatar(const char* id, const char* binimage, size_t length)
|
||||||
|
{
|
||||||
|
if (!id || !binimage || length <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Calculate avatar hash
|
||||||
|
CSHA1 s1;
|
||||||
|
char hash[256];
|
||||||
|
s1.Reset();
|
||||||
|
s1.Update((uchar*)binimage, length);
|
||||||
|
s1.Final();
|
||||||
|
s1.ReportHash(hash, CSHA1::REPORT_HEX);
|
||||||
|
|
||||||
|
BString sha1;
|
||||||
|
sha1.SetTo(hash, 256);
|
||||||
|
|
||||||
|
BString oldSha1;
|
||||||
|
if (fAvatarCache.FindString("id", &oldSha1) != B_OK || oldSha1 == "" || sha1 != oldSha1) {
|
||||||
|
// Replace old hash and save cache
|
||||||
|
fAvatarCache.RemoveName(id);
|
||||||
|
fAvatarCache.AddString(id, sha1);
|
||||||
|
_SaveAvatarCache();
|
||||||
|
|
||||||
|
if (oldSha1 != "") {
|
||||||
|
BPath path(fCachePath);
|
||||||
|
path.Append(oldSha1);
|
||||||
|
|
||||||
|
// Remove old image file
|
||||||
|
BEntry entry(path.Path());
|
||||||
|
entry.Remove();
|
||||||
|
|
||||||
|
// Remove old hash from the list
|
||||||
|
BString* item = NULL;
|
||||||
|
for (int32 i = 0; (item = (BString*)fAvatars->ItemAt(i)); i++) {
|
||||||
|
if (item->Compare(oldSha1) == 0) {
|
||||||
|
fAvatars->RemoveItem(item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine file path
|
||||||
|
BPath path(fCachePath);
|
||||||
|
path.Append(sha1);
|
||||||
|
|
||||||
|
BEntry entry(path.Path());
|
||||||
|
if (!entry.Exists()) {
|
||||||
|
// Save to file
|
||||||
|
BFile file(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE);
|
||||||
|
file.Write(binimage, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we need to notify Caya?
|
||||||
|
bool found = false;
|
||||||
|
BString* item = NULL;
|
||||||
|
for (int32 i = 0; (item = (BString*)fAvatars->ItemAt(i)); i++) {
|
||||||
|
if (item->Compare(sha1) == 0) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
// Add new hash to the list if needed
|
||||||
|
fAvatars->AddItem(new BString(sha1));
|
||||||
|
|
||||||
|
// Notify Caya that the avatar has changed
|
||||||
|
_AvatarChanged(id, path.Path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
JabberHandler::_AvatarChanged(const char* id, const char* filename)
|
||||||
|
{
|
||||||
|
entry_ref ref;
|
||||||
|
if (get_ref_for_path(filename, &ref) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BMessage msg(IM_MESSAGE);
|
||||||
|
msg.AddInt32("im_what", IM_AVATAR_SET);
|
||||||
|
msg.AddString("protocol", kProtocolSignature);
|
||||||
|
msg.AddString("id", id);
|
||||||
|
msg.AddRef("ref", &ref);
|
||||||
|
fServerMessenger->SendMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CayaStatus
|
CayaStatus
|
||||||
JabberHandler::_GlooxStatusToCaya(gloox::Presence::PresenceType type)
|
JabberHandler::_GlooxStatusToCaya(gloox::Presence::PresenceType type)
|
||||||
{
|
{
|
||||||
|
@ -456,11 +600,6 @@ JabberHandler::handleVCard(const gloox::JID& jid, const gloox::VCard* card)
|
||||||
|
|
||||||
std::string fullName = name.family + " " + name.given;
|
std::string fullName = name.family + " " + name.given;
|
||||||
|
|
||||||
#if 0
|
|
||||||
BString decoded
|
|
||||||
= Base64::Decode(BString(photo.binval.c_str()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BMessage msg(IM_MESSAGE);
|
BMessage msg(IM_MESSAGE);
|
||||||
msg.AddInt32("im_what", IM_EXTENDED_CONTACT_INFO);
|
msg.AddInt32("im_what", IM_EXTENDED_CONTACT_INFO);
|
||||||
msg.AddString("protocol", kProtocolSignature);
|
msg.AddString("protocol", kProtocolSignature);
|
||||||
|
@ -473,6 +612,15 @@ JabberHandler::handleVCard(const gloox::JID& jid, const gloox::VCard* card)
|
||||||
msg.AddString("suffix", name.suffix.c_str());
|
msg.AddString("suffix", name.suffix.c_str());
|
||||||
msg.AddString("full name", fullName.c_str());
|
msg.AddString("full name", fullName.c_str());
|
||||||
fServerMessenger->SendMessage(&msg);
|
fServerMessenger->SendMessage(&msg);
|
||||||
|
|
||||||
|
// Return if there's no avatar icon
|
||||||
|
if (!photo.binval.c_str())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_SetupAvatarCache() == B_OK)
|
||||||
|
// Cache avatar icon
|
||||||
|
_CacheAvatar(jid.bare().c_str(), photo.binval.c_str(),
|
||||||
|
photo.binval.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#ifndef _JABBER_HANDLER_H
|
#ifndef _JABBER_HANDLER_H
|
||||||
#define _JABBER_HANDLER_H
|
#define _JABBER_HANDLER_H
|
||||||
|
|
||||||
|
#include <Path.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
#include <libgloox/client.h>
|
#include <libgloox/client.h>
|
||||||
|
@ -21,8 +22,10 @@
|
||||||
#include <libgloox/vcardhandler.h>
|
#include <libgloox/vcardhandler.h>
|
||||||
#include <libgloox/vcardmanager.h>
|
#include <libgloox/vcardmanager.h>
|
||||||
|
|
||||||
#include "CayaProtocol.h"
|
#include <CayaProtocol.h>
|
||||||
#include "CayaConstants.h"
|
#include <CayaConstants.h>
|
||||||
|
|
||||||
|
class BList;
|
||||||
|
|
||||||
class JabberHandler : public CayaProtocol, gloox::RosterListener, gloox::ConnectionListener,
|
class JabberHandler : public CayaProtocol, gloox::RosterListener, gloox::ConnectionListener,
|
||||||
gloox::LogHandler, gloox::MessageHandler, gloox::VCardHandler {
|
gloox::LogHandler, gloox::MessageHandler, gloox::VCardHandler {
|
||||||
|
@ -66,10 +69,20 @@ private:
|
||||||
|
|
||||||
thread_id fRecvThread;
|
thread_id fRecvThread;
|
||||||
|
|
||||||
|
BPath fCachePath;
|
||||||
|
BPath fAvatarCachePath;
|
||||||
|
BMessage fAvatarCache;
|
||||||
|
BList* fAvatars;
|
||||||
|
|
||||||
void _MessageSent(const char* id, const char* subject,
|
void _MessageSent(const char* id, const char* subject,
|
||||||
const char* body);
|
const char* body);
|
||||||
CayaStatus _GlooxStatusToCaya(gloox::Presence::PresenceType type);
|
CayaStatus _GlooxStatusToCaya(gloox::Presence::PresenceType type);
|
||||||
|
|
||||||
|
status_t _SetupAvatarCache();
|
||||||
|
status_t _SaveAvatarCache();
|
||||||
|
void _CacheAvatar(const char* id, const char* binval, size_t length);
|
||||||
|
void _AvatarChanged(const char*id, const char* filename);
|
||||||
|
|
||||||
virtual void onConnect();
|
virtual void onConnect();
|
||||||
virtual void onDisconnect(gloox::ConnectionError);
|
virtual void onDisconnect(gloox::ConnectionError);
|
||||||
virtual bool onTLSConnect(const gloox::CertInfo&);
|
virtual bool onTLSConnect(const gloox::CertInfo&);
|
||||||
|
|
|
@ -9,7 +9,7 @@ AddOn jabber :
|
||||||
JabberMain.cpp
|
JabberMain.cpp
|
||||||
JabberProtocol.cpp
|
JabberProtocol.cpp
|
||||||
JabberHandler.cpp
|
JabberHandler.cpp
|
||||||
: be libgloox.a network ssl crypto z $(TARGET_LIBSTDC++)
|
: be libsupport.a libgloox.a network ssl crypto z $(TARGET_LIBSTDC++)
|
||||||
: jabber.rdef jabber_settings.rdef
|
: jabber.rdef jabber_settings.rdef
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ AddOn gtalk :
|
||||||
GoogleTalkMain.cpp
|
GoogleTalkMain.cpp
|
||||||
GoogleTalkProtocol.cpp
|
GoogleTalkProtocol.cpp
|
||||||
JabberHandler.cpp
|
JabberHandler.cpp
|
||||||
: be libgloox.a network ssl crypto z $(TARGET_LIBSTDC++)
|
: be libsupport.a libgloox.a network ssl crypto z $(TARGET_LIBSTDC++)
|
||||||
: gtalk.rdef gtalk_settings.rdef
|
: gtalk.rdef gtalk_settings.rdef
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -25,12 +25,15 @@ AddOn facebook :
|
||||||
FacebookMain.cpp
|
FacebookMain.cpp
|
||||||
FacebookProtocol.cpp
|
FacebookProtocol.cpp
|
||||||
JabberHandler.cpp
|
JabberHandler.cpp
|
||||||
: be libgloox.a network ssl crypto z $(TARGET_LIBSTDC++)
|
: be libsupport.a libgloox.a network ssl crypto z $(TARGET_LIBSTDC++)
|
||||||
: facebook.rdef facebook_settings.rdef
|
: facebook.rdef facebook_settings.rdef
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Depends jabber : libsupport.a ;
|
||||||
Depends jabber : libgloox.a ;
|
Depends jabber : libgloox.a ;
|
||||||
|
Depends gtalk : libsupport.a ;
|
||||||
Depends gtalk : libgloox.a ;
|
Depends gtalk : libgloox.a ;
|
||||||
|
Depends facebook : libsupport.a ;
|
||||||
Depends facebook : libgloox.a ;
|
Depends facebook : libgloox.a ;
|
||||||
|
|
||||||
LINKFLAGS on jabber += -L$(OPENSSL_LIBRARY_DIR) ;
|
LINKFLAGS on jabber += -L$(OPENSSL_LIBRARY_DIR) ;
|
||||||
|
|
Ŝarĝante…
Reference in New Issue