From 16634865ad22aa865e79930e5c4fb570627ef69a Mon Sep 17 00:00:00 2001 From: Sergey Bolhovskoy Date: Mon, 29 Dec 2014 09:59:36 +0000 Subject: VKontakte: add filtering for notifications rework processing for notifications (output formating) version bump git-svn-id: http://svn.miranda-ng.org/main/trunk@11668 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/VKontakte/res/resource.rc | 57 ++++++----- protocols/VKontakte/src/misc.cpp | 114 ++++++++++++--------- protocols/VKontakte/src/resource.h | 4 + protocols/VKontakte/src/version.h | 2 +- protocols/VKontakte/src/vk_feed.cpp | 179 +++++++++++++++++++++++---------- protocols/VKontakte/src/vk_options.cpp | 21 ++++ protocols/VKontakte/src/vk_proto.cpp | 5 + protocols/VKontakte/src/vk_proto.h | 14 ++- 8 files changed, 263 insertions(+), 133 deletions(-) (limited to 'protocols/VKontakte') diff --git a/protocols/VKontakte/res/resource.rc b/protocols/VKontakte/res/resource.rc index 9784b53811..de05fdf1b4 100644 --- a/protocols/VKontakte/res/resource.rc +++ b/protocols/VKontakte/res/resource.rc @@ -57,7 +57,7 @@ BEGIN LEFTMARGIN, 4 RIGHTMARGIN, 297 TOPMARGIN, 7 - BOTTOMMARGIN, 193 + BOTTOMMARGIN, 222 END IDD_ACCMGRUI, DIALOG @@ -132,37 +132,42 @@ BEGIN "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,101,278,10 END -IDD_OPT_FEEDS DIALOGEX 0, 0, 304, 202 +IDD_OPT_FEEDS DIALOGEX 0, 0, 304, 230 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "News and event notifications",IDC_STATIC,4,8,293,97 - CTEXT "WARNING: Causes excessive network traffic!!!",IDC_STATIC,12,19,278,8 - CONTROL "Enable news feeds",IDC_NEWS_ENBL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,30,278,10 - LTEXT "Interval for news updates (min):",IDC_STATIC,16,44,169,8 - EDITTEXT IDC_ED_INT_NEWS,190,41,40,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN_INT_NEWS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,230,41,14,14 - CONTROL "Enable event notifications",IDC_NOTIF_ENBL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,56,278,10 - LTEXT "Interval for notification updates (min):",IDC_STATIC,16,70,169,8 - EDITTEXT IDC_ED_INT_NOTIF,190,67,40,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_SPIN_INT_NOTIF,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,230,67,14,14 + GROUPBOX "News and event notifications",IDC_STATIC,4,8,293,90 + CTEXT "WARNING: Causes excessive network traffic!!!",IDC_STATIC,12,18,278,8 + CONTROL "Enable news feeds",IDC_NEWS_ENBL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,29,169,10 + LTEXT "Interval for news updates (min):",IDC_STATIC,16,40,169,8 + EDITTEXT IDC_ED_INT_NEWS,190,35,40,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN_INT_NEWS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,230,35,14,14 + CONTROL "Enable event notifications",IDC_NOTIF_ENBL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,51,169,10 + LTEXT "Interval for notification updates (min):",IDC_STATIC,16,62,169,8 + EDITTEXT IDC_ED_INT_NOTIF,190,57,40,14,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN_INT_NOTIF,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,230,57,14,14 CONTROL "Special contact always enabled",IDC_SPEC_CONT_ENBL, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,81,278,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,73,278,10 CONTROL "Autoclear news and notification history",IDC_NEWSAUTOCLEAR, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,92,278,10 - GROUPBOX "News types",IDC_STATIC,4,107,293,35 - CONTROL "Wall posts",IDC_F_POSTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,118,129,10 - CONTROL "Photos",IDC_F_PHOTOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,129,129,10 - CONTROL "Photos tags",IDC_F_TAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,118,129,10 - CONTROL "Wall photos",IDC_F_WALLPHOTOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,129,129,10 - GROUPBOX "News sources",IDC_STATIC,4,144,293,46 - CONTROL "Friends",IDC_S_FRIENDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,155,129,10 - CONTROL "Groups",IDC_S_GROUPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,166,129,10 - CONTROL "Include banned sources",IDC_S_BANNED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,177,129,10 - CONTROL "Pages",IDC_S_PAGES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,155,129,10 - CONTROL "Subscriptions to users",IDC_S_FOLLOWING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,166,129,10 - CONTROL "No reposts",IDC_S_NOREPOSTES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,177,129,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,84,278,10 + GROUPBOX "News types",IDC_STATIC,4,98,293,35 + CONTROL "Wall posts",IDC_F_POSTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,109,129,10 + CONTROL "Photos",IDC_F_PHOTOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,120,129,10 + CONTROL "Photos tags",IDC_F_TAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,109,129,10 + CONTROL "Wall photos",IDC_F_WALLPHOTOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,120,129,10 + GROUPBOX "News sources",IDC_STATIC,4,134,293,46 + CONTROL "Friends",IDC_S_FRIENDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,145,129,10 + CONTROL "Groups",IDC_S_GROUPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,156,129,10 + CONTROL "Include banned sources",IDC_S_BANNED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,167,129,10 + CONTROL "Pages",IDC_S_PAGES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,145,129,10 + CONTROL "Subscriptions to users",IDC_S_FOLLOWING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,156,129,10 + CONTROL "No reposts",IDC_S_NOREPOSTES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,167,129,10 + GROUPBOX "Notifications types",IDC_STATIC,4,181,293,36 + CONTROL "Comments",IDC_N_COMMENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,192,129,10 + CONTROL "Likes",IDC_N_LIKES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,203,129,10 + CONTROL "Reposts",IDC_N_REPOSTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,192,129,10 + CONTROL "Mentions in comments",IDC_N_MENTIONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,154,203,129,10 END IDD_ACCMGRUI DIALOGEX 0, 0, 186, 68 diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp index 83231b2228..05d2574408 100644 --- a/protocols/VKontakte/src/misc.cpp +++ b/protocols/VKontakte/src/misc.cpp @@ -670,9 +670,9 @@ CMString CVkProto::SpanVKNotificationType(CMString& tszType, VKObjType& vkFeedba { _T("follow"), vkNull, vkUsers, _T("") }, { _T("friend_accepted"), vkNull, vkUsers, _T("") }, { _T("mention"), vkNull, vkPost, _T("") }, - { _T("mention_comments"), vkPost, vkComment, _T("") }, { _T("wall"), vkNull, vkPost, _T("") }, { _T("wall_publish"), vkNull, vkPost, _T("") }, + { _T("comment_post"), vkPost, vkComment, TranslateT("commented on your post") }, { _T("comment_photo"), vkPhoto, vkComment, TranslateT("commented on your photo") }, { _T("comment_video"), vkVideo, vkComment, TranslateT("commented on your video") }, @@ -690,8 +690,9 @@ CMString CVkProto::SpanVKNotificationType(CMString& tszType, VKObjType& vkFeedba { _T("copy_post"), vkPost, vkCopy, TranslateT("shared your post") }, { _T("copy_photo"), vkPhoto, vkCopy, TranslateT("shared your photo") }, { _T("copy_video"), vkVideo, vkCopy, TranslateT("shared your video") }, - { _T("mention_comment_photo"), vkPhoto, vkComment, _T("") }, - { _T("mention_comment_video"), vkVideo, vkComment, _T("") } + { _T("mention_comments"), vkPost, vkComment, _T("mentioned you in comment") }, + { _T("mention_comment_photo"), vkPhoto, vkComment, _T("mentioned you in comment to photo") }, + { _T("mention_comment_video"), vkVideo, vkComment, _T("mentioned you in comment to video") } }; CMString tszRes; @@ -748,6 +749,66 @@ CMString CVkProto::GetVkPhotoItem(JSONNODE *pPhoto) return tszRes; } +CMString CVkProto::SetBBCString(TCHAR *tszString, VKBBCType bbcType, TCHAR *tszAddString) +{ + CVKBBCItem bbcItem[] = { + { vkbbcB, bbcNo, _T("%s") }, + { vkbbcB, bbcBasic, _T("[b]%s[/b]") }, + { vkbbcB, bbcAdvanced, _T("[b]%s[/b]") }, + { vkbbcI, bbcNo, _T("%s") }, + { vkbbcI, bbcBasic, _T("[i]%s[/i]") }, + { vkbbcI, bbcAdvanced, _T("[i]%s[/i]") }, + { vkbbcS, bbcNo, _T("%s") }, + { vkbbcS, bbcBasic, _T("[s]%s[/s]") }, + { vkbbcS, bbcAdvanced, _T("[s]%s[/s]") }, + { vkbbcU, bbcNo, _T("%s") }, + { vkbbcU, bbcBasic, _T("[u]%s[/u]") }, + { vkbbcU, bbcAdvanced, _T("[u]%s[/u]") }, + { vkbbcUrl, bbcNo, _T("%s (%s)") }, + { vkbbcUrl, bbcBasic, _T("[b]%s[/b] (%s)") }, + { vkbbcUrl, bbcAdvanced, _T("[url=%s]%s[/url]") }, + { vkbbcSize, bbcNo, _T("%s") }, + { vkbbcSize, bbcBasic, _T("%s") }, + { vkbbcSize, bbcAdvanced, _T("[size=%s]%s[/size]") }, + { vkbbcColor, bbcNo, _T("%s") }, + { vkbbcColor, bbcBasic, _T("%s") }, + { vkbbcColor, bbcAdvanced, _T("[color=%s]%s[/color]") }, + }; + + TCHAR *ptszFormat = NULL; + for (int i = 0; i < SIZEOF(bbcItem); i++) + if (bbcItem[i].vkBBCType == bbcType && bbcItem[i].vkBBCSettings == m_iBBCForNews){ + ptszFormat = bbcItem[i].ptszTempate; + break; + } + + CMString res; + if (ptszFormat == NULL) + return CMString(tszString); + + if (bbcType == vkbbcUrl && m_iBBCForNews != bbcAdvanced) + res.AppendFormat(ptszFormat, tszString ? tszString : _T(""), tszAddString ? tszAddString : _T("")); + else if (m_iBBCForNews == bbcAdvanced && bbcType >= vkbbcUrl) + res.AppendFormat(ptszFormat, tszAddString ? tszAddString : _T(""), tszString ? tszString : _T("")); + else + res.AppendFormat(ptszFormat, tszString ? tszString : _T("")); + + return res; +} + +CMString& CVkProto::ClearFormatNick(CMString& tszText) +{ + int iNameEnd = tszText.Find(_T("],")), iNameBeg = tszText.Find(_T("|")); + if (iNameEnd != -1 && iNameBeg != -1 && iNameBeg < iNameEnd){ + CMString tszName = tszText.Mid(iNameBeg + 1, iNameEnd - iNameBeg - 1); + CMString tszBody = tszText.Mid(iNameEnd + 2); + if (!tszName.IsEmpty() && !tszBody.IsEmpty()) + tszText = tszName + _T(",") + tszBody; + } + + return tszText; +} + ///////////////////////////////////////////////////////////////////////////////////////// CMString CVkProto::GetAttachmentDescr(JSONNODE *pAttachments) @@ -860,50 +921,3 @@ CMString CVkProto::GetAttachmentDescr(JSONNODE *pAttachments) return res; } - -CMString CVkProto::SetBBCString(TCHAR *tszString, VKBBCType bbcType, TCHAR *tszAddString) -{ - CVKBBCItem bbcItem[] = { - { vkbbcB, bbcNo, _T("%s") }, - { vkbbcB, bbcBasic, _T("[b]%s[/b]") }, - { vkbbcB, bbcAdvanced, _T("[b]%s[/b]") }, - { vkbbcI, bbcNo, _T("%s") }, - { vkbbcI, bbcBasic, _T("[i]%s[/i]") }, - { vkbbcI, bbcAdvanced, _T("[i]%s[/i]") }, - { vkbbcS, bbcNo, _T("%s") }, - { vkbbcS, bbcBasic, _T("[s]%s[/s]") }, - { vkbbcS, bbcAdvanced, _T("[s]%s[/s]") }, - { vkbbcU, bbcNo, _T("%s") }, - { vkbbcU, bbcBasic, _T("[u]%s[/u]") }, - { vkbbcU, bbcAdvanced, _T("[u]%s[/u]") }, - { vkbbcUrl, bbcNo, _T("%s (%s)") }, - { vkbbcUrl, bbcBasic, _T("[b]%s[/b] (%s)") }, - { vkbbcUrl, bbcAdvanced, _T("[url=%s]%s[/url]") }, - { vkbbcSize, bbcNo, _T("%s") }, - { vkbbcSize, bbcBasic, _T("%s") }, - { vkbbcSize, bbcAdvanced, _T("[size=%s]%s[/size]") }, - { vkbbcColor, bbcNo, _T("%s") }, - { vkbbcColor, bbcBasic, _T("%s") }, - { vkbbcColor, bbcAdvanced, _T("[color=%s]%s[/color]") }, - }; - - TCHAR *ptszFormat = NULL; - for (int i = 0; i < SIZEOF(bbcItem); i++) - if (bbcItem[i].vkBBCType == bbcType && bbcItem[i].vkBBCSettings == m_iBBCForNews){ - ptszFormat = bbcItem[i].ptszTempate; - break; - } - - CMString res; - if (ptszFormat == NULL) - return CMString(tszString); - - if (bbcType == vkbbcUrl && m_iBBCForNews != bbcAdvanced) - res.AppendFormat(ptszFormat, tszString ? tszString : _T(""), tszAddString ? tszAddString : _T("")); - else if (m_iBBCForNews == bbcAdvanced && bbcType >= vkbbcUrl) - res.AppendFormat(ptszFormat, tszAddString ? tszAddString : _T(""), tszString ? tszString : _T("")); - else - res.AppendFormat(ptszFormat, tszString ? tszString : _T("")); - - return res; -} \ No newline at end of file diff --git a/protocols/VKontakte/src/resource.h b/protocols/VKontakte/src/resource.h index 252877ef6d..a86f9fc703 100644 --- a/protocols/VKontakte/src/resource.h +++ b/protocols/VKontakte/src/resource.h @@ -85,6 +85,10 @@ #define IDC_S_FOLLOWING 1077 #define IDC_S_BANNED 1078 #define IDC_S_NOREPOSTES 1079 +#define IDC_N_COMMENTS 1080 +#define IDC_N_LIKES 1081 +#define IDC_N_REPOSTS 1082 +#define IDC_N_MENTIONS 1083 // Next default values for new objects // diff --git a/protocols/VKontakte/src/version.h b/protocols/VKontakte/src/version.h index 214cf90db2..30ec6234b9 100644 --- a/protocols/VKontakte/src/version.h +++ b/protocols/VKontakte/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 1 #define __RELEASE_NUM 0 -#define __BUILD_NUM 37 +#define __BUILD_NUM 38 #include diff --git a/protocols/VKontakte/src/vk_feed.cpp b/protocols/VKontakte/src/vk_feed.cpp index 0488f5a4c1..918bbd2618 100644 --- a/protocols/VKontakte/src/vk_feed.cpp +++ b/protocols/VKontakte/src/vk_feed.cpp @@ -49,6 +49,11 @@ void CVkProto::AddFeedSpecialUser() void CVkProto::AddFeedEvent(CMString& tszBody, time_t tTime) { + if (tszBody.IsEmpty()) { + debugLogA("CVkProto::AddFeedEvent %d", tTime); + return; + } + MCONTACT hContact = FindUser(VK_FEED_USER, true); ptrT ptszBody(mir_tstrdup(tszBody.GetBuffer())); PROTORECVEVENT recv = { 0 }; @@ -264,118 +269,159 @@ CMString CVkProto::GetVkFeedback(JSONNODE *pFeedback, VKObjType vkFeedbackType, if (iUserId){ vkUser = GetVkUserInfo(iUserId, vkUsers); - CMString tszText = json_as_string(json_get(pFeedback, "text")); - - int iNameEnd = tszText.Find(_T("],")), iNameBeg = tszText.Find(_T("|")); - if (iNameEnd != -1 && iNameBeg != -1 && iNameBeg < iNameEnd){ - CMString tszName = tszText.Mid(iNameBeg + 1, iNameEnd - iNameBeg - 1); - CMString tszBody = tszText.Mid(iNameEnd + 2); - if (!tszName.IsEmpty() && !tszBody.IsEmpty()) - tszText = tszName + _T(",") + tszBody; - } - - tszRes.AppendFormat(tszFormat, SetBBCString(vkUser->m_tszUserNick.GetBuffer(), vkbbcUrl, vkUser->m_tszLink.GetBuffer()), tszText.GetBuffer()); + CMString tszText = json_as_string(json_get(pFeedback, "text")); + tszRes.AppendFormat(tszFormat, SetBBCString(vkUser->m_tszUserNick.GetBuffer(), vkbbcUrl, vkUser->m_tszLink.GetBuffer()), ClearFormatNick(tszText).GetBuffer()); } return tszRes; } -CMString CVkProto::GetVkParent(JSONNODE *pParent, VKObjType vkParentType, TCHAR *ptszReply) +CVKNewsItem* CVkProto::GetVkParent(JSONNODE *pParent, VKObjType vkParentType, TCHAR *ptszReplyText, TCHAR *ptszReplyLink) { debugLogA("CVkProto::GetVkParent"); CMString tszRes; if (!pParent || !vkParentType) - return tszRes; - + return NULL; + + CVKNewsItem * vkNotificationItem = new CVKNewsItem(); + if (vkParentType == vkPhoto) { CMString tszPhoto = GetVkPhotoItem(pParent); LONG iOwnerId = json_as_int(json_get(pParent, "owner_id")); LONG iId = json_as_int(json_get(pParent, "id")); - - CMString tszLink; - tszLink.AppendFormat(_T("https://vk.com/photo%d_%d"), iOwnerId, iId); - tszRes.AppendFormat(_T("\n%s\n%s"), tszPhoto.GetBuffer(), SetBBCString(TranslateT("Link"), vkbbcUrl, tszLink.GetBuffer())); + vkNotificationItem->tszId.AppendFormat(_T("%d_%d"), iOwnerId, iId); + vkNotificationItem->tszLink.AppendFormat(_T("https://vk.com/photo%s"), vkNotificationItem->tszId.GetBuffer()); + vkNotificationItem->tszText.AppendFormat(_T("\n%s"), tszPhoto.GetBuffer()); + + if (ptszReplyText) + vkNotificationItem->tszText.AppendFormat(_T("\n>> %s"), SetBBCString(ptszReplyText, vkbbcI).GetBuffer()); + + vkNotificationItem->tszText.AppendFormat(_T("\n%s"), SetBBCString(TranslateT("Link"), vkbbcUrl, vkNotificationItem->tszLink.GetBuffer()).GetBuffer()); } else if (vkParentType == vkVideo) { LONG iOwnerId = json_as_int(json_get(pParent, "owner_id")); LONG iId = json_as_int(json_get(pParent, "id")); CMString tszTitle = json_as_string(json_get(pParent, "title")); - CMString tszLink; - tszLink.AppendFormat(_T("https://vk.com/video%d_%d"), iOwnerId, iId); - tszRes.AppendFormat(_T("\n%s"), SetBBCString(tszTitle.GetBuffer(), vkbbcUrl, tszLink.GetBuffer())); + vkNotificationItem->tszId.AppendFormat(_T("%d_%d"), iOwnerId, iId); + vkNotificationItem->tszLink.AppendFormat(_T("https://vk.com/video%s"), vkNotificationItem->tszId.GetBuffer()); + + CMString tszText = json_as_string(json_get(pParent, "text")); + ClearFormatNick(tszText); + + if (!tszText.IsEmpty()) + vkNotificationItem->tszText.AppendFormat(_T("\n%s: %s"), SetBBCString(TranslateT("Video description:"), vkbbcB), SetBBCString(tszText.GetBuffer(), vkbbcI).GetBuffer()); + + if (ptszReplyText) + vkNotificationItem->tszText.AppendFormat(_T("\n>> %s"), SetBBCString(ptszReplyText, vkbbcI).GetBuffer()); + + vkNotificationItem->tszText.AppendFormat(_T("\n%s"), SetBBCString(tszTitle.GetBuffer(), vkbbcUrl, vkNotificationItem->tszLink.GetBuffer()).GetBuffer()); } else if (vkParentType == vkPost) { LONG iOwnerId = json_as_int(json_get(pParent, "from_id")); LONG iId = json_as_int(json_get(pParent, "id")); - CMString tszLink; - tszLink.AppendFormat(_T("https://vk.com/wall%d_%d%s"), iOwnerId, iId, ptszReply ? ptszReply : _T("")); - tszRes.AppendFormat(_T("\n%s"), SetBBCString(TranslateT("Link"), vkbbcUrl, tszLink.GetBuffer())); + vkNotificationItem->tszId.AppendFormat(_T("%d_%d"), iOwnerId, iId); + vkNotificationItem->tszLink.AppendFormat(_T("https://vk.com/wall%s%s"), vkNotificationItem->tszId.GetBuffer(), ptszReplyLink ? ptszReplyLink : _T("")); + + CMString tszText = json_as_string(json_get(pParent, "text")); + ClearFormatNick(tszText); + + if (!tszText.IsEmpty()) + vkNotificationItem->tszText.AppendFormat(_T("\n%s: %s"), SetBBCString(TranslateT("Post text:"), vkbbcB), SetBBCString(tszText.GetBuffer(), vkbbcI).GetBuffer()); + + if (ptszReplyText) + vkNotificationItem->tszText.AppendFormat(_T("\n>> %s"), SetBBCString(ptszReplyText, vkbbcI).GetBuffer()); + + vkNotificationItem->tszText.AppendFormat(_T("\n%s"), SetBBCString(TranslateT("Link"), vkbbcUrl, vkNotificationItem->tszLink.GetBuffer()).GetBuffer()); } else if (vkParentType == vkTopic) { LONG iOwnerId = json_as_int(json_get(pParent, "owner_id")); LONG iId = json_as_int(json_get(pParent, "id")); CMString tszTitle = json_as_string(json_get(pParent, "title")); - CMString tszLink; - tszLink.AppendFormat(_T("https://vk.com/topic%d_%d%s"), iOwnerId, iId, ptszReply ? ptszReply : _T("")); - tszRes.AppendFormat(_T("\n%s"), SetBBCString(tszTitle.GetBuffer(), vkbbcUrl, tszLink.GetBuffer())); + vkNotificationItem->tszId.AppendFormat(_T("%d_%d"), iOwnerId, iId); + vkNotificationItem->tszLink.AppendFormat(_T("https://vk.com/topic%s%s"), + vkNotificationItem->tszId.GetBuffer(), ptszReplyLink ? ptszReplyLink : _T("")); + + CMString tszText = json_as_string(json_get(pParent, "text")); + ClearFormatNick(tszText); + + if (!tszText.IsEmpty()) + vkNotificationItem->tszText.AppendFormat(_T("\n%s: %s"), SetBBCString(TranslateT("Topic text:"), vkbbcB), SetBBCString(tszText.GetBuffer(), vkbbcI).GetBuffer()); + + if (ptszReplyText) + vkNotificationItem->tszText.AppendFormat(_T("\n>> %s"), SetBBCString(ptszReplyText, vkbbcI).GetBuffer()); + + vkNotificationItem->tszText.AppendFormat(_T("\n%s"), SetBBCString(tszTitle.GetBuffer(), vkbbcUrl, vkNotificationItem->tszLink.GetBuffer()).GetBuffer()); } else if (vkParentType == vkComment) { + CMString tszText = json_as_string(json_get(pParent, "text")); + ClearFormatNick(tszText); + JSONNODE *pNode = json_get(pParent, "photo"); if (pNode) - return GetVkParent(pNode, vkPhoto); + return GetVkParent(pNode, vkPhoto, tszText.IsEmpty() ? NULL : tszText.GetBuffer()); pNode = json_get(pParent, "video"); if (pNode) - return GetVkParent(pNode, vkVideo); + return GetVkParent(pNode, vkVideo, tszText.IsEmpty() ? NULL : tszText.GetBuffer()); LONG iId = json_as_int(json_get(pParent, "id")); pNode = json_get(pParent, "post"); if (pNode){ CMString tszRepl; - tszRepl.AppendFormat(_T("?reply=%d"), iId); - tszRes = GetVkParent(pNode, vkPost, tszRepl.GetBuffer()); - return tszRes; + tszRepl.AppendFormat(_T("?reply=%d"), iId); + return GetVkParent(pNode, vkPost, tszText.IsEmpty() ? NULL : tszText.GetBuffer(), tszRepl.GetBuffer()); } pNode = json_get(pParent, "topic"); if (pNode){ - CMString tszRepl; + CMString tszRepl; tszRepl.AppendFormat(_T("?reply=%d"), iId); - tszRes = GetVkParent(pNode, vkTopic, tszRepl.GetBuffer()); - return tszRes; + return GetVkParent(pNode, vkTopic, tszText.IsEmpty() ? NULL : tszText.GetBuffer(), tszRepl.GetBuffer()); } } - return tszRes; + return vkNotificationItem; } -CMString CVkProto::GetVkNotificationsItem(JSONNODE *pItem, OBJLIST &vkUsers, time_t &tDate) +CVKNewsItem* CVkProto::GetVkNotificationsItem(JSONNODE *pItem, OBJLIST &vkUsers) { debugLogA("CVkProto::GetVkNotificationsItem"); - CMString tszRes; if (pItem == NULL) - return tszRes; + return NULL; CMString tszType = json_as_string(json_get(pItem, "type")); - tDate = json_as_int(json_get(pItem, "date")); - VKObjType vkFeedbackType = vkNull, vkParentType = vkNull; CMString tszNotificationTranslate = SpanVKNotificationType(tszType, vkFeedbackType, vkParentType); JSONNODE *pFeedback = json_get(pItem, "feedback"); if (!pFeedback) - return tszRes; + return NULL; CVkUserInfo *vkUser = NULL; CMString tszFeedback = GetVkFeedback(pFeedback, vkFeedbackType, vkUsers, vkUser); JSONNODE *pParent = json_get(pItem, "parent"); if (!pParent) - return tszRes; - CMString tszParent = GetVkParent(pParent, vkParentType); - if (!tszParent.IsEmpty() && !tszFeedback.IsEmpty()) - tszRes.AppendFormat(tszFeedback, tszNotificationTranslate.GetBuffer(), tszParent.GetBuffer()); - return tszRes; + return NULL; + + CVKNewsItem* vkNotification = GetVkParent(pParent, vkParentType); + if (!vkNotification) + return NULL; + + if (vkNotification && !tszFeedback.IsEmpty()){ + CMString tszNotificaton; + tszNotificaton.AppendFormat(tszFeedback, tszNotificationTranslate.GetBuffer(), vkNotification->tszText.GetBuffer()); + vkNotification->tszText = tszNotificaton; + vkNotification->tszType = tszType; + vkNotification->tDate = json_as_int(json_get(pItem, "date")); + vkNotification->vkFeedbackType = vkFeedbackType; + vkNotification->vkParentType = vkParentType; + vkNotification->vkUser = vkUser; + return vkNotification; + } + + delete vkNotification; + return NULL; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -456,6 +502,8 @@ void CVkProto::OnReceiveUnreadNews(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *p if (pItems != NULL) for (int i = 0; (pItem = json_at(pItems, i)) != NULL; i++){ CVKNewsItem *vkNewsItem = GetVkNewsItem(pItem, vkUsers); + if (!vkNewsItem) + continue; if (vkNews.find(vkNewsItem) == NULL) vkNews.insert(vkNewsItem); else @@ -479,14 +527,29 @@ void CVkProto::RetrieveUnreadNotifications(time_t tLastNotificationsTime) debugLogA("CVkProto::RetrieveUnreadNotifications"); if (!IsOnline()) return; - + Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/notifications.get.json", true, &CVkProto::OnReceiveUnreadNotifications) << INT_PARAM("count", 100) << INT_PARAM("start_time", tLastNotificationsTime + 1) - << CHAR_PARAM("filters", "comments,likes,reposts") << VER_API); } +bool CVkProto::FilterNotification(CVKNewsItem* vkNotificationItem) +{ + if (vkNotificationItem->vkParentType == vkNull) + return false; + + if (vkNotificationItem->tszType == _T("mention_comments") + || vkNotificationItem->tszType == _T("mention_comment_photo") + || vkNotificationItem->tszType == _T("mention_comment_video")) + return m_bNotificationFilterMentions; + + bool result = (vkNotificationItem->vkFeedbackType == vkUsers && m_bNotificationFilterLikes); + result = (vkNotificationItem->vkFeedbackType == vkCopy && m_bNotificationFilterReposts) || result; + result = (vkNotificationItem->vkFeedbackType == vkComment && m_bNotificationFilterComments) || result; + return result; +} + void CVkProto::OnReceiveUnreadNotifications(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnReceiveUnreadNotifications %d", reply->resultCode); @@ -504,14 +567,24 @@ void CVkProto::OnReceiveUnreadNotifications(NETLIBHTTPREQUEST *reply, AsyncHttpR JSONNODE *pItems = json_get(pResponse, "items"); JSONNODE *pItem; + OBJLIST vkNotification(5, sttCompareVKNewsItems); if (pItems != NULL) - for (int i = 0; (pItem = json_at(pItems, i)) != NULL; i++){ - time_t tDate; - CMString tszText = GetVkNotificationsItem(pItem, vkUsers, tDate); - AddFeedEvent(tszText, tDate); + for (int i = 0; (pItem = json_at(pItems, i)) != NULL; i++){ + CVKNewsItem *vkNotificationItem = GetVkNotificationsItem(pItem, vkUsers); + if (!vkNotificationItem) + continue; + if (vkNotification.find(vkNotificationItem) == NULL) + vkNotification.insert(vkNotificationItem); + else + delete vkNotificationItem; } + for (int i = 0; i < vkNotification.getCount(); i++) + if (FilterNotification(&vkNotification[i])) + AddFeedEvent(vkNotification[i].tszText, vkNotification[i].tDate); + setDword("LastNotificationsTime", time(NULL)); + vkNotification.destroy(); vkUsers.destroy(); } diff --git a/protocols/VKontakte/src/vk_options.cpp b/protocols/VKontakte/src/vk_options.cpp index 4cff0b64a6..8316977d2b 100644 --- a/protocols/VKontakte/src/vk_options.cpp +++ b/protocols/VKontakte/src/vk_options.cpp @@ -362,6 +362,11 @@ INT_PTR CALLBACK CVkProto::OptionsFeedsProc(HWND hwndDlg, UINT uMsg, WPARAM wPar CheckDlgButton(hwndDlg, IDC_S_BANNED, ppro->m_bNewsSourceIncludeBanned ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_S_NOREPOSTES, ppro->m_bNewsSourceNoReposts ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_N_COMMENTS, ppro->m_bNotificationFilterComments ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_N_LIKES, ppro->m_bNotificationFilterLikes ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_N_REPOSTS, ppro->m_bNotificationFilterReposts ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_N_MENTIONS, ppro->m_bNotificationFilterMentions ? BST_CHECKED : BST_UNCHECKED); + SendDlgItemMessage(hwndDlg, IDC_SPIN_INT_NEWS, UDM_SETRANGE, 0, MAKELONG(60*24, 1)); SendDlgItemMessage(hwndDlg, IDC_SPIN_INT_NEWS, UDM_SETPOS, 0, ppro->m_iNewsInterval); @@ -392,6 +397,10 @@ INT_PTR CALLBACK CVkProto::OptionsFeedsProc(HWND hwndDlg, UINT uMsg, WPARAM wPar case IDC_S_FOLLOWING: case IDC_S_BANNED: case IDC_S_NOREPOSTES: + case IDC_N_COMMENTS: + case IDC_N_LIKES: + case IDC_N_REPOSTS: + case IDC_N_MENTIONS: if (HIWORD(wParam) == BN_CLICKED && (HWND)lParam == GetFocus()) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; @@ -445,6 +454,18 @@ INT_PTR CALLBACK CVkProto::OptionsFeedsProc(HWND hwndDlg, UINT uMsg, WPARAM wPar ppro->m_bNewsSourceNoReposts = IsDlgButtonChecked(hwndDlg, IDC_S_NOREPOSTES) == BST_CHECKED; ppro->setByte("NewsSourceNoReposts", ppro->m_bNewsSourceNoReposts); + ppro->m_bNotificationFilterComments = IsDlgButtonChecked(hwndDlg, IDC_N_COMMENTS) == BST_CHECKED; + ppro->setByte("NotificationFilterComments", ppro->m_bNotificationFilterComments); + + ppro->m_bNotificationFilterLikes = IsDlgButtonChecked(hwndDlg, IDC_N_LIKES) == BST_CHECKED; + ppro->setByte("NotificationFilterLikes", ppro->m_bNotificationFilterLikes); + + ppro->m_bNotificationFilterReposts = IsDlgButtonChecked(hwndDlg, IDC_N_REPOSTS) == BST_CHECKED; + ppro->setByte("NotificationFilterReposts", ppro->m_bNotificationFilterReposts); + + ppro->m_bNotificationFilterMentions = IsDlgButtonChecked(hwndDlg, IDC_N_REPOSTS) == BST_CHECKED; + ppro->setByte("NotificationFilterMentions", ppro->m_bNotificationFilterMentions); + TCHAR buffer[5] = { 0 }; GetDlgItemText(hwndDlg, IDC_ED_INT_NEWS, buffer, SIZEOF(buffer)); ppro->setDword("NewsInterval", ppro->m_iNewsInterval = _ttoi(buffer)); diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp index 61c11dde35..a0f8444fc2 100644 --- a/protocols/VKontakte/src/vk_proto.cpp +++ b/protocols/VKontakte/src/vk_proto.cpp @@ -98,6 +98,11 @@ CVkProto::CVkProto(const char *szModuleName, const TCHAR *ptszUserName) : m_bNewsSourceIncludeBanned = getBool("NewsSourceIncludeBanned", false); m_bNewsSourceNoReposts = getBool("NewsSourceNoReposts", false); + m_bNotificationFilterComments = getBool("NotificationFilterComments", true); + m_bNotificationFilterLikes = getBool("NotificationFilterComments", true); + m_bNotificationFilterReposts = getBool("NotificationFilterComments", true); + m_bNotificationFilterMentions = getBool("NotificationFilterMentions", true); + // Set all contacts offline -- in case we crashed SetAllContactStatuses(ID_STATUS_OFFLINE); vk_Instances.insert(this); diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index 7355130c1c..96ff1b0123 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -194,6 +194,7 @@ struct CVKNewsItem : public MZeroedObject { tDate = NULL; vkUser = NULL; bIsGroup = bIsRepost = false; + vkFeedbackType = vkParentType = vkNull; }; CMString tszId; @@ -202,6 +203,7 @@ struct CVKNewsItem : public MZeroedObject { CMString tszText; CMString tszLink; CMString tszType; + VKObjType vkFeedbackType, vkParentType; bool bIsGroup; bool bIsRepost; }; @@ -356,14 +358,15 @@ struct CVkProto : public PROTO CVKNewsItem* GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, bool isRepost = false); - CMString GetVkNotificationsItem(JSONNODE *pItem, OBJLIST &vkUsers, time_t &tDate); + CVKNewsItem* GetVkNotificationsItem(JSONNODE *pItem, OBJLIST &vkUsers); CMString GetVkFeedback(JSONNODE *pFeedback, VKObjType vkFeedbackType, OBJLIST &vkUsers, CVkUserInfo *vkUser); - CMString GetVkParent(JSONNODE *pParent, VKObjType vkParentType, TCHAR *ptszReply = NULL); + CVKNewsItem* GetVkParent(JSONNODE *pParent, VKObjType vkParentType, TCHAR *ptszReplyText = NULL, TCHAR *ptszReplyLink = NULL); void RetrieveUnreadNews(time_t tLastNewsTime); void OnReceiveUnreadNews(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void RetrieveUnreadNotifications(time_t tLastNotificationsTime); + bool FilterNotification(CVKNewsItem* vkNotificationItem); void OnReceiveUnreadNotifications(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void RetrieveUnreadEvents(); void NewsClearHistory(); @@ -401,6 +404,7 @@ struct CVkProto : public PROTO CMString SpanVKNotificationType(CMString& tszType, VKObjType& vkFeedback, VKObjType& vkParent); CMString SetBBCString(TCHAR *tszString, VKBBCType, TCHAR *tszAddString = NULL); + CMString& ClearFormatNick(CMString& tszText); CMString GetAttachmentDescr(JSONNODE*); @@ -562,7 +566,11 @@ private: m_bNewsSourcePages, m_bNewsSourceFollowing, m_bNewsSourceIncludeBanned, - m_bNewsSourceNoReposts; + m_bNewsSourceNoReposts, + m_bNotificationFilterComments, + m_bNotificationFilterLikes, + m_bNotificationFilterReposts, + m_bNotificationFilterMentions; int m_iNewsInterval, m_iNotificationsInterval, m_iNewsAutoClearHistoryInterval; -- cgit v1.2.3