From 23479c4e542e48ced40947777aa574e435153d34 Mon Sep 17 00:00:00 2001
From: Alexander Lantsev <aunsane@gmail.com>
Date: Sun, 28 Apr 2013 21:26:57 +0000
Subject: some fixes in avatar loading

git-svn-id: http://svn.miranda-ng.org/main/trunk@4563 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
---
 protocols/Skype/src/skype.cpp         |  2 +-
 protocols/Skype/src/skype_avatars.cpp | 57 +++++++++++++++++++++++++++--------
 protocols/Skype/src/skype_profile.cpp | 31 +++++++++----------
 protocols/Skype/src/skype_proto.h     |  6 ++--
 protocols/Skype/src/skype_utils.cpp   | 29 ++++++------------
 5 files changed, 74 insertions(+), 51 deletions(-)

(limited to 'protocols')

diff --git a/protocols/Skype/src/skype.cpp b/protocols/Skype/src/skype.cpp
index 0a67359a25..78af8aa51c 100644
--- a/protocols/Skype/src/skype.cpp
+++ b/protocols/Skype/src/skype.cpp
@@ -137,7 +137,7 @@ int StartSkypeRuntime(HINSTANCE hInstance, const wchar_t *profileName, int &port
 	if (skypeKitPath != NULL)
 		*skypeKitPath = 0;
 	::swprintf(fileName, SIZEOF(fileName), L"%s\\%s", fileName, L"SkypeKit.exe");
-	if ( !::PathFileExists(fileName))
+	if ( ::GetFileAttributes(fileName) == DWORD(-1))
 	{
 		HRSRC hRes = ::FindResource(hInstance, MAKEINTRESOURCE(IDR_RUNTIME), L"BIN");
 		if (hRes)
diff --git a/protocols/Skype/src/skype_avatars.cpp b/protocols/Skype/src/skype_avatars.cpp
index 0df0814391..c95d4e3d2a 100644
--- a/protocols/Skype/src/skype_avatars.cpp
+++ b/protocols/Skype/src/skype_avatars.cpp
@@ -1,6 +1,6 @@
 #include "skype_proto.h"
 
-bool CSkypeProto::IsAvatarChanged(const SEBinary &avatar)
+bool CSkypeProto::IsAvatarChanged(const SEBinary &avatar, HANDLE hContact)
 {
 	bool result = false;
 
@@ -8,7 +8,7 @@ bool CSkypeProto::IsAvatarChanged(const SEBinary &avatar)
 	::mir_md5_hash((PBYTE)avatar.data(), (int)avatar.size(), digest);
 
 	DBVARIANT dbv;
-	::db_get(NULL, this->m_szModuleName, "AvatarHash", &dbv);
+	::db_get(hContact, this->m_szModuleName, "AvatarHash", &dbv);
 	if (dbv.type == DBVT_BLOB && dbv.pbVal && dbv.cpbVal == 16)
 	{
 		if (::memcmp(digest, dbv.pbVal, 16) == 0)
@@ -56,7 +56,7 @@ int CSkypeProto::DetectAvatarFormat(const wchar_t *path)
 
 wchar_t * CSkypeProto::GetContactAvatarFilePath(HANDLE hContact)
 {
-	wchar_t *path = new wchar_t[MAX_PATH];
+	wchar_t *path = (wchar_t*)::mir_alloc(MAX_PATH * sizeof(wchar_t));
 
 	this->InitCustomFolders();
 
@@ -78,7 +78,7 @@ wchar_t * CSkypeProto::GetContactAvatarFilePath(HANDLE hContact)
 		::mir_sntprintf(path, MAX_PATH, _T("%s\\%s avatar.jpg"), path, sid);
 	else
 	{
-		delete [] path;
+		::mir_free(path);
 		return NULL;
 	}
 
@@ -94,7 +94,7 @@ INT_PTR __cdecl CSkypeProto::GetAvatarInfo(WPARAM, LPARAM lParam)
 		return GAIR_NOAVATAR;
 	}
 
-	wchar_t *sid = ::db_get_wsa(pai->hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN);
+	mir_ptr<wchar_t> sid = ::db_get_wsa(pai->hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN);
 	if (sid)
 	{
 		wchar_t *path = this->GetContactAvatarFilePath(pai->hContact);
@@ -105,7 +105,7 @@ INT_PTR __cdecl CSkypeProto::GetAvatarInfo(WPARAM, LPARAM lParam)
 			return GAIR_SUCCESS;
 		}
 
-		::mir_free(sid);
+		::mir_free(path);		
 	}
 
 	return GAIR_NOAVATAR;
@@ -160,10 +160,10 @@ INT_PTR __cdecl CSkypeProto::GetMyAvatar(WPARAM wParam, LPARAM lParam)
 		return -2;
 
 	wchar_t *path = this->GetContactAvatarFilePath(NULL);
-	if (path && ::PathFileExists(path)) 
+	if (path && CSkypeProto::FileExists(path)) 
 	{
 		::wcsncpy((wchar_t *)wParam, path, (int)lParam);
-		delete path;
+		::mir_free(path);
 		return 0;
 	}
 
@@ -178,25 +178,31 @@ INT_PTR __cdecl CSkypeProto::SetMyAvatar(WPARAM, LPARAM lParam)
 	if (path)
 	{
 		wchar_t *avatarPath = this->GetContactAvatarFilePath(NULL);
-		if (::wcscmp(path, avatarPath) && !::CopyFile(path, avatarPath, FALSE))
+		if ( !::wcscmp(path, avatarPath))
 		{
-			this->Log(L"Failed to copy our avatar to local storage.");
+			this->Log(L"New avatar path are same with old.");
 			return iRet;
 		}
 
-		SEBinary avatar = this->GetAvatarBinary(avatarPath);
+		SEBinary avatar = this->GetAvatarBinary(path);
 		if (avatar.size() == 0)
 		{
 			this->Log(L"Failed to read avatar file.");
 			return iRet;
 		}
 
-		if (!this->IsAvatarChanged(avatar))
+		if (this->IsAvatarChanged(avatar))
 		{
 			this->Log(L"New avatar are same with old.");
 			return iRet;
 		}
 
+		if ( !::CopyFile(path, avatarPath, FALSE))
+		{
+			this->Log(L"Failed to copy new avatar to local storage.");
+			return iRet;
+		}
+		
 		Skype::VALIDATERESULT result = Skype::NOT_VALIDATED;
 		if (!this->account->SetAvatar(avatar, result))
 		{
@@ -207,6 +213,8 @@ INT_PTR __cdecl CSkypeProto::SetMyAvatar(WPARAM, LPARAM lParam)
 		uint newTS = this->account->GetUintProp(/* *::P_AVATAR_TIMESTAMP */ 182);
 		::db_set_dw(NULL, this->m_szModuleName, "AvatarTS", newTS);
 		iRet = 0;
+
+		::mir_free(avatarPath);
 	}
 	else
 	{
@@ -216,4 +224,29 @@ INT_PTR __cdecl CSkypeProto::SetMyAvatar(WPARAM, LPARAM lParam)
 	}
 
 	return iRet;
+}
+
+SEBinary CSkypeProto::GetAvatarBinary(wchar_t *path)
+{
+	SEBinary avatar;
+
+	if (CSkypeProto::FileExists(path))
+	{
+		int len;
+		char *buffer;
+		FILE* fp = ::_wfopen(path, L"rb");
+		if (fp)
+		{
+			::fseek(fp, 0, SEEK_END);
+			len = ::ftell(fp);
+			::fseek(fp, 0, SEEK_SET);
+			buffer = new char[len + 1];
+			::fread(buffer, len, 1, fp);
+			::fclose(fp);
+
+			avatar.set(buffer, len);
+		}
+	}
+
+	return avatar;
 }
\ No newline at end of file
diff --git a/protocols/Skype/src/skype_profile.cpp b/protocols/Skype/src/skype_profile.cpp
index 31c81d9a97..90ca29133a 100644
--- a/protocols/Skype/src/skype_profile.cpp
+++ b/protocols/Skype/src/skype_profile.cpp
@@ -41,17 +41,16 @@ SettingItem CSkypeProto::setting[] = {
 void CSkypeProto::UpdateProfileAvatar(SEObject *obj, HANDLE hContact)
 {
 	uint newTS = hContact ? obj->GetUintProp(Contact::P_AVATAR_TIMESTAMP) : obj->GetUintProp(Account::P_AVATAR_TIMESTAMP);
+	if (!newTS) return;
+
 	DWORD oldTS = ::db_get_dw(hContact, this->m_szModuleName, "AvatarTS", 0);
-	
-	wchar_t *path = this->GetContactAvatarFilePath(hContact);
-	SEBinary data = hContact ? obj->GetBinProp(Contact::P_AVATAR_IMAGE) : obj->GetBinProp(Account::P_AVATAR_IMAGE);
 
-	bool hasNewAvatar = newTS > oldTS;
-	bool isAvatarEmpty = data.size() == 0;
-	bool isAvatarFileExists = ::PathFileExists(path) > 0;
-	if ( !isAvatarEmpty)
+	wchar_t *path = this->GetContactAvatarFilePath(hContact);
+	bool isAvatarFileExists = CSkypeProto::FileExists(path);
+	if (newTS > oldTS || !isAvatarFileExists)
 	{
-		if (hasNewAvatar || !isAvatarFileExists)
+		SEBinary data = hContact ? obj->GetBinProp(Contact::P_AVATAR_IMAGE) : obj->GetBinProp(Account::P_AVATAR_IMAGE);
+		if (data.size() > 0)
 		{
 			FILE *fp = ::_wfopen(path, L"wb");
 			if (fp)
@@ -81,14 +80,14 @@ void CSkypeProto::UpdateProfileAvatar(SEObject *obj, HANDLE hContact)
 				}
 			}
 		}
-	}
-	else if (isAvatarFileExists)
-	{
-		::_wremove(path);
-		this->SendBroadcast(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, NULL, 0);
+		else if (isAvatarFileExists)
+		{
+			::_wremove(path);
+			this->SendBroadcast(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, NULL, 0);
+		}
 	}
 
-	delete [] path;
+	::mir_free(path);
 }
 
 void CSkypeProto::UpdateProfileAboutText(SEObject *obj, HANDLE hContact)
@@ -331,7 +330,7 @@ void CSkypeProto::UpdateProfileTimezone(SEObject *obj, HANDLE hContact)
 
 void CSkypeProto::UpdateProfile(SEObject *obj, HANDLE hContact)
 {
-	this->UpdateProfileAvatar(obj, hContact);
+	//this->UpdateProfileAvatar(obj, hContact);
 
 	uint newTS = hContact ? obj->GetUintProp(Contact::P_PROFILE_TIMESTAMP) : obj->GetUintProp(Account::P_PROFILE_TIMESTAMP);
 	if (newTS > ::db_get_dw(hContact, this->m_szModuleName, "ProfileTS", 0))
@@ -376,6 +375,6 @@ void __cdecl CSkypeProto::LoadOwnInfo(void *)
 		mir_ptr<wchar_t> nick = ::mir_utf8decodeW(data);
 		::db_set_ws(NULL, this->m_szModuleName, "Nick", nick);
 	}
-
+	this->UpdateProfileAvatar(this->account.fetch());
 	this->UpdateProfile(this->account.fetch());
 }
\ No newline at end of file
diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h
index f42d581b35..bb8388c669 100644
--- a/protocols/Skype/src/skype_proto.h
+++ b/protocols/Skype/src/skype_proto.h
@@ -222,7 +222,7 @@ protected:
 	void	OnAccountChanged(int prop);
 
 	// avatars
-	bool IsAvatarChanged(const SEBinary &avatar);
+	bool IsAvatarChanged(const SEBinary &avatar, HANDLE hContact = NULL);
 
 	static int DetectAvatarFormatBuffer(const char *pBuffer);
 	static int DetectAvatarFormat(const wchar_t *path);
@@ -234,6 +234,8 @@ protected:
 	INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM);
 	INT_PTR __cdecl SetMyAvatar(WPARAM, LPARAM);
 
