From 3bdbd608284853f05acdf137013de71efd915499 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sun, 9 Mar 2014 20:23:19 +0000 Subject: Dropbox: - added MS_DROPBOX_SEND_FILE service - added new behaviors for download links - attempt to fix tabsrmm button behavior git-svn-id: http://svn.miranda-ng.org/main/trunk@8527 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dropbox/Dropbox_12.vcxproj | 1 + plugins/Dropbox/Dropbox_12.vcxproj.filters | 3 + plugins/Dropbox/res/resource.rc | 10 +- plugins/Dropbox/src/common.h | 2 +- plugins/Dropbox/src/dropbox.cpp | 4 +- plugins/Dropbox/src/dropbox.h | 19 +- plugins/Dropbox/src/dropbox_dialogs.cpp | 14 +- plugins/Dropbox/src/dropbox_events.cpp | 32 ++- plugins/Dropbox/src/dropbox_services.cpp | 73 +++++ plugins/Dropbox/src/dropbox_transfers.cpp | 443 +++++++++++++++++++---------- plugins/Dropbox/src/dropbox_utils.cpp | 20 +- plugins/Dropbox/src/m_dropbox.h | 11 + plugins/Dropbox/src/resource.h | 7 +- 13 files changed, 456 insertions(+), 183 deletions(-) create mode 100644 plugins/Dropbox/src/m_dropbox.h (limited to 'plugins') diff --git a/plugins/Dropbox/Dropbox_12.vcxproj b/plugins/Dropbox/Dropbox_12.vcxproj index cc7d7a4020..aca802d645 100644 --- a/plugins/Dropbox/Dropbox_12.vcxproj +++ b/plugins/Dropbox/Dropbox_12.vcxproj @@ -190,6 +190,7 @@ + diff --git a/plugins/Dropbox/Dropbox_12.vcxproj.filters b/plugins/Dropbox/Dropbox_12.vcxproj.filters index 8384591e36..f9b68c3089 100644 --- a/plugins/Dropbox/Dropbox_12.vcxproj.filters +++ b/plugins/Dropbox/Dropbox_12.vcxproj.filters @@ -51,6 +51,9 @@ Header Files + + Header Files + diff --git a/plugins/Dropbox/res/resource.rc b/plugins/Dropbox/res/resource.rc index aeb2ab414b..7937bcaf18 100644 --- a/plugins/Dropbox/res/resource.rc +++ b/plugins/Dropbox/res/resource.rc @@ -39,11 +39,17 @@ BEGIN LTEXT "3.",IDC_STATIC,21,71,8,8 LTEXT "Initiate authorization",IDC_STATIC,29,71,109,16 PUSHBUTTON "Authorize",IDC_AUTHORIZE,144,68,169,14,BS_CENTER - GROUPBOX "Other",IDC_STATIC,5,111,313,33 - CONTROL "Use shortened share links",IDC_USE_SHORT_LINKS,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,125,298,10 + GROUPBOX "Download link",IDC_STATIC,5,111,313,70 + CONTROL "Use shortened download links",IDC_URL_USE_SHORT,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,125,298,10 LTEXT "4.",IDC_STATIC,22,89,8,8 LTEXT "Check status of authorization",IDC_STATIC,30,89,109,17 CTEXT "",IDC_AUTH_STATUS,145,89,169,8 + CONTROL "Autosend download link to contact",IDC_URL_AUTOSEND, + "Button",BS_AUTORADIOBUTTON,15,138,298,10 + CONTROL "Paste download link to message log",IDC_URL_COPYTOML, + "Button",BS_AUTORADIOBUTTON,15,151,298,10 + CONTROL "Copy download link to clibboard",IDC_URL_COPYTOCB, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,164,298,10 END diff --git a/plugins/Dropbox/src/common.h b/plugins/Dropbox/src/common.h index 265ce1765c..7caccc5420 100644 --- a/plugins/Dropbox/src/common.h +++ b/plugins/Dropbox/src/common.h @@ -29,13 +29,13 @@ #include "version.h" #include "resource.h" - #define MODULE "Dropbox" extern HINSTANCE g_hInstance; class CDropbox; +#include "m_dropbox.h" #include "dropbox.h" #endif //_COMMON_H_ \ No newline at end of file diff --git a/plugins/Dropbox/src/dropbox.cpp b/plugins/Dropbox/src/dropbox.cpp index f364597139..89e3a427fd 100644 --- a/plugins/Dropbox/src/dropbox.cpp +++ b/plugins/Dropbox/src/dropbox.cpp @@ -13,6 +13,8 @@ CDropbox::CDropbox() HookEventObj(ME_OPT_INITIALISE, OnOptionsInitialized, this); HookEventObj(ME_CLIST_PREBUILDCONTACTMENU, OnPrebuildContactMenu, this); + CreateServiceFunctionObj(MS_DROPBOX_SEND_FILE, SendFileToDropbox, this); + CreateProtoServiceFunction(MODULE, PS_GETCAPS, ProtoGetCaps); CreateProtoServiceFunctionObj(PSS_FILE, ProtoSendFile, this); CreateProtoServiceFunctionObj(PSS_MESSAGE, ProtoSendMessage, this); @@ -299,7 +301,7 @@ UINT CDropbox::RequestAcceessTokenAsync(void *owner, void* param) if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("unknown error")); else - HandleFileTransferError(response, hContact); + HandleFileTransferError(instance->hNetlibUser, response); } SetDlgItemTextA(hwndDlg, IDC_REQUEST_CODE, ""); diff --git a/plugins/Dropbox/src/dropbox.h b/plugins/Dropbox/src/dropbox.h index 783297ad44..2e63719160 100644 --- a/plugins/Dropbox/src/dropbox.h +++ b/plugins/Dropbox/src/dropbox.h @@ -15,7 +15,7 @@ #define DROPBOX_API_KEY "fa8du7gkf2q8xzg" #include "..\..\..\Dropbox\secret_key.h" -#define DROPBOX_FILE_CHUNK_SIZE 1024 * 1024 //1 MB +#define DROPBOX_FILE_CHUNK_SIZE 4 * 1024 * 1024 //4 MB #define BBB_ID_FILE_SEND 10001 @@ -57,7 +57,7 @@ private: static int OnPreShutdown(void *obj, WPARAM wParam, LPARAM lParam); static int OnContactDeleted(void *obj, WPARAM wParam, LPARAM lParam); static int OnOptionsInitialized(void *obj, WPARAM wParam, LPARAM lParam); - static int OnPrebuildContactMenu(void *obj, WPARAM wParam, LPARAM lParam); + static int OnPrebuildContactMenu(void *obj, WPARAM wParam, LPARAM lParam); static int OnSrmmWindowOpened(void *obj, WPARAM wParam, LPARAM lParam); static int OnTabSrmmButtonPressed(void *obj, WPARAM wParam, LPARAM lParam); static int OnFileDoalogCancelled(void *obj, WPARAM wParam, LPARAM lParam); @@ -69,6 +69,8 @@ private: static INT_PTR ProtoSendMessage(void *obj, WPARAM wParam, LPARAM lParam); 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 @@ -89,13 +91,16 @@ private: void RequestAccountInfo(); // transrers - static int HandleFileTransferError(NETLIBHTTPREQUEST *response, MCONTACT hContact); + static int HandleFileTransferError(HANDLE hNetlibUser, NETLIBHTTPREQUEST *response); + + int SendFile(const char *fileName, const char *data, int length); + int SendFileChunkedFirst(const char *data, int length, char *uploadId, int &offset); + int SendFileChunkedNext(const char *data, int length, const char *uploadId, int &offset); + int SendFileChunkedLast(const char *fileName, const char *uploadId); - int SendFileChunkedFirst(const char *data, int length, char *uploadId, int &offset, MCONTACT hContact); - int SendFileChunkedNext(const char *data, int length, const char *uploadId, int &offset, MCONTACT hContact); - int SendFileChunkedLast(const char *fileName, const char *uploadId, MCONTACT hContact); + int CreateFolder(const char *folderName); - int CreateFolder(const char *folderName, MCONTACT hContact); + int CreateDownloadUrl(const char *path, char *url); static void _cdecl SendFileAsync(void *arg); diff --git a/plugins/Dropbox/src/dropbox_dialogs.cpp b/plugins/Dropbox/src/dropbox_dialogs.cpp index 07bd42c5dd..1f8e30aeca 100644 --- a/plugins/Dropbox/src/dropbox_dialogs.cpp +++ b/plugins/Dropbox/src/dropbox_dialogs.cpp @@ -13,7 +13,6 @@ INT_PTR CALLBACK CDropbox::MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam instance = (CDropbox*)lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - CheckDlgButton(hwndDlg, IDC_USE_SHORT_LINKS, db_get_b(NULL, MODULE, "UseSortLinks", 1)); EnableWindow(GetDlgItem(hwndDlg, IDC_AUTHORIZE), FALSE); LOGFONT lf; @@ -26,6 +25,11 @@ INT_PTR CALLBACK CDropbox::MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("you are already authorized")); else SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("you are not authorized yet")); + + CheckDlgButton(hwndDlg, IDC_USE_SHORT_LINKS, db_get_b(NULL, MODULE, "UseSortLinks", 1)); + CheckDlgButton(hwndDlg, IDC_URL_AUTOSEND, db_get_b(NULL, MODULE, "UrlAutoSend", 1)); + CheckDlgButton(hwndDlg, IDC_URL_COPYTOML, db_get_b(NULL, MODULE, "UrlPasteToMessageLog", 0)); + CheckDlgButton(hwndDlg, IDC_URL_COPYTOCB, db_get_b(NULL, MODULE, "UrlCopyToClipboard", 0)); } return TRUE; @@ -52,6 +56,9 @@ INT_PTR CALLBACK CDropbox::MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam break; case IDC_USE_SHORT_LINKS: + case IDC_URL_AUTOSEND: + case IDC_URL_COPYTOML: + case IDC_URL_COPYTOCB: SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; @@ -60,7 +67,12 @@ INT_PTR CALLBACK CDropbox::MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam case WM_NOTIFY: if (reinterpret_cast(lParam)->code == PSN_APPLY) + { db_set_b(NULL, MODULE, "UseSortLinks", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_USE_SHORT_LINKS)); + db_set_b(NULL, MODULE, "UrlAutoSend", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_URL_AUTOSEND)); + db_set_b(NULL, MODULE, "UrlPasteToMessageLog", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_URL_COPYTOML)); + db_set_b(NULL, MODULE, "UrlCopyToClipboard", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_URL_COPYTOCB)); + } break; } return FALSE; diff --git a/plugins/Dropbox/src/dropbox_events.cpp b/plugins/Dropbox/src/dropbox_events.cpp index 6562457131..14d982f928 100644 --- a/plugins/Dropbox/src/dropbox_events.cpp +++ b/plugins/Dropbox/src/dropbox_events.cpp @@ -6,6 +6,7 @@ int CDropbox::OnModulesLoaded(void *obj, WPARAM wParam, LPARAM lParam) HookEventObj(ME_FILEDLG_CANCELED, OnFileDoalogCancelled, obj); HookEventObj(ME_FILEDLG_SUCCEEDED, OnFileDoalogSuccessed, obj); + HookEventObj(ME_MSG_WINDOWEVENT, OnSrmmWindowOpened, obj); NETLIBUSER nlu = { sizeof(nlu) }; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; @@ -29,7 +30,6 @@ int CDropbox::OnModulesLoaded(void *obj, WPARAM wParam, LPARAM lParam) bbd.dwDefPos = 100 + bbd.dwButtonID; CallService(MS_BB_ADDBUTTON, 0, (LPARAM)&bbd); - HookEventObj(ME_MSG_WINDOWEVENT, OnSrmmWindowOpened, obj); HookEventObj(ME_MSG_BUTTONPRESSED, OnTabSrmmButtonPressed, obj); } @@ -91,12 +91,13 @@ int CDropbox::OnSrmmWindowOpened(void *obj, WPARAM wParam, LPARAM lParam) BBButton bbd = { sizeof(bbd) }; bbd.pszModuleName = MODULE; - if (ev->hContact == instance->GetDefaultContact() || !instance->HasAccessToken() || status == ID_STATUS_OFFLINE) + bbd.dwButtonID = BBB_ID_FILE_SEND; + bbd.bbbFlags = BBSF_RELEASED; + if (ev->hContact == instance->GetDefaultContact() || !instance->HasAccessToken()) bbd.bbbFlags = BBSF_HIDDEN | BBSF_DISABLED; - else if (instance->hTransferContact) + else if (/*instance->hTransferContact*/ status == ID_STATUS_OFFLINE) bbd.bbbFlags = BBSF_DISABLED; - bbd.dwButtonID = BBB_ID_FILE_SEND; CallService(MS_BB_SETBUTTONSTATE, ev->hContact, (LPARAM)&bbd); } @@ -115,6 +116,13 @@ int CDropbox::OnTabSrmmButtonPressed(void *obj, WPARAM wParam, LPARAM lParam) HWND hwnd = (HWND)CallService(MS_FILE_SENDFILE, instance->GetDefaultContact(), 0); instance->dcftp[hwnd] = cbc->hContact; + + BBButton bbd = { sizeof(bbd) }; + bbd.pszModuleName = MODULE; + bbd.dwButtonID = BBB_ID_FILE_SEND; + bbd.bbbFlags = BBSF_DISABLED; + + CallService(MS_BB_SETBUTTONSTATE, cbc->hContact, (LPARAM)&bbd); } return 0; @@ -129,6 +137,13 @@ int CDropbox::OnFileDoalogCancelled(void *obj, WPARAM hContact, LPARAM lParam) { instance->dcftp.erase((HWND)lParam); instance->hTransferContact = 0; + + BBButton bbd = { sizeof(bbd) }; + bbd.pszModuleName = MODULE; + bbd.dwButtonID = BBB_ID_FILE_SEND; + bbd.bbbFlags = BBSF_RELEASED; + + CallService(MS_BB_SETBUTTONSTATE, hContact, (LPARAM)&bbd); } return 0; @@ -140,7 +155,16 @@ int CDropbox::OnFileDoalogSuccessed(void *obj, WPARAM hContact, LPARAM lParam) HWND hwnd = (HWND)lParam; if (instance->hTransferContact == instance->dcftp[hwnd]) + { instance->dcftp.erase((HWND)lParam); + BBButton bbd = { sizeof(bbd) }; + bbd.pszModuleName = MODULE; + bbd.dwButtonID = BBB_ID_FILE_SEND; + bbd.bbbFlags = BBSF_RELEASED; + + CallService(MS_BB_SETBUTTONSTATE, hContact, (LPARAM)&bbd); + } + return 0; } \ No newline at end of file diff --git a/plugins/Dropbox/src/dropbox_services.cpp b/plugins/Dropbox/src/dropbox_services.cpp index 84c9f6b5b7..3755299199 100644 --- a/plugins/Dropbox/src/dropbox_services.cpp +++ b/plugins/Dropbox/src/dropbox_services.cpp @@ -172,6 +172,72 @@ INT_PTR CDropbox::ProtoReceiveMessage(void *obj, WPARAM, LPARAM lParam) return 0; } +INT_PTR CDropbox::SendFileToDropbox(void *obj, WPARAM hContact, LPARAM lParam) +{ + CDropbox *instance = (CDropbox*)obj; + + const char *filePath = (char*)lParam; + const char *fileName = strrchr(filePath, '\\') + 1; + + FILE *file = fopen(filePath, "rb"); + if (file != NULL) + { + fseek(file, 0, SEEK_END); + DWORD fileSize = ftell(file); + fseek(file, 0, SEEK_SET); + + int chunkSize = DROPBOX_FILE_CHUNK_SIZE; + if (fileSize <= (DROPBOX_FILE_CHUNK_SIZE)) + { + char *data = new char[fileSize + 1]; + int count = (int)fread(data, sizeof(char), fileSize, file); + + instance->SendFile(fileName, data, fileSize); + } + else + { + int offset = 0; + bool error = false; + char *uploadId = new char[32]; + + while (!feof(file) && !ferror(file)) + { + char *data = new char[chunkSize + 1]; + int count = (int)fread(data, sizeof(char), chunkSize, file); + + if (!offset) + { + if (instance->SendFileChunkedFirst(data, count, uploadId, offset)) + { + error = true; + break; + } + } + else + { + if (instance->SendFileChunkedNext(data, count, uploadId, offset)) + { + error = true; + break; + } + } + } + + fclose(file); + + if (!error) + { + if (instance->SendFileChunkedLast(fileName, uploadId)) + { + error = true; + } + } + } + } + + return 0; +} + INT_PTR CDropbox::SendFilesToDropbox(void *obj, WPARAM hContact, LPARAM) { CDropbox *instance = (CDropbox*)obj; @@ -182,5 +248,12 @@ INT_PTR CDropbox::SendFilesToDropbox(void *obj, WPARAM hContact, LPARAM) 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 c764ff9081..53433bacd1 100644 --- a/plugins/Dropbox/src/dropbox_transfers.cpp +++ b/plugins/Dropbox/src/dropbox_transfers.cpp @@ -1,28 +1,55 @@ #include "common.h" -int CDropbox::HandleFileTransferError(NETLIBHTTPREQUEST *response, MCONTACT hContact) +int CDropbox::HandleFileTransferError(HANDLE hNetlibUser, NETLIBHTTPREQUEST *response) { if (!response) { - CDropbox::ShowNotification(TranslateT("Server does not respond"), MB_ICONERROR, hContact); + Netlib_Logf(hNetlibUser, "%s", "Server does not respond"); + //CDropbox::ShowNotification(TranslateT("Server does not respond"), MB_ICONERROR); return ACKRESULT_FAILED; } if (response->resultCode != HTTP_STATUS_OK) { - CDropbox::ShowNotification(HttpStatusToText((HTTP_STATUS)response->resultCode), MB_ICONERROR, hContact); + Netlib_Logf(hNetlibUser, "%s", HttpStatusToText((HTTP_STATUS)response->resultCode)); + //CDropbox::ShowNotification(TranslateTS(HttpStatusToText((HTTP_STATUS)response->resultCode)), MB_ICONERROR); return response->resultCode; } return 0; } -int CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, int &offset, MCONTACT hContact) +int CDropbox::SendFile(const char *fileName, const char *data, int length) +{ + char *utf8_fileName = mir_utf8encode(fileName); + + CMStringA url; + url.AppendFormat(DROPBOX_APICONTENT_URL "/files_put/%s/%s", + DROPBOX_API_ROOT, + utf8_fileName); + url.Replace('\\', '/'); + + mir_free(utf8_fileName); + + HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_PUT, DROPBOX_APICONTENT_URL "/files_put"); + request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); + request->pData = (char*)mir_alloc(sizeof(char)* length); + memcpy(request->pData, data, length); + request->dataLength = length; + + mir_ptr response(request->Send()); + + delete request; + + return HandleFileTransferError(hNetlibUser, response); +} + +int CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, int &offset) { HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_PUT, DROPBOX_APICONTENT_URL "/chunked_upload"); request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); request->AddHeader("Content-Type", "application/octet-stream"); - request->pData = (char*)mir_alloc(sizeof(char) * length); + request->pData = (char*)mir_alloc(sizeof(char)* length); memcpy(request->pData, data, length); request->dataLength = length; @@ -44,13 +71,13 @@ int CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, return 0; } - return HandleFileTransferError(response, hContact); + return HandleFileTransferError(hNetlibUser, response); } - return HandleFileTransferError(response, hContact); + return HandleFileTransferError(hNetlibUser, response); } -int CDropbox::SendFileChunkedNext(const char *data, int length, const char *uploadId, int &offset, MCONTACT hContact) +int CDropbox::SendFileChunkedNext(const char *data, int length, const char *uploadId, int &offset) { CMStringA url = DROPBOX_APICONTENT_URL "/chunked_upload"; url.AppendFormat("?upload_id=%s&offset=%i", uploadId, offset); @@ -58,7 +85,7 @@ int CDropbox::SendFileChunkedNext(const char *data, int length, const char *uplo HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_PUT, url); request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); request->AddHeader("Content-Type", "application/octet-stream"); - request->pData = (char*)mir_alloc(sizeof(char) * length); + request->pData = (char*)mir_alloc(sizeof(char)* length); memcpy(request->pData, data, length); request->dataLength = length; @@ -77,13 +104,13 @@ int CDropbox::SendFileChunkedNext(const char *data, int length, const char *uplo return 0; } - return HandleFileTransferError(response, hContact); + return HandleFileTransferError(hNetlibUser, response); } - return HandleFileTransferError(response, hContact); + return HandleFileTransferError(hNetlibUser, response); } -int CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId, MCONTACT hContact) +int CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId) { char *utf8_fileName = mir_utf8encode(fileName); @@ -109,80 +136,80 @@ int CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId, MC delete request; - if (response && response->resultCode == HTTP_STATUS_OK) - { - if (!strchr(fileName, '\\')) - { - url.Replace(DROPBOX_APICONTENT_URL, DROPBOX_API_URL); - url.Replace("commit_chunked_upload", "shares"); - - request = new HttpRequest(hNetlibUser, REQUEST_POST, url); - request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); - if (!db_get_b(NULL, MODULE, "UseSortLinks", 1)) - { - request->pData = mir_strdup("short_url=false"); - request->dataLength = strlen(request->pData); - } - - response = request->Send(); - - delete request; - - if (response &&response->resultCode == HTTP_STATUS_OK) - { - JSONNODE *root = json_parse(response->pData); - if (root) - { - JSONNODE *node = json_get(root, "url"); - - char message[1024]; - mir_snprintf( - message, - SIZEOF(message), - Translate("Link to download file \"%s\": %s"), - fileName, - mir_u2a(json_as_string(node))); - - if (hContact != CDropbox::GetDefaultContact()) - { - if (CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message) != ACKRESULT_FAILED) - { - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.szModule = MODULE; - dbei.timestamp = time(NULL); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = strlen(message); - dbei.pBlob = (PBYTE)message; - dbei.flags = DBEF_SENT | DBEF_UTF; - db_event_add(hContact, &dbei); - } - } - else - { - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.szModule = MODULE; - dbei.timestamp = time(NULL); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = strlen(message); - dbei.pBlob = (PBYTE)message; - dbei.flags = DBEF_UTF; - db_event_add(hContact, &dbei); - } - - return 0; - } - - return HandleFileTransferError(response, hContact); - } - - return HandleFileTransferError(response, hContact); - } - } - - return HandleFileTransferError(response, hContact); + //if (response && response->resultCode == HTTP_STATUS_OK) + //{ + // if (!strchr(fileName, '\\')) + // { + // url.Replace(DROPBOX_APICONTENT_URL, DROPBOX_API_URL); + // url.Replace("commit_chunked_upload", "shares"); + + // request = new HttpRequest(hNetlibUser, REQUEST_POST, url); + // request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); + // if (!db_get_b(NULL, MODULE, "UseSortLinks", 1)) + // { + // request->pData = mir_strdup("short_url=false"); + // request->dataLength = strlen(request->pData); + // } + + // response = request->Send(); + + // delete request; + + // if (response &&response->resultCode == HTTP_STATUS_OK) + // { + // JSONNODE *root = json_parse(response->pData); + // if (root) + // { + // JSONNODE *node = json_get(root, "url"); + + // char message[1024]; + // mir_snprintf( + // message, + // SIZEOF(message), + // Translate("Link to download file \"%s\": %s"), + // fileName, + // mir_u2a(json_as_string(node))); + + // if (hContact != CDropbox::GetDefaultContact()) + // { + // if (CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message) != ACKRESULT_FAILED) + // { + // DBEVENTINFO dbei = { sizeof(dbei) }; + // dbei.szModule = MODULE; + // dbei.timestamp = time(NULL); + // dbei.eventType = EVENTTYPE_MESSAGE; + // dbei.cbBlob = strlen(message); + // dbei.pBlob = (PBYTE)message; + // dbei.flags = DBEF_SENT | DBEF_UTF; + // db_event_add(hContact, &dbei); + // } + // } + // else + // { + // DBEVENTINFO dbei = { sizeof(dbei) }; + // dbei.szModule = MODULE; + // dbei.timestamp = time(NULL); + // dbei.eventType = EVENTTYPE_MESSAGE; + // dbei.cbBlob = strlen(message); + // dbei.pBlob = (PBYTE)message; + // dbei.flags = DBEF_UTF; + // db_event_add(hContact, &dbei); + // } + + // return 0; + // } + + // return HandleFileTransferError(hNetlibUser, response); + // } + + // return HandleFileTransferError(hNetlibUser, response); + // } + //} + + return HandleFileTransferError(hNetlibUser, response); } -int CDropbox::CreateFolder(const char *folderName, MCONTACT hContact) +int CDropbox::CreateFolder(const char *folderName) { char *utf8_folderName = mir_utf8encode(folderName); @@ -206,78 +233,112 @@ int CDropbox::CreateFolder(const char *folderName, MCONTACT hContact) delete request; - if (response && (response->resultCode == HTTP_STATUS_OK || response->resultCode == HTTP_STATUS_FORBIDDEN)) - { - if (!strchr(folderName, '\\')) - { - CMStringA url = DROPBOX_API_URL; - url.AppendFormat("/shares/%s/%s", - DROPBOX_API_ROOT, - folder); - - request = new HttpRequest(hNetlibUser, REQUEST_POST, url); - request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); - if (!db_get_b(NULL, MODULE, "UseSortLinks", 1)) - { - request->pData = mir_strdup("short_url=false"); - request->dataLength = strlen(request->pData); - } + //if (response && (response->resultCode == HTTP_STATUS_OK || response->resultCode == HTTP_STATUS_FORBIDDEN)) + //{ + // if (!strchr(folderName, '\\')) + // { + // CMStringA url = DROPBOX_API_URL; + // url.AppendFormat("/shares/%s/%s", + // DROPBOX_API_ROOT, + // folder); + + // request = new HttpRequest(hNetlibUser, REQUEST_POST, url); + // request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); + // if (!db_get_b(NULL, MODULE, "UseSortLinks", 1)) + // { + // request->pData = mir_strdup("short_url=false"); + // request->dataLength = strlen(request->pData); + // } + + // mir_free(response); + + // response = request->Send(); + + // if (response && response->resultCode == HTTP_STATUS_OK) + // { + // JSONNODE *root = json_parse(response->pData); + // if (root != NULL) + // { + // JSONNODE *node = json_get(root, "url"); + // char message[1024]; + // mir_snprintf( + // message, + // SIZEOF(message), + // Translate("Link to download folder \"%s\": %s"), + // folderName, + // mir_u2a(json_as_string(node))); + + // if (hContact != CDropbox::GetDefaultContact()) + // { + // if (CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message) != ACKRESULT_FAILED) + // { + // DBEVENTINFO dbei = { sizeof(dbei) }; + // dbei.szModule = MODULE; + // dbei.timestamp = time(NULL); + // dbei.eventType = EVENTTYPE_MESSAGE; + // dbei.cbBlob = strlen(message); + // dbei.pBlob = (PBYTE)message; + // dbei.flags = DBEF_SENT | DBEF_UTF; + // db_event_add(hContact, &dbei); + // } + // } + // else + // { + // DBEVENTINFO dbei = { sizeof(dbei) }; + // dbei.szModule = MODULE; + // dbei.timestamp = time(NULL); + // dbei.eventType = EVENTTYPE_MESSAGE; + // dbei.cbBlob = strlen(message); + // dbei.pBlob = (PBYTE)message; + // dbei.flags = DBEF_UTF; + // db_event_add(hContact, &dbei); + // } + + // return 0; + // } + + // return HandleFileTransferError(hNetlibUser, response); + // } + + // return HandleFileTransferError(hNetlibUser, response); + // } + //} + + return HandleFileTransferError(hNetlibUser, response); +} - mir_free(response); +int CDropbox::CreateDownloadUrl(const char *path, char *url) +{ + CMStringA api_url = DROPBOX_API_URL; + api_url.AppendFormat("/shares/%s/%s", + DROPBOX_API_ROOT, + path); - response = request->Send(); + if (!db_get_b(NULL, MODULE, "UseSortLinks", 1)) + api_url += "?short_url=false"; - if (response && response->resultCode == HTTP_STATUS_OK) - { - JSONNODE *root = json_parse(response->pData); - if (root != NULL) - { - JSONNODE *node = json_get(root, "url"); - char message[1024]; - mir_snprintf( - message, - SIZEOF(message), - Translate("Link to download folder \"%s\": %s"), - folderName, - mir_u2a(json_as_string(node))); - - if (hContact != CDropbox::GetDefaultContact()) - { - if (CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)&message) != ACKRESULT_FAILED) - { - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.szModule = MODULE; - dbei.timestamp = time(NULL); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = strlen(message); - dbei.pBlob = (PBYTE)message; - dbei.flags = DBEF_SENT | DBEF_UTF; - db_event_add(hContact, &dbei); - } - } - else - { - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.szModule = MODULE; - dbei.timestamp = time(NULL); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = strlen(message); - dbei.pBlob = (PBYTE)message; - dbei.flags = DBEF_UTF; - db_event_add(hContact, &dbei); - } + HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, api_url); + request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); - return 0; - } + mir_ptr response(request->Send()); - return HandleFileTransferError(response, hContact); - } + delete request; - return HandleFileTransferError(response, hContact); + if (response && response->resultCode == HTTP_STATUS_OK) + { + JSONNODE *root = json_parse(response->pData); + if (root != NULL) + { + JSONNODE *node = json_get(root, "url"); + strcpy(url, mir_u2a(json_as_string(node))); + + return 0; } + + return HandleFileTransferError(hNetlibUser, response); } - return HandleFileTransferError(response, hContact); + return HandleFileTransferError(hNetlibUser, response); } void _cdecl CDropbox::SendFileAsync(void *arg) @@ -285,11 +346,30 @@ void _cdecl CDropbox::SendFileAsync(void *arg) bool error = false; FileTransferParam *ftp = (FileTransferParam*)arg; + CMStringA urls; + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ftp->hProcess, 0); for (int i = 0; ftp->pszFolders[i]; i++) { - if (ftp->instance->CreateFolder(ftp->pszFolders[i], ftp->hContact)) + if (!ftp->instance->CreateFolder(ftp->pszFolders[i])) + { + if (!strchr(ftp->pszFolders[i], '\\')) + { + char url[MAX_PATH]; + if (!ftp->instance->CreateDownloadUrl(ftp->pszFolders[i], url)) + { + urls += url; + urls += "\r\n"; + } + else + { + error = true; + break; + } + } + } + else { error = true; break; @@ -325,18 +405,18 @@ void _cdecl CDropbox::SendFileAsync(void *arg) while (!feof(file) && !ferror(file)) { - int chunkSize = DROPBOX_FILE_CHUNK_SIZE; - if (fileSize < 1024*1024) - chunkSize = DROPBOX_FILE_CHUNK_SIZE / 5; - else if (fileSize > 20*1024*1024) - chunkSize = DROPBOX_FILE_CHUNK_SIZE * 4; + int chunkSize = DROPBOX_FILE_CHUNK_SIZE / 4; + if (fileSize < 1024 * 1024) + chunkSize = DROPBOX_FILE_CHUNK_SIZE / 20; + else if (fileSize > 20 * 1024 * 1024) + chunkSize = DROPBOX_FILE_CHUNK_SIZE; char *data = new char[chunkSize + 1]; int count = (int)fread(data, sizeof(char), chunkSize, file); if (!offset) { - if (ftp->instance->SendFileChunkedFirst(data, count, uploadId, offset, ftp->hContact)) + if (ftp->instance->SendFileChunkedFirst(data, count, uploadId, offset)) { error = true; break; @@ -344,7 +424,7 @@ void _cdecl CDropbox::SendFileAsync(void *arg) } else { - if (ftp->instance->SendFileChunkedNext(data, count, uploadId, offset, ftp->hContact)) + if (ftp->instance->SendFileChunkedNext(data, count, uploadId, offset)) { error = true; break; @@ -361,12 +441,28 @@ void _cdecl CDropbox::SendFileAsync(void *arg) if (!error) { - if (ftp->instance->SendFileChunkedLast(fileName, uploadId, ftp->hContact)) + if (ftp->instance->SendFileChunkedLast(fileName, uploadId)) { error = true; + break; } else { + if (!strchr(fileName, '\\')) + { + char url[MAX_PATH]; + if (!ftp->instance->CreateDownloadUrl(fileName, url)) + { + urls += url; + urls += "\r\n"; + } + else + { + error = true; + break; + } + } + ftp->pfts.currentFileProgress = ftp->pfts.currentFileSize; if (i < ftp->pfts.totalFiles - 1) @@ -381,7 +477,42 @@ void _cdecl CDropbox::SendFileAsync(void *arg) ftp->instance->hTransferContact = 0; if (!error) + { ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftp->hProcess, 0); + + if (db_get_b(NULL, MODULE, "UrlAutoSend", 0)) + { + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = MODULE; + dbei.flags = DBEF_UTF; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = urls.GetLength(); + dbei.pBlob = (PBYTE)urls.GetBuffer(); + + if (ftp->hContact != ftp->instance->GetDefaultContact()) + { + CallContactService(ftp->hContact, PSS_MESSAGE, 0, (LPARAM)urls.GetBuffer()); + dbei.flags |= DBEF_SENT | DBEF_READ; + } + + db_event_add(ftp->hContact, &dbei); + } + else if (db_get_b(NULL, MODULE, "UrlPasteToMessageLog", 1)) + CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM)ftp->hContact, (LPARAM)urls.GetBuffer()); + + if (db_get_b(NULL, MODULE, "UrlCopyToClipboard", 1)) + { + int length = urls.GetLength() + 1; + HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, length); + memcpy(GlobalLock(hMem), urls.GetBuffer(), length); + GlobalUnlock(hMem); + OpenClipboard(0); + EmptyClipboard(); + SetClipboardData(CF_TEXT, hMem); + CloseClipboard(); + } + } else ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ftp->hProcess, 0); diff --git a/plugins/Dropbox/src/dropbox_utils.cpp b/plugins/Dropbox/src/dropbox_utils.cpp index ecf6c584a0..34ac156dc5 100644 --- a/plugins/Dropbox/src/dropbox_utils.cpp +++ b/plugins/Dropbox/src/dropbox_utils.cpp @@ -13,26 +13,26 @@ wchar_t *CDropbox::HttpStatusToText(HTTP_STATUS status) switch (status) { case HTTP_STATUS_OK: - return TranslateT("OK"); + return L"OK"; case HTTP_STATUS_BAD_REQUEST: - return TranslateT("Bad input parameter. Error message should indicate which one and why"); + return L"Bad input parameter. Error message should indicate which one and why"; case HTTP_STATUS_UNAUTHORIZED: - return TranslateT("Bad or expired token. This can happen if the user or Dropbox revoked or expired an access token. To fix, you should re-authenticate the user"); + return L"Bad or expired token. This can happen if the user or Dropbox revoked or expired an access token. To fix, you should re-authenticate the user"; case HTTP_STATUS_FORBIDDEN: - return TranslateT("Bad OAuth request (wrong consumer key, bad nonce, expired timestamp...). Unfortunately, re-authenticating the user won't help here"); + return L"Bad OAuth request (wrong consumer key, bad nonce, expired timestamp...). Unfortunately, re-authenticating the user won't help here"; case HTTP_STATUS_NOT_FOUND: - return TranslateT("File or folder not found at the specified path"); + return L"File or folder not found at the specified path"; case HTTP_STATUS_METHOD_NOT_ALLOWED: - return TranslateT("Request method not expected (generally should be GET or POST)"); + return L"Request method not expected (generally should be GET or POST)"; case HTTP_STATUS_TOO_MANY_REQUESTS: - return TranslateT("Your app is making too many requests and is being rate limited. 429s can trigger on a per-app or per-user basis"); + return L"Your app is making too many requests and is being rate limited. 429s can trigger on a per-app or per-user basis"; case HTTP_STATUS_SERVICE_UNAVAILABLE: - return TranslateT("If the response includes the Retry-After header, this means your OAuth 1.0 app is being rate limited. Otherwise, this indicates a transient server error, and your app should retry its request."); + return L"If the response includes the Retry-After header, this means your OAuth 1.0 app is being rate limited. Otherwise, this indicates a transient server error, and your app should retry its request."; case HTTP_STATUS_INSUFICIENTE_STORAGE: - return TranslateT("User is over Dropbox storage quota"); + return L"User is over Dropbox storage quota"; } - return TranslateT("Unknown"); + return L"Unknown"; } void CDropbox::ShowNotification(const wchar_t *caption, const wchar_t *message, int flags, MCONTACT hContact) diff --git a/plugins/Dropbox/src/m_dropbox.h b/plugins/Dropbox/src/m_dropbox.h new file mode 100644 index 0000000000..d0266942a7 --- /dev/null +++ b/plugins/Dropbox/src/m_dropbox.h @@ -0,0 +1,11 @@ +#ifndef M_DROPBOX_H_ +#define M_DROPBOX_H_ + +//upload file on Dropbox +//wParam = (MCONTACT)hContact +//lParam = (LPARAM)(const char*)szPath +//returns 0 on success or nonzero on failure +//returns immediately, before the file or folder is uploaded +#define MS_DROPBOX_SEND_FILE "Dropbox/Send/File" + +#endif //M_DROPBOX_H_ \ No newline at end of file diff --git a/plugins/Dropbox/src/resource.h b/plugins/Dropbox/src/resource.h index bd27208c23..a8423821f2 100644 --- a/plugins/Dropbox/src/resource.h +++ b/plugins/Dropbox/src/resource.h @@ -8,8 +8,13 @@ #define IDC_AUTHORIZE 1002 #define IDC_CHECK2 1004 #define IDC_USE_SHORT_LINKS 1004 +#define IDC_URL_USE_SHORT 1004 #define IDC_AUTH_STATUS 1005 #define IDC_GET_AUTH_LINK 1006 +#define IDC_URL_COPYTOCB 1009 +#define IDC_CHECK1 1010 +#define IDC_URL_COPYTOML 1029 +#define IDC_URL_AUTOSEND 1030 #define IDC_GETAUTH 1200 // Next default values for new objects @@ -18,7 +23,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 103 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1007 +#define _APS_NEXT_CONTROL_VALUE 1011 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif -- cgit v1.2.3