diff options
author | George Hazan <ghazan@miranda.im> | 2019-03-02 12:32:44 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2019-03-02 12:32:55 +0300 |
commit | 931a7dc1ac0dbc7e6c1083583ced915e572f5b47 (patch) | |
tree | 9fe9a6448d44030e26aa7107ce16044ed413e0d0 /protocols/GmailNotifier/src | |
parent | dd7d9954042254e66e3bbbec7195c6be8b1a0663 (diff) |
all protocols (even virtual ones) moved to the Protocols folder
Diffstat (limited to 'protocols/GmailNotifier/src')
-rw-r--r-- | protocols/GmailNotifier/src/check.cpp | 149 | ||||
-rw-r--r-- | protocols/GmailNotifier/src/main.cpp | 162 | ||||
-rw-r--r-- | protocols/GmailNotifier/src/notify.cpp | 206 | ||||
-rw-r--r-- | protocols/GmailNotifier/src/options.cpp | 284 | ||||
-rw-r--r-- | protocols/GmailNotifier/src/resource.h | 47 | ||||
-rw-r--r-- | protocols/GmailNotifier/src/stdafx.cxx | 18 | ||||
-rw-r--r-- | protocols/GmailNotifier/src/stdafx.h | 100 | ||||
-rw-r--r-- | protocols/GmailNotifier/src/utility.cpp | 77 | ||||
-rw-r--r-- | protocols/GmailNotifier/src/version.h | 13 |
9 files changed, 1056 insertions, 0 deletions
diff --git a/protocols/GmailNotifier/src/check.cpp b/protocols/GmailNotifier/src/check.cpp new file mode 100644 index 0000000000..06a1926ef1 --- /dev/null +++ b/protocols/GmailNotifier/src/check.cpp @@ -0,0 +1,149 @@ +#include "stdafx.h" + +#pragma comment(lib, "Wininet.lib") + +static int ParsePage(char *page, resultLink *prst) +{ + char *str_head; + char *str_tail; + char name[64], title[64]; + int num = 0; + wchar_t str[64]; + + prst->next = nullptr; + if (!(str_head = strstr(page, "<entry>"))) + return 0; + + while (str_head = strstr(str_head, "<title>")) { + prst = prst->next = (resultLink *)malloc(sizeof(resultLink)); + str_head += 7; + str_tail = strstr(str_head, "</title>"); + *str_tail = '\0'; + mir_strncpy(title, str_head, 41); + if (mir_strlen(title) == 40) + mir_strcat(title, "..."); + *str_tail = ' '; + + str_head = strstr(str_head, "<name>") + 6; + str_tail = strstr(str_head, "</name>"); + *str_tail = '\0'; + mir_strncpy(name, str_head, 11); + mir_strcat(name, ": "); + *str_tail = ' '; + + mir_strcpy(prst->content, name); + mir_strcat(prst->content, title); + MultiByteToWideChar(CP_UTF8, 0, prst->content, -1, str, 64); + WideCharToMultiByte(CP_ACP, 0, str, -1, prst->content, 64, nullptr, nullptr); + num++; + } + prst->next = nullptr; + return num; +} + +void CheckMailInbox(Account *curAcc) +{ + if (curAcc->IsChecking) + return; + + curAcc->IsChecking = true; + + ptrA szNick(db_get_sa(curAcc->hContact, "CList", "MyHandle", curAcc->name)); + + char *tail = strstr(szNick, " ["); + if (tail) *tail = 0; + + db_set_s(curAcc->hContact, "CList", "MyHandle", CMStringA(FORMAT, "%s [%s]", szNick.get(), Translate("Checking..."))); + + if (curAcc->hosted[0]) { + CMStringA szUrl(FORMAT, "https://www.google.com/a/%s/LoginAction", curAcc->hosted); + CMStringA szBody("continue=https%3A%2F%2Fmail.google.com%2Fa%2F"); + szBody.Append(curAcc->hosted); + szBody.Append("%2Ffeed%2Fatom&service=mail&userName="); + tail = strchr(curAcc->name, '@'); + if (tail) *tail = 0; + szBody.Append(curAcc->name); + if (tail) *tail = '@'; + szBody.Append("&password="); + szBody.Append(curAcc->pass); + + NETLIBHTTPHEADER headers[1] = { + { "Content-Type", "application/x-www-form-urlencoded" } + }; + + NETLIBHTTPREQUEST nlr = {}; + nlr.cbSize = sizeof(nlr); + nlr.szUrl = szUrl.GetBuffer(); + nlr.requestType = REQUEST_POST; + nlr.headersCount = _countof(headers); + nlr.headers = headers; + nlr.dataLength = szBody.GetLength(); + nlr.pData = szBody.GetBuffer(); + + NETLIBHTTPREQUEST *nlu = Netlib_HttpTransaction(hNetlibUser, &nlr); + if (nlu == nullptr || nlu->resultCode != 200) { + mir_strcpy(curAcc->results.content, Translate("Can't send account data!")); + + Netlib_FreeHttpRequest(nlu); + curAcc->results_num = -1; + mir_strcat(curAcc->results.content, "]"); + curAcc->IsChecking = false; + return; + } + + Netlib_FreeHttpRequest(nlu); + } + + // go! + CMStringA loginPass(FORMAT, "%s:%s", curAcc->name, curAcc->pass); + ptrA loginPassEncoded(mir_base64_encode(loginPass.c_str(), loginPass.GetLength())); + + CMStringA szUrl("https://mail.google.com"), szAuth(FORMAT, "Basic %s", loginPassEncoded.get()); + if (curAcc->hosted[0]) + szUrl.AppendFormat("/a/%s/feed/atom", curAcc->hosted); + else + szUrl.Append("/mail/feed/atom"); + + NETLIBHTTPHEADER headers[1] = { + { "Authorization", szAuth.GetBuffer() } + }; + + NETLIBHTTPREQUEST nlr = {}; + nlr.cbSize = sizeof(nlr); + nlr.szUrl = szUrl.GetBuffer(); + nlr.requestType = REQUEST_GET; + nlr.headers = headers; + nlr.headersCount = _countof(headers); + + NETLIBHTTPREQUEST *nlu = Netlib_HttpTransaction(hNetlibUser, &nlr); + if (nlu == nullptr) { + mir_snprintf(curAcc->results.content, "%s [%s]", szNick.get(), + (nlr.resultCode == 401) ? Translate("Wrong name or password!") : Translate("Can't get RSS feed!")); + Netlib_FreeHttpRequest(nlu); + + curAcc->results_num = -1; + curAcc->IsChecking = false; + return; + } + + curAcc->results_num = ParsePage(nlu->pData, &curAcc->results); + mir_snprintf(curAcc->results.content, "%s [%d]", szNick.get(), curAcc->results_num); + + curAcc->IsChecking = false; +} + +void __cdecl Check_ThreadFunc(void *lpParam) +{ + if (lpParam) { + CheckMailInbox((Account *)lpParam); + NotifyUser((Account *)lpParam); + } + else { + for (auto &it : g_accs) { + if (GetContactProto(it->hContact)) { + CheckMailInbox(it); + NotifyUser(it); + } + } + } +} diff --git a/protocols/GmailNotifier/src/main.cpp b/protocols/GmailNotifier/src/main.cpp new file mode 100644 index 0000000000..42158bd826 --- /dev/null +++ b/protocols/GmailNotifier/src/main.cpp @@ -0,0 +1,162 @@ +/* +Miranda plugin template, originally by Richard Hughes +http://miranda-icq.sourceforge.net/ + +This file is placed in the public domain. Anybody is free to use or +modify it as they wish with no restriction. +There is no warranty. +*/ + +#include "stdafx.h" +#include "version.h" + +CMPlugin g_plugin; + +UINT hTimer; +HNETLIBUSER hNetlibUser; +NOTIFYICONDATA niData; +optionSettings opt; + +OBJLIST<Account> g_accs(1); +BOOL optionWindowIsOpen = FALSE; +short ID_STATUS_NONEW; + +///////////////////////////////////////////////////////////////////////////////////////// + +static PLUGININFOEX pluginInfoEx = +{ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + // {243955E0-75D9-4CC3-9B28-6F9C5AF4532D} + { 0x243955e0, 0x75d9, 0x4cc3, { 0x9b, 0x28, 0x6f, 0x9c, 0x5a, 0xf4, 0x53, 0x2d } } +}; + +CMPlugin::CMPlugin() : + PLUGIN<CMPlugin>(MODULENAME, pluginInfoEx) +{ + RegisterProtocol(PROTOTYPE_VIRTUAL); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR GetCaps(WPARAM wParam, LPARAM) +{ + if (wParam == PFLAGNUM_2 && opt.ShowCustomIcon) + return PF2_ONLINE | PF2_LIGHTDND | PF2_SHORTAWAY; + + return 0; +} + +INT_PTR GetStatus(WPARAM, LPARAM) +{ + return ID_STATUS_ONLINE; +} + +INT_PTR GetName(WPARAM wParam, LPARAM lParam) +{ + mir_strncpy((char*)lParam, MODULENAME, wParam); + return 0; +} + +void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) +{ + PluginMenuCommand(0, 0); +} + +INT_PTR PluginMenuCommand(WPARAM hContact, LPARAM) +{ + if (!optionWindowIsOpen) + mir_forkthread(Check_ThreadFunc, GetAccountByContact(hContact)); + + return 0; +} + +static int OnMirandaStart(WPARAM, LPARAM) +{ + PluginMenuCommand(0, 0); + return 0; +} + +int CMPlugin::Load() +{ + g_plugin.addSound("Gmail", LPGENW("Other"), LPGENW("Gmail: New thread(s)")); + HookEvent(ME_CLIST_DOUBLECLICKED, OpenBrowser); + + NETLIBUSER nlu = {}; + nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION | NUF_UNICODE; + nlu.szSettingsModule = MODULENAME; + nlu.szDescriptiveName.w = TranslateT("Gmail Notifier connection"); + hNetlibUser = Netlib_RegisterUser(&nlu); + + CreateProtoServiceFunction(MODULENAME, PS_GETCAPS, GetCaps); + CreateProtoServiceFunction(MODULENAME, PS_GETSTATUS, GetStatus); + CreateProtoServiceFunction(MODULENAME, PS_GETNAME, GetName); + CreateServiceFunction("GmailMNotifier/Notifying", Notifying); + + opt.circleTime = g_plugin.getDword("circleTime", 30); + opt.notifierOnTray = g_plugin.getDword("notifierOnTray", TRUE); + opt.notifierOnPop = g_plugin.getDword("notifierOnPop", TRUE); + opt.popupDuration = g_plugin.getDword("popupDuration", -1); + opt.popupBgColor = g_plugin.getDword("popupBgColor", RGB(173, 206, 247)); + opt.popupTxtColor = g_plugin.getDword("popupTxtColor", RGB(0, 0, 0)); + opt.OpenUsePrg = g_plugin.getDword("OpenUsePrg", 0); + opt.ShowCustomIcon = g_plugin.getDword("ShowCustomIcon", FALSE); + opt.UseOnline = g_plugin.getDword("UseOnline", FALSE); + opt.AutoLogin = g_plugin.getDword("AutoLogin", TRUE); + opt.LogThreads = g_plugin.getDword("LogThreads", FALSE); + + DBVARIANT dbv; + if (db_get_s(0, "SkinIcons", "core_status_" MODULENAME "4", &dbv)) { + db_set_s(0, "SkinIcons", "core_status_" MODULENAME "0", "plugins\\GmailNotifier.dll,2"); + db_set_s(0, "SkinIcons", "core_status_" MODULENAME "1", "plugins\\GmailNotifier.dll,2"); + db_set_s(0, "SkinIcons", "core_status_" MODULENAME "2", "plugins\\GmailNotifier.dll,0"); + db_set_s(0, "SkinIcons", "core_status_" MODULENAME "4", "plugins\\GmailNotifier.dll,1"); + } + else db_free(&dbv); + + BuildList(); + ID_STATUS_NONEW = opt.UseOnline ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE; + for (auto &it : g_accs) + db_set_dw(it->hContact, MODULENAME, "Status", ID_STATUS_NONEW); + + hTimer = SetTimer(nullptr, 0, opt.circleTime * 60000, TimerProc); + HookEvent(ME_SYSTEM_MODULESLOADED, OnMirandaStart); + HookEvent(ME_OPT_INITIALISE, OptInit); + + CreateServiceFunction(MODULENAME "/MenuCommand", PluginMenuCommand); + + CMenuItem mi(&g_plugin); + SET_UID(mi, 0xbe16f37, 0x17be, 0x4494, 0xaa, 0xb2, 0x3a, 0xa7, 0x38, 0xfa, 0xf9, 0xcc); + mi.position = -0x7FFFFFFF; + mi.hIcolibItem = Skin_LoadProtoIcon(MODULENAME, ID_STATUS_ONLINE); + mi.name.a = LPGEN("&Check all Gmail inboxes"); + mi.pszService = MODULENAME "/MenuCommand"; + Menu_AddMainMenuItem(&mi); + + SET_UID(mi, 0x22c6ace1, 0xba0c, 0x44b5, 0xa4, 0xd2, 0x1, 0x7d, 0xb1, 0xe0, 0x51, 0xeb); + mi.name.a = LPGEN("&Check Gmail inbox"); + mi.pszService = "/MenuCommand"; + Menu_AddContactMenuItem(&mi, MODULENAME); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int CMPlugin::Unload() +{ + if (hTimer) + KillTimer(nullptr, hTimer); + + for (auto &it : g_accs) + DeleteResults(it->results.next); + g_accs.destroy(); + + Netlib_CloseHandle(hNetlibUser); + return 0; +} diff --git a/protocols/GmailNotifier/src/notify.cpp b/protocols/GmailNotifier/src/notify.cpp new file mode 100644 index 0000000000..54b47560a6 --- /dev/null +++ b/protocols/GmailNotifier/src/notify.cpp @@ -0,0 +1,206 @@ +#include "stdafx.h" + +static void __cdecl Login_ThreadFunc(Account *curAcc) +{ + if (curAcc == nullptr) + return; + + HANDLE hTempFile; + DWORD dwBytesWritten, dwBufSize = 1024; + char szTempName[MAX_PATH]; + char buffer[1024]; + char *str_temp; + char lpPathBuffer[1024]; + + if (GetBrowser(lpPathBuffer)) { + if (opt.AutoLogin == 0) { + if (curAcc->hosted[0]) { + mir_strcat(lpPathBuffer, "https://mail.google.com/a/"); + mir_strcat(lpPathBuffer, curAcc->hosted); + mir_strcat(lpPathBuffer, "/?logout"); + } + else { + mir_strcat(lpPathBuffer, "https://mail.google.com/mail/?logout"); + } + } + else { + if (curAcc->hosted[0]) { + GetTempPathA(dwBufSize, buffer); + GetTempFileNameA(buffer, "gmail", 0, szTempName); + + hTempFile = CreateFileA(szTempName, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + mir_strcpy(buffer, FORMDATA1); + mir_strcat(buffer, curAcc->hosted); + mir_strcat(buffer, FORMDATA2); + mir_strcat(buffer, curAcc->hosted); + mir_strcat(buffer, FORMDATA3); + mir_strcat(buffer, "<input type=hidden name=userName value="); + mir_strcat(buffer, curAcc->name); + if ((str_temp = strstr(buffer, "@")) != nullptr) + *str_temp = '\0'; + mir_strcat(buffer, "><input type=hidden name=password value="); + mir_strcat(buffer, curAcc->pass); + mir_strcat(buffer, "></form></body>"); + WriteFile(hTempFile, buffer, (DWORD)mir_strlen(buffer), &dwBytesWritten, nullptr); + CloseHandle(hTempFile); + mir_strcat(lpPathBuffer, szTempName); + } + else { + mir_strcat(lpPathBuffer, LINK); + mir_strcat(lpPathBuffer, mir_urlEncode(curAcc->name)); + if (opt.AutoLogin == 1) + mir_strcat(lpPathBuffer, "&PersistentCookie=yes"); + } + } + } + + STARTUPINFOA suInfo = { 0 }; + PROCESS_INFORMATION procInfo; + suInfo.cb = sizeof(suInfo); + suInfo.wShowWindow = SW_MAXIMIZE; + if (CreateProcessA(nullptr, lpPathBuffer, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &suInfo, &procInfo)) + CloseHandle(procInfo.hProcess); + + if (curAcc->hosted[0]) { + Sleep(30000); + DeleteFileA(szTempName); + } +} + +int OpenBrowser(WPARAM hContact, LPARAM) +{ + char *proto = GetContactProto(hContact); + if (proto && !mir_strcmp(proto, MODULENAME)) { + Account *curAcc = GetAccountByContact(hContact); + PUDeletePopup(curAcc->popUpHwnd); + g_clistApi.pfnRemoveEvent(curAcc->hContact, 1); + if (GetKeyState(VK_SHIFT) >> 8 || optionWindowIsOpen) + return FALSE; + + if (curAcc->oldResults_num != 0) { + g_plugin.setWord(curAcc->hContact, "Status", ID_STATUS_NONEW); + curAcc->oldResults_num = 0; + DeleteResults(curAcc->results.next); + curAcc->results.next = nullptr; + } + mir_forkThread<Account>(Login_ThreadFunc, curAcc); + } + return FALSE; +} + +INT_PTR Notifying(WPARAM, LPARAM lParam) +{ + OpenBrowser(((CLISTEVENT*)lParam)->hContact, 0); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + MCONTACT hContact = PUGetContact(hWnd); + Account *curAcc = GetAccountByContact(hContact); + + switch (message) { + case UM_INITPOPUP: + curAcc->popUpHwnd = hWnd; + break; + + case WM_COMMAND: + if (HIWORD(wParam) == STN_CLICKED) + OpenBrowser((WPARAM)hContact, 0); + break; + + case WM_CONTEXTMENU: + PUDeletePopup(hWnd); + curAcc->popUpHwnd = nullptr; + g_clistApi.pfnRemoveEvent(hContact, 1); + } + return DefWindowProc(hWnd, message, wParam, lParam); +} + +void NotifyUser(Account *curAcc) +{ + if (optionWindowIsOpen) + return; + + db_set_s(curAcc->hContact, "CList", "MyHandle", curAcc->results.content); + switch (curAcc->results_num) { + case 0: + PUDeletePopup(curAcc->popUpHwnd); + g_clistApi.pfnRemoveEvent(curAcc->hContact, 1); + if (curAcc->oldResults_num != 0) + g_plugin.setWord(curAcc->hContact, "Status", ID_STATUS_NONEW); + break; + + case -1: + g_plugin.setWord(curAcc->hContact, "Status", ID_STATUS_AWAY); + break; + + default: + g_plugin.setWord(curAcc->hContact, "Status", ID_STATUS_OCCUPIED); + int newMails = (curAcc->oldResults_num == -1) ? (curAcc->results_num) : (curAcc->results_num - curAcc->oldResults_num); + if (opt.LogThreads&&newMails > 0) { + DBEVENTINFO dbei = {}; + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.flags = DBEF_READ; + dbei.szModule = MODULENAME; + dbei.timestamp = time(0); + + resultLink *prst = curAcc->results.next; + for (int i = 0; i < newMails; i++) { + dbei.cbBlob = (DWORD)mir_strlen(prst->content) + 1; + dbei.pBlob = (PBYTE)prst->content; + db_event_add(curAcc->hContact, &dbei); + prst = prst->next; + } + } + if (opt.notifierOnTray&&newMails > 0) { + g_clistApi.pfnRemoveEvent(curAcc->hContact, 1); + + CLISTEVENT cle = {}; + cle.hContact = curAcc->hContact; + cle.hDbEvent = 1; + cle.flags = CLEF_URGENT; + cle.hIcon = Skin_LoadProtoIcon(MODULENAME, ID_STATUS_OCCUPIED); + cle.pszService = "GmailMNotifier/Notifying"; + cle.szTooltip.a = curAcc->results.next->content; + g_clistApi.pfnAddEvent(&cle); + } + + if (opt.notifierOnPop&&newMails > 0) { + POPUPDATA ppd = { 0 }; + + ppd.lchContact = curAcc->hContact; + ppd.lchIcon = Skin_LoadProtoIcon(MODULENAME, ID_STATUS_OCCUPIED); + mir_strcpy(ppd.lpzContactName, curAcc->results.content); + resultLink *prst = curAcc->results.next; + for (int i = 0; i < 5 && i < newMails; i++) { + mir_strcat(ppd.lpzText, prst->content); + mir_strcat(ppd.lpzText, "\n"); + prst = prst->next; + } + ppd.colorBack = opt.popupBgColor; + ppd.colorText = opt.popupTxtColor; + ppd.PluginWindowProc = PopupDlgProc; + ppd.PluginData = nullptr; + ppd.iSeconds = opt.popupDuration; + PUDeletePopup(curAcc->popUpHwnd); + PUAddPopup(&ppd); + } + if (newMails > 0) + Skin_PlaySound("Gmail"); + } + curAcc->oldResults_num = curAcc->results_num; + DeleteResults(curAcc->results.next); + curAcc->results.next = nullptr; +} + +void DeleteResults(resultLink *prst) +{ + if (prst != nullptr) { + if (prst->next != nullptr) + DeleteResults(prst->next); + free(prst); + } +} diff --git a/protocols/GmailNotifier/src/options.cpp b/protocols/GmailNotifier/src/options.cpp new file mode 100644 index 0000000000..3d83fe4671 --- /dev/null +++ b/protocols/GmailNotifier/src/options.cpp @@ -0,0 +1,284 @@ +#include "stdafx.h" + +static void SaveButton(HWND hwndDlg, HWND hwndCombo, int curIndex) +{ + if (curIndex < 0 || curIndex >= g_accs.getCount()) + return; + + Account &acc = g_accs[curIndex]; + if (GetDlgItemTextA(hwndDlg, IDC_NAME, acc.name, _countof(acc.name))) { + char *tail = strstr(acc.name, "@"); + if (tail && mir_strcmp(tail + 1, "gmail.com") != 0) + mir_strcpy(acc.hosted, tail + 1); + SendMessageA(hwndCombo, CB_DELETESTRING, curIndex, 0); + SendMessageA(hwndCombo, CB_INSERTSTRING, curIndex, (LPARAM)acc.name); + SendMessageA(hwndCombo, CB_SETCURSEL, curIndex, 0); + g_plugin.setString(acc.hContact, "name", acc.name); + g_plugin.setString(acc.hContact, "Nick", acc.name); + + GetDlgItemTextA(hwndDlg, IDC_PASS, acc.pass, _countof(acc.pass)); + g_plugin.setString(acc.hContact, "Password", acc.pass); + } +} + +static INT_PTR CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int ShowControl; + char str[MAX_PATH] = { 0 }; + static int curIndex = 0; + static bool bInit = false; + HWND hwndCombo = GetDlgItem(hwndDlg, IDC_NAME); + + if (g_accs.getCount()) { + EnableWindow(hwndCombo, TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_PASS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTNSAV), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTNDEL), TRUE); + } + else { + EnableWindow(hwndCombo, FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_PASS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTNSAV), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTNDEL), FALSE); + } + + switch (msg) { + case WM_INITDIALOG: + bInit = true; + TranslateDialogDefault(hwndDlg); + optionWindowIsOpen = TRUE; + BuildList(); + + for (auto &it : g_accs) + SendMessageA(hwndCombo, CB_ADDSTRING, 0, (LONG_PTR)it->name); + SendMessage(hwndCombo, CB_SETCURSEL, curIndex, 0); + if (curIndex < g_accs.getCount()) + SetDlgItemTextA(hwndDlg, IDC_PASS, g_accs[curIndex].pass); + + SetDlgItemInt(hwndDlg, IDC_CIRCLE, opt.circleTime, FALSE); + if (opt.notifierOnTray) + CheckDlgButton(hwndDlg, IDC_OPTTRAY, BST_CHECKED); + if (opt.notifierOnPop) { + CheckDlgButton(hwndDlg, IDC_OPTPOP, BST_CHECKED); + ShowWindow(GetDlgItem(hwndDlg, IDC_DURATION), SW_SHOW); + ShowWindow(GetDlgItem(hwndDlg, IDC_BGCOLOR), SW_SHOW); + ShowWindow(GetDlgItem(hwndDlg, IDC_TEXTCOLOR), SW_SHOW); + ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_DURATION), SW_SHOW); + ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_COLOR), SW_SHOW); + ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_LESS), SW_SHOW); + ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_SEC), SW_SHOW); + } + + SetDlgItemInt(hwndDlg, IDC_DURATION, opt.popupDuration, TRUE); + SendDlgItemMessage(hwndDlg, IDC_BGCOLOR, CPM_SETCOLOUR, 0, opt.popupBgColor); + SendDlgItemMessage(hwndDlg, IDC_TEXTCOLOR, CPM_SETCOLOUR, 0, opt.popupTxtColor); + + if (opt.OpenUsePrg == 0) + CheckDlgButton(hwndDlg, IDC_SYSDEF, BST_CHECKED); + else if (opt.OpenUsePrg == 1) + CheckDlgButton(hwndDlg, IDC_USEIE, BST_CHECKED); + else if (opt.OpenUsePrg == 2) { + CheckDlgButton(hwndDlg, IDC_STARTPRG, BST_CHECKED); + ShowWindow(GetDlgItem(hwndDlg, IDC_PRG), SW_SHOW); + ShowWindow(GetDlgItem(hwndDlg, IDC_PRGBROWSE), SW_SHOW); + } + { + DBVARIANT dbv; + if (!g_plugin.getString("OpenUsePrgPath", &dbv)) { + mir_strcpy(str, dbv.pszVal); + db_free(&dbv); + } + } + SetDlgItemTextA(hwndDlg, IDC_PRG, str); + + if (opt.UseOnline) + CheckDlgButton(hwndDlg, IDC_ONLINE, BST_CHECKED); + if (opt.ShowCustomIcon) + CheckDlgButton(hwndDlg, IDC_SHOWICON, BST_CHECKED); + if (opt.AutoLogin == 0) + CheckDlgButton(hwndDlg, IDC_AUTOLOGIN, BST_CHECKED); + else if (opt.AutoLogin == 1) + CheckDlgButton(hwndDlg, IDC_AUTOLOGIN, BST_UNCHECKED); + else if (opt.AutoLogin == 2) + CheckDlgButton(hwndDlg, IDC_AUTOLOGIN, BST_INDETERMINATE); + if (opt.LogThreads) + CheckDlgButton(hwndDlg, IDC_LOGTHREADS, BST_CHECKED); + + bInit = false; + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_SYSDEF: + case IDC_USEIE: + case IDC_STARTPRG: + ShowControl = IsDlgButtonChecked(hwndDlg, IDC_STARTPRG) ? SW_SHOW : SW_HIDE; + ShowWindow(GetDlgItem(hwndDlg, IDC_PRG), ShowControl); + ShowWindow(GetDlgItem(hwndDlg, IDC_PRGBROWSE), ShowControl); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_OPTPOP: + ShowControl = IsDlgButtonChecked(hwndDlg, IDC_OPTPOP) ? SW_SHOW : SW_HIDE; + ShowWindow(GetDlgItem(hwndDlg, IDC_DURATION), ShowControl); + ShowWindow(GetDlgItem(hwndDlg, IDC_BGCOLOR), ShowControl); + ShowWindow(GetDlgItem(hwndDlg, IDC_TEXTCOLOR), ShowControl); + ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_DURATION), ShowControl); + ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_COLOR), ShowControl); + ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_LESS), ShowControl); + ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_SEC), ShowControl); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_PRGBROWSE: + wchar_t szName[_MAX_PATH]; + GetDlgItemText(hwndDlg, IDC_PRG, szName, _countof(szName)); + { + OPENFILENAME OpenFileName = {}; + OpenFileName.lStructSize = sizeof(OPENFILENAME); + OpenFileName.hwndOwner = hwndDlg; + OpenFileName.lpstrFilter = L"Executables (*.exe;*.com;*.bat)\0*.exe;*.com;*.bat\0\0"; + OpenFileName.lpstrFile = szName; + OpenFileName.nMaxFile = _countof(szName); + OpenFileName.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; + if (!GetOpenFileName(&OpenFileName)) + return 0; + SetDlgItemText(hwndDlg, IDC_PRG, szName); + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_BTNADD: + { + Account *p = new Account(); + p->hContact = db_add_contact(); + Proto_AddToContact(p->hContact, MODULENAME); + g_accs.insert(p); + + curIndex = SendMessageA(hwndCombo, CB_ADDSTRING, 0, (LPARAM)""); + SendMessage(hwndCombo, CB_SETCURSEL, curIndex, 0); + SetDlgItemTextA(hwndDlg, IDC_PASS, ""); + SetFocus(hwndCombo); + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_BTNSAV: + SaveButton(hwndDlg, hwndCombo, curIndex); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_BTNDEL: + { + SendMessage(hwndCombo, CB_DELETESTRING, curIndex, 0); + + Account &acc = g_accs[curIndex]; + DeleteResults(acc.results.next); + db_delete_contact(acc.hContact); + g_accs.remove(curIndex); + + curIndex = 0; + SendMessage(hwndCombo, CB_SETCURSEL, 0, 0); + if (g_accs.getCount()) + SetDlgItemTextA(hwndDlg, IDC_PASS, g_accs[0].pass); + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_NAME: + if (HIWORD(wParam) == CBN_SELCHANGE) { + curIndex = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0); + SetDlgItemTextA(hwndDlg, IDC_PASS, g_accs[curIndex].pass); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + + case IDC_CIRCLE: + case IDC_DURATION: + if (!bInit && (HIWORD(wParam) == EN_CHANGE)) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_ONLINE: + case IDC_SHOWICON: + case IDC_AUTOLOGIN: + case IDC_LOGTHREADS: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + + return TRUE; + + case WM_NOTIFY: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + SaveButton(hwndDlg, hwndCombo, curIndex); + opt.circleTime = GetDlgItemInt(hwndDlg, IDC_CIRCLE, nullptr, FALSE); + if (opt.circleTime > 0) { + KillTimer(nullptr, hTimer); + hTimer = SetTimer(nullptr, 0, opt.circleTime * 60000, TimerProc); + g_plugin.setDword("circleTime", opt.circleTime); + } + opt.notifierOnTray = IsDlgButtonChecked(hwndDlg, IDC_OPTTRAY); + opt.notifierOnPop = IsDlgButtonChecked(hwndDlg, IDC_OPTPOP); + g_plugin.setDword("notifierOnTray", opt.notifierOnTray); + g_plugin.setDword("notifierOnPop", opt.notifierOnPop); + + opt.popupDuration = GetDlgItemInt(hwndDlg, IDC_DURATION, nullptr, TRUE); + g_plugin.setDword("popupDuration", opt.popupDuration); + + opt.popupBgColor = SendDlgItemMessage(hwndDlg, IDC_BGCOLOR, CPM_GETCOLOUR, 0, opt.popupBgColor); + opt.popupTxtColor = SendDlgItemMessage(hwndDlg, IDC_TEXTCOLOR, CPM_GETCOLOUR, 0, opt.popupBgColor); + g_plugin.setDword("popupBgColor", opt.popupBgColor); + g_plugin.setDword("popupTxtColor", opt.popupTxtColor); + + if (IsDlgButtonChecked(hwndDlg, IDC_SYSDEF) == BST_CHECKED) + opt.OpenUsePrg = 0; + else if (IsDlgButtonChecked(hwndDlg, IDC_USEIE) == BST_CHECKED) + opt.OpenUsePrg = 1; + else if (IsDlgButtonChecked(hwndDlg, IDC_STARTPRG) == BST_CHECKED) { + opt.OpenUsePrg = 2; + } + GetDlgItemTextA(hwndDlg, IDC_PRG, str, _countof(str)); + + g_plugin.setDword("OpenUsePrg", opt.OpenUsePrg); + g_plugin.setString("OpenUsePrgPath", str); + + opt.ShowCustomIcon = IsDlgButtonChecked(hwndDlg, IDC_SHOWICON); + opt.UseOnline = IsDlgButtonChecked(hwndDlg, IDC_ONLINE); + if (IsDlgButtonChecked(hwndDlg, IDC_AUTOLOGIN) == BST_CHECKED) + opt.AutoLogin = 0; + else if (IsDlgButtonChecked(hwndDlg, IDC_AUTOLOGIN) == BST_UNCHECKED) + opt.AutoLogin = 1; + else if (IsDlgButtonChecked(hwndDlg, IDC_AUTOLOGIN) == BST_INDETERMINATE) + opt.AutoLogin = 2; + opt.LogThreads = IsDlgButtonChecked(hwndDlg, IDC_LOGTHREADS); + g_plugin.setDword("ShowCustomIcon", opt.ShowCustomIcon); + g_plugin.setDword("UseOnline", opt.UseOnline); + g_plugin.setDword("AutoLogin", opt.AutoLogin); + g_plugin.setDword("LogThreads", opt.LogThreads); + + ID_STATUS_NONEW = opt.UseOnline ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE; + for (auto &it : g_accs) + g_plugin.setWord(it->hContact, "Status", ID_STATUS_NONEW); + } + return TRUE; + + case WM_CLOSE: + optionWindowIsOpen = FALSE; + return TRUE; + } + return FALSE; +} + +int OptInit(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = {}; + odp.position = -790000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT); + odp.szTitle.a = LPGEN("GmailNotifier"); + odp.szGroup.a = LPGEN("Network"); + odp.flags = ODPF_BOLDGROUPS; + odp.pfnDlgProc = DlgProcOpts; + g_plugin.addOptions(wParam, &odp); + return 0; +} diff --git a/protocols/GmailNotifier/src/resource.h b/protocols/GmailNotifier/src/resource.h new file mode 100644 index 0000000000..7979aabf00 --- /dev/null +++ b/protocols/GmailNotifier/src/resource.h @@ -0,0 +1,47 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by C:\Users\xx\Documents\Visual Studio 2010\Projects\miranda-ng\plugins\GmailNotifier\res\options.rc +// +#define IDD_OPT 101 +#define IDI_ICONNEW 106 +#define IDI_ICONERR 109 +#define IDI_ICONEPT 111 +#define IDC_GROUPMAIN 1000 +#define IDC_CONFIG 1001 +#define IDC_CONFIRM 1002 +#define IDC_OPTTRAY 1002 +#define IDC_OPTPOP 1003 +#define IDC_USEIE 1004 +#define IDC_STATIC_DURATION 1006 +#define IDC_BGCOLOR 1007 +#define IDC_TEXTCOLOR 1008 +#define IDC_PRG 1009 +#define IDC_SYSDEF 1010 +#define IDC_STARTPRG 1011 +#define IDC_PRGBROWSE 1012 +#define IDC_STATIC_COLOR 1014 +#define IDC_STATIC_LESS 1016 +#define IDC_STATIC_SEC 1017 +#define IDC_STATIC_CUSTOM 1018 +#define IDC_BTNADD 1019 +#define IDC_PASS 1020 +#define IDC_BTNSAV 1021 +#define IDC_NAME 1022 +#define IDC_CIRCLE 1023 +#define IDC_DURATION 1024 +#define IDC_SHOWICON 1025 +#define IDC_BTNDEL 1026 +#define IDC_AUTOLOGIN 1028 +#define IDC_LOGTHREADS 1029 +#define IDC_ONLINE 1036 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 113 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1008 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/protocols/GmailNotifier/src/stdafx.cxx b/protocols/GmailNotifier/src/stdafx.cxx new file mode 100644 index 0000000000..1b563fc866 --- /dev/null +++ b/protocols/GmailNotifier/src/stdafx.cxx @@ -0,0 +1,18 @@ +/* +Copyright (C) 2012-19 Miranda NG team (https://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "stdafx.h"
\ No newline at end of file diff --git a/protocols/GmailNotifier/src/stdafx.h b/protocols/GmailNotifier/src/stdafx.h new file mode 100644 index 0000000000..da6bc1039d --- /dev/null +++ b/protocols/GmailNotifier/src/stdafx.h @@ -0,0 +1,100 @@ +#pragma once + +#include <windows.h> +#include <time.h> +#include <stdio.h> +#include "resource.h" + +#include "newpluginapi.h" +#include "m_clistint.h" +#include "m_skin.h" +#include "m_langpack.h" +#include "m_database.h" +#include "m_system.h" +#include "m_protocols.h" +#include "m_userinfo.h" +#include "m_options.h" +#include "m_protosvc.h" +#include "m_utils.h" +#include "m_ignore.h" +#include "m_clc.h" +#include "m_popup.h" +#include "m_netlib.h" + +#define WM_SHELLNOTIFY WM_USER+5 +#define IDI_TRAY WM_USER+6 +#define MODULENAME "GmailMNotifier" +#define _MAX_DOWN_BUFFER 65536 +#define LINK "https://accounts.google.com/ServiceLogin?continue=https%3A%2F%2Fmail.google.com%2Fmail&service=mail&passive=true&Email=" +#define FORMDATA1 "<body onload=document.gmail.submit();><form name=gmail action=https://www.google.com/a/" +#define FORMDATA2 "/LoginAction method=POST><input type=hidden name=continue value=https://mail.google.com/a/" +#define FORMDATA3 "><INPUT type=hidden value=mail name=service>" +// #define STR1 "javascript:document.write('<form name=gmail action=https://www.google.com/a/" +// #define STR2 "/LoginAction method=post><input type=hidden name=continue value=https://mail.google.com/hosted/" +// #define STR3 "><input type=hidden value=mail name=service><input type=hidden name=userName value=" +// #define STR4 "><input type=hidden name=password value=" +// #define STR5 ">');document.gmail.submit();" +//#define LINK2 "https://www.google.com/a/altmanoptik.com/LoginAction?continue=https%3A%2F%2Fmail.google.com%2Fhosted%2Faltmanoptik.com&service=mail&userName=test&password=123456" + +struct resultLink +{ + char content[64]; + struct resultLink *next; +}; + +struct Account : public MZeroedObject +{ + char name[256]; + char pass[256]; + char hosted[64]; + MCONTACT hContact; + int oldResults_num; + int results_num; + resultLink results; + HWND popUpHwnd; + bool IsChecking; +}; + +struct optionSettings +{ + int circleTime; + BOOL notifierOnTray; + BOOL notifierOnPop; + int popupDuration; + COLORREF popupTxtColor; + COLORREF popupBgColor; + int OpenUsePrg; + BOOL ShowCustomIcon; + BOOL UseOnline; + int AutoLogin; + BOOL LogThreads; +}; + +extern OBJLIST<Account> g_accs; +extern optionSettings opt; +extern HNETLIBUSER hNetlibUser; +extern UINT hTimer; +extern short ID_STATUS_NONEW; +extern BOOL optionWindowIsOpen; + +INT_PTR Notifying(WPARAM, LPARAM); +INT_PTR PluginMenuCommand(WPARAM, LPARAM); +void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD); +BOOL GetBrowser(char *); + +void NotifyUser(Account *); +int OptInit(WPARAM, LPARAM); +void Check_ThreadFunc(void *); +int OpenBrowser(WPARAM, LPARAM); +void DeleteResults(resultLink *); +void BuildList(void); + +Account* GetAccountByContact(MCONTACT hContact); + +struct CMPlugin : public PLUGIN<CMPlugin> +{ + CMPlugin(); + + int Load() override; + int Unload() override; +}; diff --git a/protocols/GmailNotifier/src/utility.cpp b/protocols/GmailNotifier/src/utility.cpp new file mode 100644 index 0000000000..cda56e956c --- /dev/null +++ b/protocols/GmailNotifier/src/utility.cpp @@ -0,0 +1,77 @@ +#include "stdafx.h" + +void BuildList(void) +{ + g_accs.destroy(); + + for (auto &hContact : Contacts(MODULENAME)) { + ptrA szName(g_plugin.getStringA(hContact, "name")); + if (szName != nullptr) { + Account *p = new Account; + p->hContact = hContact; + mir_strcpy(p->name, szName); + CallService(MS_IGNORE_IGNORE, hContact, IGNOREEVENT_USERONLINE); + + ptrA szPassword(g_plugin.getStringA(hContact, "Password")); + if (szPassword != nullptr) + mir_strcpy(p->pass, szPassword); + g_accs.insert(p); + } + } + + for (auto &acc : g_accs) { + char *tail = strchr(acc->name, '@'); + if (tail && mir_strcmp(tail + 1, "gmail.com") != 0) + mir_strcpy(acc->hosted, tail + 1); + acc->IsChecking = false; + } +} + +BOOL GetBrowser(char *str) +{ + HKEY hKey = nullptr; + char *strKey; + char strIE[] = "Applications\\iexplore.exe\\shell\\open\\command"; + char strDefault[] = "https\\shell\\open\\command"; + DBVARIANT dbv; + + if (opt.OpenUsePrg == 1) + strKey = strIE; + else if (opt.OpenUsePrg == 0) + strKey = strDefault; + else { + if (!g_plugin.getString("OpenUsePrgPath", &dbv)) { + mir_strcpy(str, dbv.pszVal); + db_free(&dbv); + } + else *str = 0; + return FALSE; + } + + // Open the registry + if (RegOpenKeyExA(HKEY_CLASSES_ROOT, strKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + // Data size + DWORD cbData = 0; + // Get the default value + if (RegQueryValueExA(hKey, nullptr, nullptr, nullptr, nullptr, &cbData) == ERROR_SUCCESS && cbData > 0) { + if (RegQueryValueExA(hKey, nullptr, nullptr, nullptr, (LPBYTE)str, &cbData) == ERROR_SUCCESS) { + if ((strKey = strstr(str, "%1")) != nullptr) + *(strKey--) = '\0'; + if ((strKey = strstr(str, "-")) != nullptr) + *(strKey--) = '\0'; + RegCloseKey(hKey); + return TRUE; + } + } + } + return FALSE; +} + +Account* GetAccountByContact(MCONTACT hContact) +{ + for (auto &it : g_accs) + if (it->hContact == hContact) + return it; + + return nullptr; +} diff --git a/protocols/GmailNotifier/src/version.h b/protocols/GmailNotifier/src/version.h new file mode 100644 index 0000000000..8eeed10480 --- /dev/null +++ b/protocols/GmailNotifier/src/version.h @@ -0,0 +1,13 @@ +#define __MAJOR_VERSION 1 +#define __MINOR_VERSION 0 +#define __RELEASE_NUM 1 +#define __BUILD_NUM 2 + +#include <stdver.h> + +#define __PLUGIN_NAME "Gmail Multiple Notifier" +#define __FILENAME "GmailNotifier.dll" +#define __DESCRIPTION "Check your Gmail inboxes locally." +#define __AUTHOR "Mixwind" +#define __AUTHORWEB "https://miranda-ng.org/p/GmailNotifier/" +#define __COPYRIGHT "© 2005 Sun Zhuo" |