+	SEBinary GetAvatarBinary(wchar_t *path);
+
 	// messages
 	void	OnMessage(CConversation::Ref conversation, CMessage::Ref message);
 	void	OnMessageSended(CConversation::Ref &conversation, CMessage::Ref &message);
@@ -357,7 +359,7 @@ protected:
 	int		SkypeToMirandaStatus(CContact::AVAILABILITY availability);
 	CContact::AVAILABILITY MirandaToSkypeStatus(int status);
 
-	SEBinary GetAvatarBinary(wchar_t *path);
+	static bool FileExists(wchar_t *path);	
 
 	// instances
 	static LIST<CSkypeProto> instanceList;
diff --git a/protocols/Skype/src/skype_utils.cpp b/protocols/Skype/src/skype_utils.cpp
index 7201041afe..2bd14e00a5 100644
--- a/protocols/Skype/src/skype_utils.cpp
+++ b/protocols/Skype/src/skype_utils.cpp
@@ -505,27 +505,16 @@ CContact::AVAILABILITY CSkypeProto::MirandaToSkypeStatus(int status)
 	return availability;
 }
 
-SEBinary CSkypeProto::GetAvatarBinary(wchar_t *path)
+bool CSkypeProto::FileExists(wchar_t *path)
 {
-	SEBinary avatar;
-
-	if (::PathFileExists(path))
+	//return ::GetFileAttributes(fileName) != DWORD(-1)
+	WIN32_FIND_DATA wfd;
+	HANDLE hFind = ::FindFirstFile(path, &wfd);
+	if (INVALID_HANDLE_VALUE != hFind)
 	{
-		int len;
-		char *buffer;
-		FILE* fp = ::_wfopen(path, L"rb");
-		if (fp)
-		{
-			::fseek(fp, 0, SEEK_END);
-			len = ::ftell(fp);
-			::fseek(fp, 0, SEEK_SET);
-			buffer = new char[len + 1];
-			::fread(buffer, len, 1, fp);
-			::fclose(fp);
-
-			avatar.set(buffer, len);
-		}
+		::FindClose(hFind);
+		return true;
 	}
+	return false;
+}
 
-	return avatar;
-}
\ No newline at end of file
-- 
cgit v1.2.3