From 7478b207dea289dcddb5e1bce5b5191ac92605b1 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sun, 20 Apr 2014 18:52:22 +0000 Subject: Dropbox: service and events reworked git-svn-id: http://svn.miranda-ng.org/main/trunk@9005 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dropbox/src/dropbox.cpp | 7 +- plugins/Dropbox/src/dropbox.h | 10 +- plugins/Dropbox/src/dropbox_events.cpp | 72 +------------- plugins/Dropbox/src/dropbox_menus.cpp | 27 ++++- plugins/Dropbox/src/dropbox_services.cpp | 33 +------ plugins/Dropbox/src/dropbox_transfers.cpp | 157 ++++++++++++++++++++++-------- plugins/Dropbox/src/file_transfer.h | 30 +++++- 7 files changed, 180 insertions(+), 156 deletions(-) (limited to 'plugins/Dropbox/src') diff --git a/plugins/Dropbox/src/dropbox.cpp b/plugins/Dropbox/src/dropbox.cpp index 9081daae85..f998a6d935 100644 --- a/plugins/Dropbox/src/dropbox.cpp +++ b/plugins/Dropbox/src/dropbox.cpp @@ -11,9 +11,7 @@ CDropbox::CDropbox() HookEventObj(ME_SYSTEM_PRESHUTDOWN, OnPreShutdown, this); HookEventObj(ME_SYSTEM_MODULESLOADED, OnModulesLoaded, this); - hFileSendFailedHook = CreateHookableEvent(ME_DROPBOX_SEND_FAILED); - hFileSendSuccessedHook = CreateHookableEvent(ME_DROPBOX_SEND_SUCCEEDED); - HookEventObj(ME_DROPBOX_SEND_SUCCEEDED, OnSendSuccessed, this); + hFileSentEventHook = CreateHookableEvent(ME_DROPBOX_SENT); CreateServiceFunctionObj(MS_DROPBOX_SEND_FILE, SendFileToDropbox, this); @@ -36,8 +34,7 @@ CDropbox::CDropbox() CDropbox::~CDropbox() { - DestroyHookableEvent(hFileSendFailedHook); - DestroyHookableEvent(hFileSendSuccessedHook); + DestroyHookableEvent(hFileSentEventHook); } MCONTACT CDropbox::GetDefaultContact() diff --git a/plugins/Dropbox/src/dropbox.h b/plugins/Dropbox/src/dropbox.h index c044a4f1b9..543b492d7c 100644 --- a/plugins/Dropbox/src/dropbox.h +++ b/plugins/Dropbox/src/dropbox.h @@ -44,8 +44,7 @@ private: ULONG hFileProcess; ULONG hMessageProcess; - HANDLE hFileSendFailedHook; - HANDLE hFileSendSuccessedHook; + HANDLE hFileSentEventHook; MCONTACT hDefaultContact; MCONTACT hTransferContact; @@ -67,8 +66,6 @@ private: static int OnFileDialogCancelled(void *obj, WPARAM wParam, LPARAM lParam); static int OnFileDialogSuccessed(void *obj, WPARAM wParam, LPARAM lParam); - static int OnSendSuccessed(void *obj, WPARAM wParam, LPARAM lParam); - // services static HANDLE CreateProtoServiceFunctionObj(const char *szService, MIRANDASERVICEOBJ serviceProc, void *obj); @@ -78,7 +75,6 @@ private: static INT_PTR ProtoReceiveMessage(void *obj, WPARAM wParam, LPARAM lParam); static INT_PTR SendFileToDropbox(void *obj, WPARAM wParam, LPARAM lParam); - static INT_PTR SendFilesToDropbox(void *obj, WPARAM wParam, LPARAM lParam); // commands static void CommandHelp(void *arg); @@ -108,6 +104,8 @@ private: int CreateDownloadUrl(const char *path, wchar_t *url); static UINT SendFilesAsync(void *owner, void *arg); + static UINT SendFilesAndEventAsync(void *owner, void *arg); + static UINT SendFilesAndReportAsync(void *owner, void *arg); // contacts MCONTACT GetDefaultContact(); @@ -119,6 +117,8 @@ private: void InitializeMenus(); static void Menu_DisableItem(HGENMENU hMenuItem, BOOL bDisable); + static INT_PTR SendFilesToDropboxCommand(void *obj, WPARAM wParam, LPARAM lParam); + // dialogs static INT_PTR CALLBACK MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); diff --git a/plugins/Dropbox/src/dropbox_events.cpp b/plugins/Dropbox/src/dropbox_events.cpp index efd8687762..15761a4874 100644 --- a/plugins/Dropbox/src/dropbox_events.cpp +++ b/plugins/Dropbox/src/dropbox_events.cpp @@ -177,82 +177,12 @@ int CDropbox::OnFileDialogSuccessed(void *obj, WPARAM hContact, LPARAM lParam) return 0; } -int CDropbox::OnSendSuccessed(void *obj, WPARAM hContact, LPARAM lParam) -{ - wchar_t *data = (wchar_t*)lParam; - CDropbox *instance = (CDropbox*)obj; - - if (instance->hTransferContact) - instance->hTransferContact = 0; - - if (db_get_b(NULL, MODULE, "UrlAutoSend", 1)) - { - char *message = mir_utf8encodeW(data); - if (hContact != instance->GetDefaultContact()) - { - if (CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)message) != ACKRESULT_FAILED) - { - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.flags = DBEF_UTF | DBEF_SENT/* | DBEF_READ*/; - dbei.szModule = MODULE; - dbei.timestamp = time(NULL); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = wcslen(data); - dbei.pBlob = (PBYTE)message; - db_event_add(hContact, &dbei); - } - else - CallServiceSync(MS_MSG_SENDMESSAGEW, (WPARAM)hContact, (LPARAM)data); - } - else - { - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.flags = DBEF_UTF; - dbei.szModule = MODULE; - dbei.timestamp = time(NULL); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = wcslen(data); - dbei.pBlob = (PBYTE)message; - db_event_add(hContact, &dbei); - } - } - - CMString urls = data; urls += L"\r\n"; - - if (db_get_b(NULL, MODULE, "UrlPasteToMessageInputArea", 0)) - CallServiceSync(MS_MSG_SENDMESSAGEW, (WPARAM)hContact, (LPARAM)urls.GetBuffer()); - - if (db_get_b(NULL, MODULE, "UrlCopyToClipboard", 0)) - { - if (OpenClipboard(NULL)) - { - EmptyClipboard(); - size_t size = sizeof(wchar_t) * (urls.GetLength() + 1); - HGLOBAL hClipboardData = GlobalAlloc(NULL, size); - if (hClipboardData) - { - wchar_t* pchData = (wchar_t*)GlobalLock(hClipboardData); - if (pchData) - { - memcpy(pchData, (wchar_t*)urls.GetString(), size); - GlobalUnlock(hClipboardData); - SetClipboardData(CF_UNICODETEXT, hClipboardData); - } - } - CloseClipboard(); - } - } - - return 0; -} - int CDropbox::OnProtoAck(void *obj, WPARAM wParam, LPARAM lParam) { ACKDATA *ack = (ACKDATA*) lParam; - if ( !strcmp(ack->szModule, MODULE)) { + if (!strcmp(ack->szModule, MODULE)) return 0; // don't rebroadcast our own acks - } if (ack->type == ACKTYPE_STATUS/* && ((int)ack->lParam != (int)ack->hProcess)*/) { diff --git a/plugins/Dropbox/src/dropbox_menus.cpp b/plugins/Dropbox/src/dropbox_menus.cpp index 615aec238e..d01c1e1f88 100644 --- a/plugins/Dropbox/src/dropbox_menus.cpp +++ b/plugins/Dropbox/src/dropbox_menus.cpp @@ -1,17 +1,40 @@ #include "common.h" +INT_PTR CDropbox::SendFilesToDropboxCommand(void *obj, WPARAM hContact, LPARAM) +{ + CDropbox *instance = (CDropbox*)obj; + + if (!instance->HasAccessToken()) + return 1; + + instance->hTransferContact = hContact; + + HWND hwnd = (HWND)CallService(MS_FILE_SENDFILE, instance->GetDefaultContact(), 0); + + instance->dcftp[hwnd] = hContact; + + BBButton bbd = { sizeof(bbd) }; + bbd.pszModuleName = MODULE; + bbd.dwButtonID = BBB_ID_FILE_SEND; + bbd.bbbFlags = BBSF_DISABLED; + + CallService(MS_BB_SETBUTTONSTATE, hContact, (LPARAM)&bbd); + + return 0; +} + void CDropbox::InitializeMenus() { CLISTMENUITEM mi = { 0 }; mi.cbSize = sizeof(CLISTMENUITEM); - mi.flags = CMIF_TCHAR; + mi.flags = CMIF_TCHAR | CMIF_NOTOFFLINE; mi.pszService = MODULE"/SendFilesToDropbox"; mi.ptszName = LPGENT("Send files to Dropbox"); mi.position = -2000020000 + CMI_SEND_FILES; mi.icolibItem = LoadSkinnedIconHandle(SKINICON_EVENT_FILE); contactMenuItems[CMI_SEND_FILES] = Menu_AddContactMenuItem(&mi); - CreateServiceFunctionObj(mi.pszService, SendFilesToDropbox, this); + CreateServiceFunctionObj(mi.pszService, SendFilesToDropboxCommand, this); } int CDropbox::OnPrebuildContactMenu(void *obj, WPARAM hContact, LPARAM lParam) diff --git a/plugins/Dropbox/src/dropbox_services.cpp b/plugins/Dropbox/src/dropbox_services.cpp index db2e2c8be2..9197a82eed 100644 --- a/plugins/Dropbox/src/dropbox_services.cpp +++ b/plugins/Dropbox/src/dropbox_services.cpp @@ -33,7 +33,6 @@ INT_PTR CDropbox::ProtoSendFile(void *obj, WPARAM, LPARAM lParam) CCSDATA *pccsd = (CCSDATA*)lParam; FileTransferParam *ftp = new FileTransferParam(); - ftp->withVisualisation = true; ftp->pfts.flags |= PFTS_SENDING; ftp->pfts.hContact = pccsd->hContact; ftp->hContact = (instance->hTransferContact) ? instance->hTransferContact : pccsd->hContact; @@ -99,7 +98,7 @@ INT_PTR CDropbox::ProtoSendFile(void *obj, WPARAM, LPARAM lParam) ULONG fileId = InterlockedIncrement(&instance->hFileProcess); ftp->hProcess = (HANDLE)fileId; - mir_forkthreadowner(CDropbox::SendFilesAsync, obj, ftp, 0); + mir_forkthreadowner(CDropbox::SendFilesAndReportAsync, obj, ftp, 0); return fileId; } @@ -199,13 +198,12 @@ INT_PTR CDropbox::SendFileToDropbox(void *obj, WPARAM hContact, LPARAM lParam) if (!instance->HasAccessToken()) return 0; - wchar_t *filePath = (wchar_t*)lParam; - if (hContact == NULL) hContact = instance->GetDefaultContact(); + wchar_t *filePath = (wchar_t*)lParam; + FileTransferParam *ftp = new FileTransferParam(); - ftp->withVisualisation = false; ftp->pfts.flags |= PFTS_SENDING; ftp->pfts.hContact = hContact; ftp->pfts.totalFiles = 1; @@ -224,30 +222,7 @@ INT_PTR CDropbox::SendFileToDropbox(void *obj, WPARAM hContact, LPARAM lParam) ULONG fileId = InterlockedIncrement(&instance->hFileProcess); ftp->hProcess = (HANDLE)fileId; - mir_forkthreadowner(CDropbox::SendFilesAsync, obj, ftp, 0); + mir_forkthreadowner(CDropbox::SendFilesAndEventAsync, obj, ftp, 0); return fileId; -} - -INT_PTR CDropbox::SendFilesToDropbox(void *obj, WPARAM hContact, LPARAM) -{ - CDropbox *instance = (CDropbox*)obj; - - if (!instance->HasAccessToken()) - return 1; - - instance->hTransferContact = hContact; - - HWND hwnd = (HWND)CallService(MS_FILE_SENDFILE, instance->GetDefaultContact(), 0); - - instance->dcftp[hwnd] = hContact; - - BBButton bbd = { sizeof(bbd) }; - bbd.pszModuleName = MODULE; - bbd.dwButtonID = BBB_ID_FILE_SEND; - bbd.bbbFlags = BBSF_DISABLED; - - CallService(MS_BB_SETBUTTONSTATE, hContact, (LPARAM)&bbd); - - return 0; } \ No newline at end of file diff --git a/plugins/Dropbox/src/dropbox_transfers.cpp b/plugins/Dropbox/src/dropbox_transfers.cpp index 8ba7773f4b..e645f059fa 100644 --- a/plugins/Dropbox/src/dropbox_transfers.cpp +++ b/plugins/Dropbox/src/dropbox_transfers.cpp @@ -128,6 +128,10 @@ int CDropbox::CreateFolder(const char *folderName) delete request; + // forder exists on server + if (response->resultCode == HTTP_STATUS_FORBIDDEN) + return 0; + return HandleHttpResponseError(hNetlibUser, response); } @@ -167,10 +171,7 @@ UINT CDropbox::SendFilesAsync(void *owner, void *arg) CDropbox *instance = (CDropbox*)owner; FileTransferParam *ftp = (FileTransferParam*)arg; - CMString urls; - - if (ftp->withVisualisation) - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ftp->hProcess, 0); + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ftp->hProcess, 0); if (ftp->pwszFolders) { @@ -184,11 +185,7 @@ UINT CDropbox::SendFilesAsync(void *owner, void *arg) { wchar_t url[MAX_PATH]; if (!instance->CreateDownloadUrl(utf8_folderName, url)) - { - if (!urls.IsEmpty()) - urls += "\r\n"; - urls += url; - } + ftp->AddUrl(url); else { error = true; @@ -221,16 +218,14 @@ UINT CDropbox::SendFilesAsync(void *owner, void *arg) size_t fileSize = ftell(file); fseek(file, 0, SEEK_SET); - if (ftp->withVisualisation) - { - ftp->pfts.currentFileNumber = i; - ftp->pfts.currentFileSize = fileSize; - ftp->pfts.currentFileProgress = 0; - ftp->pfts.wszCurrentFile = wcsrchr(ftp->pfts.pwszFiles[i], '\\') + 1; + ftp->pfts.currentFileNumber = i; + ftp->pfts.currentFileSize = fileSize; + ftp->pfts.currentFileProgress = 0; + ftp->pfts.wszCurrentFile = wcsrchr(ftp->pfts.pwszFiles[i], '\\') + 1; - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); - } + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); + // int offset = 0; char *uploadId = new char[32]; @@ -268,13 +263,10 @@ UINT CDropbox::SendFilesAsync(void *owner, void *arg) } } - if (ftp->withVisualisation) - { - ftp->pfts.currentFileProgress += count; - ftp->pfts.totalProgress += count; + ftp->pfts.currentFileProgress += count; + ftp->pfts.totalProgress += count; - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); - } + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); } fclose(file); @@ -294,11 +286,7 @@ UINT CDropbox::SendFilesAsync(void *owner, void *arg) { wchar_t url[MAX_PATH]; if (!instance->CreateDownloadUrl(utf8_fileName, url)) - { - if (!urls.IsEmpty()) - urls += "\r\n"; - urls += url; - } + ftp->AddUrl(url); else { error = true; @@ -306,13 +294,10 @@ UINT CDropbox::SendFilesAsync(void *owner, void *arg) } } - if (ftp->withVisualisation) - { - ftp->pfts.currentFileProgress = ftp->pfts.currentFileSize; + ftp->pfts.currentFileProgress = ftp->pfts.currentFileSize; - if (i < ftp->pfts.totalFiles - 1) - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ftp->hProcess, 0); - } + if (i < ftp->pfts.totalFiles - 1) + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ftp->hProcess, 0); } } } @@ -324,22 +309,108 @@ UINT CDropbox::SendFilesAsync(void *owner, void *arg) } } - if (!error) + if (error) { - if (ftp->withVisualisation) - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftp->hProcess, 0); + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ftp->hProcess, 0); - NotifyEventHooks(instance->hFileSendSuccessedHook, ftp->hContact, (LPARAM)urls.GetBuffer()); + return 1; } - else + + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftp->hProcess, 0); + + return 0; +} + +UINT CDropbox::SendFilesAndReportAsync(void *owner, void *arg) +{ + CDropbox *instance = (CDropbox*)owner; + FileTransferParam *ftp = (FileTransferParam*)arg; + + int res = SendFilesAsync(owner, arg); + if (!res) { - if (ftp->withVisualisation) - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ftp->hProcess, 0); + CMString urls; + for (int i = 0; ftp->pwszUrls[i]; i++) + urls.AppendFormat(L"%s\r\n", ftp->pwszUrls[i]); + wchar_t *data = urls.GetBuffer(); + + if (db_get_b(NULL, MODULE, "UrlAutoSend", 1)) + { + char *message = mir_utf8encodeW(data); + if (ftp->hContact != instance->GetDefaultContact()) + { + if (CallContactService(ftp->hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)message) != ACKRESULT_FAILED) + { + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.flags = DBEF_UTF | DBEF_SENT/* | DBEF_READ*/; + dbei.szModule = MODULE; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = wcslen(data); + dbei.pBlob = (PBYTE)message; + db_event_add(ftp->hContact, &dbei); + } + else + CallServiceSync(MS_MSG_SENDMESSAGEW, (WPARAM)ftp->hContact, (LPARAM)data); + } + else + { + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.flags = DBEF_UTF; + dbei.szModule = MODULE; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = wcslen(data); + dbei.pBlob = (PBYTE)message; + db_event_add(ftp->hContact, &dbei); + } + } - NotifyEventHooks(instance->hFileSendFailedHook, ftp->hContact, 0); + if (db_get_b(NULL, MODULE, "UrlPasteToMessageInputArea", 0)) + CallServiceSync(MS_MSG_SENDMESSAGEW, (WPARAM)ftp->hContact, (LPARAM)data); + + if (db_get_b(NULL, MODULE, "UrlCopyToClipboard", 0)) + { + if (OpenClipboard(NULL)) + { + EmptyClipboard(); + size_t size = sizeof(wchar_t) * (urls.GetLength() + 1); + HGLOBAL hClipboardData = GlobalAlloc(NULL, size); + if (hClipboardData) + { + wchar_t *pchData = (wchar_t*)GlobalLock(hClipboardData); + if (pchData) + { + memcpy(pchData, (wchar_t*)data, size); + GlobalUnlock(hClipboardData); + SetClipboardData(CF_UNICODETEXT, hClipboardData); + } + } + CloseClipboard(); + } + } } delete ftp; - return 0; + return res; +} + +UINT CDropbox::SendFilesAndEventAsync(void *owner, void *arg) +{ + CDropbox *instance = (CDropbox*)owner; + FileTransferParam *ftp = (FileTransferParam*)arg; + + int res = SendFilesAsync(owner, arg); + + TRANSFERINFO ti = { 0 }; + ti.hProcess = ftp->hProcess; + ti.status = res; + ti.data = ftp->pwszUrls; + + NotifyEventHooks(instance->hFileSentEventHook, ftp->hContact, (LPARAM)&ti); + + delete ftp; + + return res; } \ No newline at end of file diff --git a/plugins/Dropbox/src/file_transfer.h b/plugins/Dropbox/src/file_transfer.h index 35d18bbf08..7558b83eba 100644 --- a/plugins/Dropbox/src/file_transfer.h +++ b/plugins/Dropbox/src/file_transfer.h @@ -13,7 +13,7 @@ struct FileTransferParam wchar_t **pwszFolders; int relativePathStart; - bool withVisualisation; + wchar_t **pwszUrls; FileTransferParam() { @@ -32,6 +32,8 @@ struct FileTransferParam pfts.pszFiles = NULL; pfts.tszWorkingDir = NULL; pfts.wszCurrentFile = NULL; + + pwszUrls = NULL; } ~FileTransferParam() @@ -56,6 +58,32 @@ struct FileTransferParam } mir_free(pwszFolders); } + + if (pwszUrls) + { + for (int i = 0; pwszUrls[i]; i++) + { + if (pwszUrls[i]) mir_free(pwszUrls[i]); + } + mir_free(pwszUrls); + } + } + + void AddUrl(const wchar_t *url) + { + int count = 0; + if (pwszUrls == NULL) + pwszUrls = (wchar_t**)mir_alloc(sizeof(wchar_t*) * 2); + else + { + for (; pwszUrls[count]; count++); + pwszUrls = (wchar_t**)mir_realloc(pwszUrls, sizeof(wchar_t*) * (count + 2)); + } + int length = wcslen(url); + pwszUrls[count] = (wchar_t*)mir_alloc(sizeof(wchar_t) * (length + 1)); + wcscpy(pwszUrls[count], url); + pwszUrls[count][length] = '\0'; + pwszUrls[count + 1] = NULL; } }; -- cgit v1.2.3