From 331d68975919584be948fb862316669cf2945d07 Mon Sep 17 00:00:00 2001 From: Sergey Bolhovskoy Date: Tue, 23 Dec 2014 07:45:38 +0000 Subject: VKontakte: fix order loading news to chat windows fix duplicate news git-svn-id: http://svn.miranda-ng.org/main/trunk@11593 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/VKontakte/src/vk_feed.cpp | 69 +++++++++++++++++++++-------------- protocols/VKontakte/src/vk_proto.h | 40 +++++++++++++++----- protocols/VKontakte/src/vk_thread.cpp | 2 +- 3 files changed, 73 insertions(+), 38 deletions(-) (limited to 'protocols') diff --git a/protocols/VKontakte/src/vk_feed.cpp b/protocols/VKontakte/src/vk_feed.cpp index 72e48360b3..2284d37ace 100644 --- a/protocols/VKontakte/src/vk_feed.cpp +++ b/protocols/VKontakte/src/vk_feed.cpp @@ -159,26 +159,28 @@ CMString CVkProto::GetVkPhotoItem(JSONNODE *pPhoto) ////////////////////////////////////////////////////////////////////////////////////////////////////////// -CMString CVkProto::GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, time_t &tDate) +CVKNewsItem* CVkProto::GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers) { debugLogA("CVkProto::GetVkNewsItem"); bool bPostLink = true; - CMString tszRes; + CVKNewsItem *vkNewsItem = new CVKNewsItem(); if (pItem == NULL) - return tszRes; - - CMString tszType = json_as_string(json_get(pItem, "type")); + return vkNewsItem; LONG iSourceId = json_as_int(json_get(pItem, "source_id")); iSourceId = iSourceId ? iSourceId : json_as_int(json_get(pItem, "owner_id")); - CVkUserInfo *vkUser = GetVkUserInfo(iSourceId, vkUsers); LONG iPostId = json_as_int(json_get(pItem, "post_id")); - tDate = json_as_int(json_get(pItem, "date")); CMString tszText = json_as_string(json_get(pItem, "text")); + + vkNewsItem->tszType = json_as_string(json_get(pItem, "type")); + vkNewsItem->vkUser = GetVkUserInfo(iSourceId, vkUsers); + vkNewsItem->bIsGroup = vkNewsItem->vkUser->m_bIsGroup; + vkNewsItem->tDate = json_as_int(json_get(pItem, "date")); + if (!tszText.IsEmpty()) tszText += _T("\n"); - if (tszType == _T("photo_tag")){ + if (vkNewsItem->tszType == _T("photo_tag")){ bPostLink = false; JSONNODE *pPhotos = json_get(pItem, "photo_tags"); if (pPhotos){ @@ -191,7 +193,7 @@ CMString CVkProto::GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, } } } - else if (tszType == _T("photo") || tszType == _T("wall_photo")){ + else if (vkNewsItem->tszType == _T("photo") || vkNewsItem->tszType == _T("wall_photo")){ bPostLink = false; JSONNODE *pPhotos = json_get(pItem, "photos"); if (pPhotos){ @@ -199,7 +201,7 @@ CMString CVkProto::GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, if (pPhotoItems) for (size_t i = 0; (pPhotoItem = json_at(pPhotoItems, i)) != NULL; i++){ tszText += GetVkPhotoItem(pPhotoItem) + _T("\n"); - if (i == 0 && tszType == _T("wall_photo")){ + if (i == 0 && vkNewsItem->tszType == _T("wall_photo")){ iPostId = json_as_int(json_get(pPhotoItem, "post_id")); bPostLink = true; break; // Max 1 wall_photo @@ -207,15 +209,16 @@ CMString CVkProto::GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, } } } - else if (tszType == _T("post") || tszType.IsEmpty()) { + else if (vkNewsItem->tszType == _T("post") || vkNewsItem->tszType.IsEmpty()) { bPostLink = true; JSONNODE * pRepost = json_get(pItem, "copy_history"); - if (pRepost){ - time_t tRDate; - CMString tszRepostText = GetVkNewsItem(json_at(pRepost, 0), vkUsers, tRDate); - tszRepostText.Replace(_T("\n"), _T("\n\t")); - tszText += tszRepostText; + if (pRepost) { + CVKNewsItem *vkRepost = GetVkNewsItem(json_at(pRepost, 0), vkUsers); + vkRepost->tszText.Replace(_T("\n"), _T("\n\t")); + tszText += vkRepost->tszText; tszText += _T("\n"); + vkNewsItem->bIsRepost = true; + delete vkRepost; } JSONNODE *pAttachments = json_get(pItem, "attachments"); @@ -224,7 +227,6 @@ CMString CVkProto::GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, } CMString tszResFormat; - CMString tszUrl; CMString tszBBCIn = m_bBBCOnNews ? _T("[b]") : _T(""); CMString tszBBCOut = m_bBBCOnNews ? _T("[/b]") : _T(""); @@ -235,15 +237,16 @@ CMString CVkProto::GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, bPostLink = false; } - tszRes.AppendFormat(tszResFormat, tszBBCIn.GetBuffer(), vkUser->m_tszUserNick.GetBuffer(), tszBBCOut.GetBuffer(), vkUser->m_tszLink.GetBuffer(), tszText.GetBuffer()); + vkNewsItem->tszText.AppendFormat(tszResFormat, tszBBCIn.GetBuffer(), vkNewsItem->vkUser->m_tszUserNick.GetBuffer(), tszBBCOut.GetBuffer(), + vkNewsItem->vkUser->m_tszLink.GetBuffer(), tszText.GetBuffer()); + vkNewsItem->tszId.AppendFormat(_T("%d_%d"), vkNewsItem->vkUser->m_UserId, iPostId); if (bPostLink) { - tszUrl.AppendFormat(_T("%d_%d"), vkUser->m_UserId, iPostId); - tszUrl = CMString(_T("https://vk.com/wall")) + tszUrl; - tszRes.AppendFormat(TranslateT("\nNews link: %s"), tszUrl.GetBuffer()); + vkNewsItem->tszLink = CMString(_T("https://vk.com/wall")) + vkNewsItem->tszId; + vkNewsItem->tszText.AppendFormat(TranslateT("\nNews link: %s"), vkNewsItem->tszLink.GetBuffer()); } - return tszRes; + return vkNewsItem; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -418,6 +421,11 @@ void CVkProto::RetrieveUnreadNews(time_t tLastNewsTime) << VER_API); } +static int sttCompareVKNewsItems(const CVKNewsItem *p1, const CVKNewsItem *p2) +{ + return p1->tszId.Compare(p2->tszId) ? (LONG)p1->tDate - (LONG)p2->tDate : 0; +} + void CVkProto::OnReceiveUnreadNews(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnReceiveUnreadNews %d", reply->resultCode); @@ -435,15 +443,22 @@ void CVkProto::OnReceiveUnreadNews(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *p JSONNODE *pItems = json_get(pResponse, "items"); JSONNODE *pItem; + OBJLIST vkNews(5, sttCompareVKNewsItems); if (pItems != NULL) - for (int i = 0; (pItem = json_at(pItems, i)) != NULL; i++){ - time_t tDate; - CMString tszText = GetVkNewsItem(pItem, vkUsers, tDate); - AddFeedEvent(tszText, tDate); + for (int i = 0; (pItem = json_at(pItems, i)) != NULL; i++){ + CVKNewsItem *vkNewsItem = GetVkNewsItem(pItem, vkUsers); + if (vkNews.find(vkNewsItem) == NULL) + vkNews.insert(vkNewsItem); + else + delete vkNewsItem; } - + for (int i = 0; i < vkNews.getCount(); i++) + AddFeedEvent(vkNews[i].tszText, vkNews[i].tDate); + setDword("LastNewsTime", time(NULL)); + + vkNews.destroy(); vkUsers.destroy(); } diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index 4540ad7999..105e0115fe 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -158,7 +158,7 @@ struct CVkFileUploadParam { __forceinline char* fileName() { return fname; } }; -struct CVkUserInfo : public MZeroedObject{ +struct CVkUserInfo : public MZeroedObject { CVkUserInfo(LONG _UserId) : m_UserId(_UserId), m_bIsGroup(false) @@ -179,6 +179,33 @@ struct CVkUserInfo : public MZeroedObject{ bool m_bIsGroup; }; +enum VKObjType { vkNull, vkPost, vkPhoto, vkVideo, vkComment, vkTopic, vkUsers, vkCopy }; + +struct CVkNotification { + TCHAR *ptszType; + VKObjType vkParent, vkFeedback; + TCHAR *ptszTranslate; +}; + + +struct CVKNewsItem : public MZeroedObject { + CVKNewsItem() + { + tDate = NULL; + vkUser = NULL; + bIsGroup = bIsRepost = true; + }; + + CMString tszId; + time_t tDate; + CVkUserInfo *vkUser; + CMString tszText; + CMString tszLink; + CMString tszType; + bool bIsGroup; + bool bIsRepost; +}; + struct TFakeAckParams { __inline TFakeAckParams(MCONTACT _hContact, int _msgid) : @@ -189,13 +216,6 @@ struct TFakeAckParams int msgid; }; -enum VKObjType { vkNull, vkPost, vkPhoto, vkVideo, vkComment, vkTopic, vkUsers, vkCopy }; - -struct CVkNotification { - TCHAR *ptszType; - VKObjType vkParent, vkFeedback; - TCHAR *ptszTranslate; -}; struct CVkProto : public PROTO { @@ -321,11 +341,11 @@ struct CVkProto : public PROTO void AddFeedSpecialUser(); void AddFeedEvent(CMString& tszBody, time_t tTime); - CVkUserInfo * GetVkUserInfo(LONG iUserId, OBJLIST &vkUsers); + CVkUserInfo* GetVkUserInfo(LONG iUserId, OBJLIST &vkUsers); void CreateVkUserInfoList(OBJLIST &vkUsers, JSONNODE *pResponse); CMString GetVkPhotoItem(JSONNODE *pPhotoItem); - CMString GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, time_t &tDate); + CVKNewsItem* GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers); CMString GetVkNotificationsItem(JSONNODE *pItem, OBJLIST &vkUsers, time_t &tDate); CMString GetVkFeedback(JSONNODE *pFeedback, VKObjType vkFeedbackType, OBJLIST &vkUsers, CVkUserInfo *vkUser); diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp index 71990dd0a5..e92e85914d 100644 --- a/protocols/VKontakte/src/vk_thread.cpp +++ b/protocols/VKontakte/src/vk_thread.cpp @@ -677,7 +677,7 @@ void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe Sleep(100); if (!CheckMid(mid)) { ProtoChainRecvMsg(hContact, &recv); - if (mid>getDword(hContact, "lastmsgid", -1)) + if (mid > getDword(hContact, "lastmsgid", -1)) setDword(hContact, "lastmsgid", mid); } } -- cgit v1.2.3