From a0a667fd07e912b1dc425748e58a72fa9a50512f Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Tue, 11 Mar 2014 14:19:01 +0000 Subject: Dropbox: - fixed TabSrmm button behavior - added ME_DROPBOX_SEND_SUCCEEDED and ME_DROPBOX_SEND_FAILED events - remained only unicode version of MS_DROPBOX_SEND_FILE - minor fixes - version bumped git-svn-id: http://svn.miranda-ng.org/main/trunk@8557 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dropbox/src/dropbox.cpp | 198 ++++++---------- plugins/Dropbox/src/dropbox.h | 30 +-- plugins/Dropbox/src/dropbox_dialogs.cpp | 6 +- plugins/Dropbox/src/dropbox_events.cpp | 147 ++++++++++-- plugins/Dropbox/src/dropbox_menus.cpp | 6 +- plugins/Dropbox/src/dropbox_services.cpp | 142 +++++------- plugins/Dropbox/src/dropbox_transfers.cpp | 363 ++++++++---------------------- plugins/Dropbox/src/dropbox_utils.cpp | 36 +-- plugins/Dropbox/src/file_transfer.h | 23 +- plugins/Dropbox/src/version.h | 2 +- plugins/ExternalAPI/m_dropbox.h | 21 +- 11 files changed, 393 insertions(+), 581 deletions(-) (limited to 'plugins') diff --git a/plugins/Dropbox/src/dropbox.cpp b/plugins/Dropbox/src/dropbox.cpp index 74c3eb8653..9081daae85 100644 --- a/plugins/Dropbox/src/dropbox.cpp +++ b/plugins/Dropbox/src/dropbox.cpp @@ -7,17 +7,18 @@ CDropbox::CDropbox() pd.type = PROTOTYPE_VIRTUAL; CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); + HookEventObj(ME_PROTO_ACK, OnProtoAck, this); HookEventObj(ME_SYSTEM_PRESHUTDOWN, OnPreShutdown, this); HookEventObj(ME_SYSTEM_MODULESLOADED, OnModulesLoaded, this); - HookEventObj(ME_DB_CONTACT_DELETED, OnContactDeleted, this); - HookEventObj(ME_OPT_INITIALISE, OnOptionsInitialized, this); - HookEventObj(ME_CLIST_PREBUILDCONTACTMENU, OnPrebuildContactMenu, this); + + hFileSendFailedHook = CreateHookableEvent(ME_DROPBOX_SEND_FAILED); + hFileSendSuccessedHook = CreateHookableEvent(ME_DROPBOX_SEND_SUCCEEDED); + HookEventObj(ME_DROPBOX_SEND_SUCCEEDED, OnSendSuccessed, this); CreateServiceFunctionObj(MS_DROPBOX_SEND_FILE, SendFileToDropbox, this); - CreateServiceFunctionObj(MS_DROPBOX_SEND_FILEW, SendFileWToDropbox, this); CreateProtoServiceFunction(MODULE, PS_GETCAPS, ProtoGetCaps); - CreateProtoServiceFunctionObj(PSS_FILE, ProtoSendFile, this); + CreateProtoServiceFunctionObj(PSS_FILEW, ProtoSendFile, this); CreateProtoServiceFunctionObj(PSS_MESSAGE, ProtoSendMessage, this); CreateProtoServiceFunctionObj(PSR_MESSAGE, ProtoReceiveMessage, this); @@ -33,6 +34,12 @@ CDropbox::CDropbox() hDefaultContact = hTransferContact = 0; } +CDropbox::~CDropbox() +{ + DestroyHookableEvent(hFileSendFailedHook); + DestroyHookableEvent(hFileSendSuccessedHook); +} + MCONTACT CDropbox::GetDefaultContact() { if (!hDefaultContact) @@ -61,71 +68,6 @@ bool CDropbox::HasAccessToken() return db_get_sa(NULL, MODULE, "TokenSecret") != NULL; } -//void CDropbox::RequestAcceessToken() -//{ -// ShellExecuteA(NULL, "open", DROPBOX_WWW_URL DROPBOX_API_VER "/oauth2/authorize?response_type=code&client_id=" DROPBOX_API_KEY, NULL, NULL, SW_SHOWDEFAULT); -// -// char request_token[128] = { 0 }; -// -// if (DialogBoxParam( -// g_hInstance, -// MAKEINTRESOURCE(IDD_TOKEN_REQUEST), -// NULL, -// CDropbox::TokenRequestProc, -// (LPARAM)&request_token) == IDOK) -// { -// char data[1024]; -// mir_snprintf( -// data, -// SIZEOF(data), -// "grant_type=authorization_code&code=%s", -// request_token); -// -// HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/oauth2/token"); -// request->pData = mir_strdup(data); -// request->dataLength = (int)strlen(data); -// request->AddHeader("Content-Type", "application/x-www-form-urlencoded"); -// request->AddBasicAuthHeader(DROPBOX_API_KEY, DROPBOX_API_SECRET); -// -// mir_ptr response(request->Send()); -// -// delete request; -// -// MCONTACT hContact = CDropbox::GetDefaultContact(); -// -// if (response) -// { -// JSONNODE *root = json_parse(response->pData); -// if (root) -// { -// if (response->resultCode == HTTP_STATUS_OK) -// { -// JSONNODE *node = json_get(root, "access_token"); -// ptrA access_token = ptrA(mir_u2a(json_as_string(node))); -// db_set_s(NULL, MODULE, "TokenSecret", access_token); -// -// if (hContact) -// { -// if (db_get_w(hContact, MODULE, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE) -// db_set_w(hContact, MODULE, "Status", ID_STATUS_ONLINE); -// } -// -// CDropbox::ShowNotification(TranslateT("You have been authorized"), MB_ICONINFORMATION); -// } -// else -// { -// JSONNODE *node = json_get(root, "error_description"); -// ptrW error_description(json_as_string(node)); -// -// CDropbox::ShowNotification((wchar_t*)error_description, MB_ICONERROR); -// } -// } -// } -// else -// HandleFileTransferError(response, hContact); -// } -//} - void CDropbox::RequestAccountInfo() { HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_GET, DROPBOX_API_URL "/account/info"); @@ -136,79 +78,69 @@ void CDropbox::RequestAccountInfo() MCONTACT hContact = CDropbox::GetDefaultContact(); - if (response) + if (response && response->resultCode == HTTP_STATUS_OK) { JSONNODE *root = json_parse(response->pData); if (root) { - if (response->resultCode == HTTP_STATUS_OK) + JSONNODE *node = json_get(root, "referral_link"); + if (node) { - JSONNODE *node = json_get(root, "referral_link"); - if (node) - { - ptrW referral_link = ptrW(json_as_string(node)); - db_set_ws(hContact, MODULE, "Homepage", referral_link); - } + ptrW referral_link = ptrW(json_as_string(node)); + db_set_ws(hContact, MODULE, "Homepage", referral_link); + } - node = json_get(root, "display_name"); - if (node) + node = json_get(root, "display_name"); + if (node) + { + ptrW display_name = ptrW(json_as_string(node)); + wchar_t *sep = wcsrchr(display_name, L' '); + if (sep) { - ptrW display_name = ptrW(json_as_string(node)); - wchar_t *sep = wcsrchr(display_name, L' '); - if (sep) - { - db_set_ws(hContact, MODULE, "LastName", sep + 1); - display_name[wcslen(display_name) - wcslen(sep)] = '\0'; - db_set_ws(hContact, MODULE, "FirstName", display_name); - } - else - { - db_set_ws(hContact, MODULE, "FirstName", display_name); - db_unset(hContact, MODULE, "LastName"); - } + db_set_ws(hContact, MODULE, "LastName", sep + 1); + display_name[wcslen(display_name) - wcslen(sep)] = '\0'; + db_set_ws(hContact, MODULE, "FirstName", display_name); } - - node = json_get(root, "country"); - if (node) + else { - ptrW isocodeW(json_as_string(node)); - ptrA isocode(mir_u2a(isocodeW)); - - if (!strlen(isocode)) - db_unset(hContact, MODULE, "Country"); - else - { - char *country = (char *)CallService(MS_UTILS_GETCOUNTRYBYISOCODE, (WPARAM)isocode, 0); - db_set_s(hContact, MODULE, "Country", country); - } + db_set_ws(hContact, MODULE, "FirstName", display_name); + db_unset(hContact, MODULE, "LastName"); } + } + + node = json_get(root, "country"); + if (node) + { + ptrW isocodeW(json_as_string(node)); + ptrA isocode(mir_u2a(isocodeW)); - node = json_get(root, "quota_info"); - root = json_as_node(node); - if (root) + if (!strlen(isocode)) + db_unset(hContact, MODULE, "Country"); + else { - node = json_get(root, "shared"); - if (node) - db_set_dw(hContact, MODULE, "SharedQuota", json_as_int(node)); - node = json_get(root, "normal"); - if (node) - db_set_dw(hContact, MODULE, "NormalQuota", json_as_int(node)); - node = json_get(root, "quota"); - if (node) - db_set_dw(hContact, MODULE, "TotalQuota", json_as_int(node)); + char *country = (char *)CallService(MS_UTILS_GETCOUNTRYBYISOCODE, (WPARAM)isocode, 0); + db_set_s(hContact, MODULE, "Country", country); } } - /*else - { - JSONNODE *node = json_get(root, "error_description"); - ptrW error_description(json_as_string(node)); - CDropbox::ShowNotification((wchar_t*)error_description, MB_ICONERROR); - }*/ + node = json_get(root, "quota_info"); + root = json_as_node(node); + if (root) + { + node = json_get(root, "shared"); + if (node) + db_set_dw(hContact, MODULE, "SharedQuota", json_as_int(node)); + node = json_get(root, "normal"); + if (node) + db_set_dw(hContact, MODULE, "NormalQuota", json_as_int(node)); + node = json_get(root, "quota"); + if (node) + db_set_dw(hContact, MODULE, "TotalQuota", json_as_int(node)); + } } } - //else - // HandleFileTransferError(response, hContact); + + HandleHttpResponseError(hNetlibUser, response); } void CDropbox::DestroyAcceessToken() @@ -282,8 +214,8 @@ UINT CDropbox::RequestAcceessTokenAsync(void *owner, void* param) if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("you have been authorized")); - else - ShowNotification(TranslateT("you have been authorized"), MB_ICONINFORMATION); + /*else + ShowNotification(TranslateT("you have been authorized"), MB_ICONINFORMATION);*/ } else { @@ -292,17 +224,17 @@ UINT CDropbox::RequestAcceessTokenAsync(void *owner, void* param) if (hwndDlg) SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, error_description); - else - ShowNotification((wchar_t*)error_description, MB_ICONERROR); + /*else + ShowNotification((wchar_t*)error_description, MB_ICONERROR);*/ } } } else { if (hwndDlg) - SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("unknown error")); - else - HandleFileTransferError(instance->hNetlibUser, response); + SetDlgItemText(hwndDlg, IDC_AUTH_STATUS, TranslateT("server does not respond")); + + HandleHttpResponseError(instance->hNetlibUser, response); } SetDlgItemTextA(hwndDlg, IDC_REQUEST_CODE, ""); diff --git a/plugins/Dropbox/src/dropbox.h b/plugins/Dropbox/src/dropbox.h index afe501c0f0..2b2418e669 100644 --- a/plugins/Dropbox/src/dropbox.h +++ b/plugins/Dropbox/src/dropbox.h @@ -37,12 +37,15 @@ class CDropbox { public: CDropbox(); - virtual ~CDropbox() { } + virtual ~CDropbox(); private: HANDLE hNetlibUser; ULONG hFileProcess; ULONG hMessageProcess; + + HANDLE hFileSendFailedHook; + HANDLE hFileSendSuccessedHook; MCONTACT hDefaultContact; MCONTACT hTransferContact; @@ -53,25 +56,28 @@ private: HGENMENU contactMenuItems[CMI_MAX]; // hooks - static int OnModulesLoaded(void *obj, WPARAM wParam, LPARAM lParam); + static int OnProtoAck(void *obj, WPARAM wParam, LPARAM lParam); static int OnPreShutdown(void *obj, WPARAM wParam, LPARAM lParam); + static int OnModulesLoaded(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 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); - static int OnFileDoalogSuccessed(void *obj, WPARAM wParam, LPARAM lParam); + 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); + static INT_PTR ProtoGetCaps(WPARAM wParam, LPARAM lParam); static INT_PTR ProtoSendFile(void *obj, WPARAM wParam, LPARAM lParam); 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 SendFileWToDropbox(void *obj, WPARAM wParam, LPARAM lParam); - static INT_PTR SendFilesToDropbox(void *obj, WPARAM wParam, LPARAM lParam); // commands @@ -92,8 +98,6 @@ private: void RequestAccountInfo(); // transrers - 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); @@ -101,9 +105,9 @@ private: int CreateFolder(const char *folderName); - int CreateDownloadUrl(const char *path, char *url); + int CreateDownloadUrl(const char *path, wchar_t *url); - static void _cdecl SendFileAsync(void *arg); + static UINT SendFilesAsync(void *owner, void *arg); // contacts MCONTACT GetDefaultContact(); @@ -119,12 +123,8 @@ private: static INT_PTR CALLBACK MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); // utils - static HANDLE CreateProtoServiceFunctionObj(const char *szService, MIRANDASERVICEOBJ serviceProc, void *obj); - static wchar_t *HttpStatusToText(HTTP_STATUS status); - - static void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); - static void ShowNotification(const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); + static int HandleHttpResponseError(HANDLE hNetlibUser, NETLIBHTTPREQUEST *response); }; #endif //_DROPBOX_PROTO_H_ \ No newline at end of file diff --git a/plugins/Dropbox/src/dropbox_dialogs.cpp b/plugins/Dropbox/src/dropbox_dialogs.cpp index 0a2f9c1187..cc116fa02f 100644 --- a/plugins/Dropbox/src/dropbox_dialogs.cpp +++ b/plugins/Dropbox/src/dropbox_dialogs.cpp @@ -27,8 +27,10 @@ INT_PTR CALLBACK CDropbox::MainOptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam 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_COPYTOMIA, db_get_b(NULL, MODULE, "UrlPasteToMessageInputArea", 0)); + if (db_get_b(NULL, MODULE, "UrlAutoSend", 1)) + SendDlgItemMessage(hwndDlg, IDC_URL_AUTOSEND, BM_SETCHECK, BST_CHECKED, 1); + else if (db_get_b(NULL, MODULE, "UrlPasteToMessageInputArea", 1)) + SendDlgItemMessage(hwndDlg, IDC_URL_COPYTOMIA, BM_SETCHECK, BST_CHECKED, 1); CheckDlgButton(hwndDlg, IDC_URL_COPYTOCB, db_get_b(NULL, MODULE, "UrlCopyToClipboard", 0)); } return TRUE; diff --git a/plugins/Dropbox/src/dropbox_events.cpp b/plugins/Dropbox/src/dropbox_events.cpp index 14d982f928..69397d8608 100644 --- a/plugins/Dropbox/src/dropbox_events.cpp +++ b/plugins/Dropbox/src/dropbox_events.cpp @@ -2,11 +2,13 @@ int CDropbox::OnModulesLoaded(void *obj, WPARAM wParam, LPARAM lParam) { - CDropbox *instance = (CDropbox*)obj; + HookEventObj(ME_DB_CONTACT_DELETED, OnContactDeleted, obj); + HookEventObj(ME_OPT_INITIALISE, OnOptionsInitialized, obj); + HookEventObj(ME_CLIST_PREBUILDCONTACTMENU, OnPrebuildContactMenu, obj); - HookEventObj(ME_FILEDLG_CANCELED, OnFileDoalogCancelled, obj); - HookEventObj(ME_FILEDLG_SUCCEEDED, OnFileDoalogSuccessed, obj); HookEventObj(ME_MSG_WINDOWEVENT, OnSrmmWindowOpened, obj); + HookEventObj(ME_FILEDLG_CANCELED, OnFileDialogCancelled, obj); + HookEventObj(ME_FILEDLG_SUCCEEDED, OnFileDialogSuccessed, obj); NETLIBUSER nlu = { sizeof(nlu) }; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; @@ -14,6 +16,8 @@ int CDropbox::OnModulesLoaded(void *obj, WPARAM wParam, LPARAM lParam) nlu.szSettingsModule = MODULE; nlu.ptszDescriptiveName = L"Dropbox"; + CDropbox *instance = (CDropbox*)obj; + instance->hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); instance->GetDefaultContact(); @@ -87,7 +91,9 @@ int CDropbox::OnSrmmWindowOpened(void *obj, WPARAM wParam, LPARAM lParam) MessageWindowEventData *ev = (MessageWindowEventData*)lParam; if (ev->uType == MSG_WINDOW_EVT_OPENING && ev->hContact) { - WORD status = db_get_w(ev->hContact, GetContactProto(ev->hContact), "Status", ID_STATUS_OFFLINE); + char *proto = GetContactProto(ev->hContact); + WORD status = db_get_w(ev->hContact, proto, "Status", ID_STATUS_OFFLINE); + bool canSendOffline = (CallProtoService(proto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_IMSENDOFFLINE) > 0; BBButton bbd = { sizeof(bbd) }; bbd.pszModuleName = MODULE; @@ -95,7 +101,7 @@ int CDropbox::OnSrmmWindowOpened(void *obj, WPARAM wParam, LPARAM lParam) bbd.bbbFlags = BBSF_RELEASED; if (ev->hContact == instance->GetDefaultContact() || !instance->HasAccessToken()) bbd.bbbFlags = BBSF_HIDDEN | BBSF_DISABLED; - else if (/*instance->hTransferContact*/ status == ID_STATUS_OFFLINE) + else if (status == ID_STATUS_OFFLINE && !canSendOffline) bbd.bbbFlags = BBSF_DISABLED; CallService(MS_BB_SETBUTTONSTATE, ev->hContact, (LPARAM)&bbd); @@ -128,28 +134,34 @@ int CDropbox::OnTabSrmmButtonPressed(void *obj, WPARAM wParam, LPARAM lParam) return 0; } -int CDropbox::OnFileDoalogCancelled(void *obj, WPARAM hContact, LPARAM lParam) +void __stdcall EnableTabSrmmButtonAsync(void *arg) +{ + BBButton bbd = { sizeof(bbd) }; + bbd.pszModuleName = MODULE; + bbd.dwButtonID = BBB_ID_FILE_SEND; + bbd.bbbFlags = BBSF_RELEASED; + MCONTACT hContact = (MCONTACT)arg; + + CallService(MS_BB_SETBUTTONSTATE, hContact, (LPARAM)&bbd); +} + +int CDropbox::OnFileDialogCancelled(void *obj, WPARAM hContact, LPARAM lParam) { CDropbox *instance = (CDropbox*)obj; HWND hwnd = (HWND)lParam; if (instance->hTransferContact == instance->dcftp[hwnd]) { + CallFunctionAsync(EnableTabSrmmButtonAsync, (void*)instance->hTransferContact); + 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; } -int CDropbox::OnFileDoalogSuccessed(void *obj, WPARAM hContact, LPARAM lParam) +int CDropbox::OnFileDialogSuccessed(void *obj, WPARAM hContact, LPARAM lParam) { CDropbox *instance = (CDropbox*)obj; @@ -158,12 +170,109 @@ int CDropbox::OnFileDoalogSuccessed(void *obj, WPARAM hContact, LPARAM lParam) { instance->dcftp.erase((HWND)lParam); - BBButton bbd = { sizeof(bbd) }; - bbd.pszModuleName = MODULE; - bbd.dwButtonID = BBB_ID_FILE_SEND; - bbd.bbbFlags = BBSF_RELEASED; + CallFunctionAsync(EnableTabSrmmButtonAsync, (void*)instance->hTransferContact); + } + + return 0; +} - CallService(MS_BB_SETBUTTONSTATE, hContact, (LPARAM)&bbd); +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)) + { + 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)mir_utf8encodeW(data); + + if (hContact != instance->GetDefaultContact()) + { + if (CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)data) != ACKRESULT_FAILED) + { + dbei.flags = DBEF_SENT | DBEF_READ | DBEF_UTF; + db_event_add(hContact, &dbei); + } + else + CallServiceSync(MS_MSG_SENDMESSAGEW, (WPARAM)hContact, (LPARAM)data); + } + else + 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)) { + return 0; // don't rebroadcast our own acks + } + + if (ack->type == ACKTYPE_STATUS/* && ((int)ack->lParam != (int)ack->hProcess)*/) + { + WORD status = ack->lParam; + bool canSendOffline = (CallProtoService(ack->szModule, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_IMSENDOFFLINE) > 0; + + MessageWindowInputData msgwi = { sizeof(msgwi) }; + msgwi.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; + + for (MCONTACT hContact = db_find_first(ack->szModule); hContact; hContact = db_find_next(hContact, ack->szModule)) + { + msgwi.hContact = hContact; + + MessageWindowData msgw; + msgw.cbSize = sizeof(msgw); + + if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&msgwi, (LPARAM)&msgw) && msgw.uState & MSG_WINDOW_STATE_EXISTS) + { + BBButton bbd = { sizeof(bbd) }; + bbd.pszModuleName = MODULE; + bbd.dwButtonID = BBB_ID_FILE_SEND; + bbd.bbbFlags = BBSF_RELEASED; + + if (status == ID_STATUS_OFFLINE && !canSendOffline) + bbd.bbbFlags = BBSF_DISABLED; + + CallService(MS_BB_SETBUTTONSTATE, hContact, (LPARAM)&bbd); + } + } } return 0; diff --git a/plugins/Dropbox/src/dropbox_menus.cpp b/plugins/Dropbox/src/dropbox_menus.cpp index a227bb4bb0..b7e60b6198 100644 --- a/plugins/Dropbox/src/dropbox_menus.cpp +++ b/plugins/Dropbox/src/dropbox_menus.cpp @@ -23,9 +23,11 @@ int CDropbox::OnPrebuildContactMenu(void *obj, WPARAM hContact, LPARAM lParam) Menu_ShowItem(instance->contactMenuItems[CMI_SEND_FILES], FALSE); - WORD status = db_get_w(hContact, GetContactProto(hContact), "Status", ID_STATUS_OFFLINE); + char *proto = GetContactProto(hContact); + WORD status = db_get_w(hContact, proto, "Status", ID_STATUS_OFFLINE); + bool canSendOffline = (CallProtoService(proto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_IMSENDOFFLINE) > 0; - if (hContact != instance->GetDefaultContact() && status != ID_STATUS_OFFLINE && instance->HasAccessToken() && !instance->hTransferContact) + if (hContact != instance->GetDefaultContact() && (status != ID_STATUS_OFFLINE || canSendOffline) && instance->HasAccessToken() && !instance->hTransferContact) Menu_ShowItem(instance->contactMenuItems[CMI_SEND_FILES], TRUE); return 0; diff --git a/plugins/Dropbox/src/dropbox_services.cpp b/plugins/Dropbox/src/dropbox_services.cpp index 2ab715089b..b91ce2de5c 100644 --- a/plugins/Dropbox/src/dropbox_services.cpp +++ b/plugins/Dropbox/src/dropbox_services.cpp @@ -1,5 +1,13 @@ #include "common.h" +HANDLE CDropbox::CreateProtoServiceFunctionObj(const char *szService, MIRANDASERVICEOBJ serviceProc, void *obj) +{ + char str[MAXMODULELABELLENGTH]; + mir_snprintf(str, sizeof(str), "%s%s", MODULE, szService); + str[MAXMODULELABELLENGTH - 1] = 0; + return CreateServiceFunctionObj(str, serviceProc, obj); +} + INT_PTR CDropbox::ProtoGetCaps(WPARAM wParam, LPARAM) { switch(wParam) @@ -8,16 +16,14 @@ INT_PTR CDropbox::ProtoGetCaps(WPARAM wParam, LPARAM) return PF1_IM | PF1_FILESEND; case PFLAGNUM_2: return PF2_ONLINE; - case PFLAG_UNIQUEIDTEXT: - return (INT_PTR)MODULE " ID"; - case PFLAG_UNIQUEIDSETTING: - return (DWORD_PTR)"uid"; + case PFLAGNUM_4: + return PF4_OFFLINEFILES; } return 0; } -INT_PTR CDropbox::ProtoSendFile(void *obj, WPARAM wParam, LPARAM lParam) +INT_PTR CDropbox::ProtoSendFile(void *obj, WPARAM, LPARAM lParam) { CDropbox *instance = (CDropbox*)obj; @@ -26,48 +32,49 @@ INT_PTR CDropbox::ProtoSendFile(void *obj, WPARAM wParam, LPARAM lParam) CCSDATA *pccsd = (CCSDATA*)lParam; - FileTransferParam *ftp = new FileTransferParam(instance); - ftp->pfts.flags = PFTS_SENDING | PFTS_UTF; + 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; instance->hTransferContact = 0; - char **files = (char**)pccsd->lParam; + wchar_t **paths = (wchar_t**)pccsd->lParam; - for (int i = 0; files[i]; i++) + for (int i = 0; paths[i]; i++) { - if (PathIsDirectoryA(files[i])) + if (PathIsDirectory(paths[i])) ftp->totalFolders++; else ftp->pfts.totalFiles++; } - ftp->pszFolders = new char*[ftp->totalFolders + 1]; - ftp->pszFolders[ftp->totalFolders] = NULL; + ftp->pwszFolders = (wchar_t**)mir_alloc(sizeof(wchar_t*) * (ftp->totalFolders + 1)); + ftp->pwszFolders[ftp->totalFolders] = NULL; - ftp->pfts.pszFiles = new char*[ftp->pfts.totalFiles + 1]; - ftp->pfts.pszFiles[ftp->pfts.totalFiles] = NULL; + ftp->pfts.pwszFiles = (wchar_t**)mir_alloc(sizeof(wchar_t*) * (ftp->pfts.totalFiles + 1)); + ftp->pfts.pwszFiles[ftp->pfts.totalFiles] = NULL; - for (int i = 0, j = 0, k = 0; files[i]; i++) + for (int i = 0, j = 0, k = 0; paths[i]; i++) { - if (PathIsDirectoryA(files[i])) + if (PathIsDirectory(paths[i])) { if (!ftp->relativePathStart) { - char *rootFolder = files[j]; - char *relativePath = strrchr(rootFolder, '\\') + 1; + wchar_t *rootFolder = paths[j]; + wchar_t *relativePath = wcsrchr(rootFolder, L'\\') + 1; ftp->relativePathStart = relativePath - rootFolder; } - ftp->pszFolders[j] = mir_strdup(&files[i][ftp->relativePathStart]); + ftp->pwszFolders[j] = mir_wstrdup(&paths[i][ftp->relativePathStart]); j++; } else { - ftp->pfts.pszFiles[k] = mir_strdup(files[i]); + ftp->pfts.pwszFiles[k] = mir_wstrdup(paths[i]); - FILE *file = fopen(files[i], "rb"); + FILE *file = _wfopen(paths[i], L"rb"); if (file != NULL) { fseek(file, 0, SEEK_END); @@ -82,7 +89,7 @@ INT_PTR CDropbox::ProtoSendFile(void *obj, WPARAM wParam, LPARAM lParam) ULONG fileId = InterlockedIncrement(&instance->hFileProcess); ftp->hProcess = (HANDLE)fileId; - mir_forkthread(CDropbox::SendFileAsync, ftp); + mir_forkthreadowner(CDropbox::SendFilesAsync, obj, ftp, 0); return fileId; } @@ -91,6 +98,9 @@ INT_PTR CDropbox::ProtoSendMessage(void *obj, WPARAM, LPARAM lParam) { CDropbox *instance = (CDropbox*)obj; + if (!instance->HasAccessToken()) + return ACKRESULT_FAILED; + CCSDATA *pccsd = (CCSDATA*)lParam; char *message = (char*)pccsd->lParam; @@ -101,7 +111,7 @@ INT_PTR CDropbox::ProtoSendMessage(void *obj, WPARAM, LPARAM lParam) dbei.eventType = EVENTTYPE_MESSAGE; dbei.cbBlob = strlen(message); dbei.pBlob = (PBYTE)message; - dbei.flags = DBEF_SENT | DBEF_UTF; + dbei.flags = DBEF_SENT | DBEF_READ | DBEF_UTF; db_event_add(pccsd->hContact, &dbei); char help[1024]; @@ -176,84 +186,38 @@ 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 (!instance->HasAccessToken()) + return 0; - if (!error) - { - if (instance->SendFileChunkedLast(fileName, uploadId)) - { - error = true; - } - } - } - } + const wchar_t *filePath = (wchar_t*)lParam; - return 0; -} + FileTransferParam *ftp = new FileTransferParam(); + ftp->withVisualisation = false; + ftp->pfts.flags |= PFTS_SENDING; + ftp->pfts.hContact = hContact; + ftp->pfts.totalFiles = 1; + ftp->hContact = (instance->hTransferContact) ? instance->hTransferContact : hContact; + instance->hTransferContact = 0; -INT_PTR CDropbox::SendFileWToDropbox(void *obj, WPARAM hContact, LPARAM lParam) -{ - const wchar_t *filePathW = (wchar_t*)lParam; - char *filePath = Utf8EncodeW(filePathW); + ftp->pfts.pwszFiles = (wchar_t**)mir_alloc(sizeof(wchar_t*) * (ftp->pfts.totalFiles + 1)); + ftp->pfts.pwszFiles[0] = mir_wstrdup(filePath); + ftp->pfts.pwszFiles[ftp->pfts.totalFiles] = NULL; - SendFileToDropbox(obj, hContact, (LPARAM)filePath); + ULONG fileId = InterlockedIncrement(&instance->hFileProcess); + ftp->hProcess = (HANDLE)fileId; - mir_free(filePath); + mir_forkthreadowner(CDropbox::SendFilesAsync, obj, ftp, 0); - return 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); diff --git a/plugins/Dropbox/src/dropbox_transfers.cpp b/plugins/Dropbox/src/dropbox_transfers.cpp index 82233f6b74..6cce51ce4e 100644 --- a/plugins/Dropbox/src/dropbox_transfers.cpp +++ b/plugins/Dropbox/src/dropbox_transfers.cpp @@ -1,24 +1,5 @@ #include "common.h" -int CDropbox::HandleFileTransferError(HANDLE hNetlibUser, NETLIBHTTPREQUEST *response) -{ - if (!response) - { - 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) - { - 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::SendFile(const char *fileName, const char *data, int length) { char *utf8_fileName = mir_utf8encode(fileName); @@ -41,7 +22,7 @@ int CDropbox::SendFile(const char *fileName, const char *data, int length) delete request; - return HandleFileTransferError(hNetlibUser, response); + return HandleHttpResponseError(hNetlibUser, response); } int CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, int &offset) @@ -67,14 +48,10 @@ int CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, node = json_get(root, "offset"); offset = json_as_int(node); - - return 0; } - - return HandleFileTransferError(hNetlibUser, response); } - return HandleFileTransferError(hNetlibUser, response); + return HandleHttpResponseError(hNetlibUser, response); } int CDropbox::SendFileChunkedNext(const char *data, int length, const char *uploadId, int &offset) @@ -100,30 +77,22 @@ int CDropbox::SendFileChunkedNext(const char *data, int length, const char *uplo { JSONNODE *node = json_get(root, "offset"); offset = json_as_int(node); - - return 0; } - - return HandleFileTransferError(hNetlibUser, response); } - return HandleFileTransferError(hNetlibUser, response); + return HandleHttpResponseError(hNetlibUser, response); } int CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId) { - char *utf8_fileName = mir_utf8encode(fileName); - CMStringA url; url.AppendFormat( "%s/commit_chunked_upload/%s/%s", DROPBOX_APICONTENT_URL, DROPBOX_API_ROOT, - utf8_fileName); + fileName); url.Replace('\\', '/'); - mir_free(utf8_fileName); - CMStringA param = CMStringA("upload_id=") + uploadId; HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, url); @@ -136,88 +105,14 @@ int CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId) 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(hNetlibUser, response); - // } - - // return HandleFileTransferError(hNetlibUser, response); - // } - //} - - return HandleFileTransferError(hNetlibUser, response); + return HandleHttpResponseError(hNetlibUser, response); } int CDropbox::CreateFolder(const char *folderName) { - char *utf8_folderName = mir_utf8encode(folderName); - - CMStringA folder = utf8_folderName; + CMStringA folder = folderName; folder.Replace('\\', '/'); - mir_free(utf8_folderName); - CMStringA param; param.AppendFormat("root=%s&path=%s", DROPBOX_API_ROOT, @@ -233,81 +128,10 @@ int CDropbox::CreateFolder(const char *folderName) 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); - // } - - // 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); + return HandleHttpResponseError(hNetlibUser, response); } -int CDropbox::CreateDownloadUrl(const char *path, char *url) +int CDropbox::CreateDownloadUrl(const char *path, wchar_t *url) { CMStringA api_url = DROPBOX_API_URL; api_url.AppendFormat("/shares/%s/%s", @@ -330,78 +154,85 @@ int CDropbox::CreateDownloadUrl(const char *path, char *url) if (root != NULL) { JSONNODE *node = json_get(root, "url"); - strcpy(url, mir_u2a(json_as_string(node))); - - return 0; + wcscpy(url, json_as_string(node)); } - - return HandleFileTransferError(hNetlibUser, response); } - return HandleFileTransferError(hNetlibUser, response); + return HandleHttpResponseError(hNetlibUser, response); } -void _cdecl CDropbox::SendFileAsync(void *arg) +UINT CDropbox::SendFilesAsync(void *owner, void *arg) { bool error = false; + CDropbox *instance = (CDropbox*)owner; FileTransferParam *ftp = (FileTransferParam*)arg; - CMStringA urls; + CMString urls; - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ftp->hProcess, 0); + if (ftp->withVisualisation) + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ftp->hProcess, 0); - for (int i = 0; ftp->pszFolders[i]; i++) + if (ftp->pwszFolders) { - if (!ftp->instance->CreateFolder(ftp->pszFolders[i])) + for (int i = 0; ftp->pwszFolders[i]; i++) { - if (!strchr(ftp->pszFolders[i], '\\')) + ptrA utf8_folderName(mir_utf8encodeW(ftp->pwszFolders[i])); + + if (!instance->CreateFolder(utf8_folderName)) { - char url[MAX_PATH]; - if (!ftp->instance->CreateDownloadUrl(ftp->pszFolders[i], url)) + if (!strchr(utf8_folderName, '\\')) { - urls += url; - urls += "\r\n"; - } - else - { - error = true; - break; + wchar_t url[MAX_PATH]; + if (!instance->CreateDownloadUrl(utf8_folderName, url)) + { + if (!urls.IsEmpty()) + urls += "\r\n"; + urls += url; + } + else + { + error = true; + break; + } } } - } - else - { - error = true; - break; + else + { + error = true; + break; + } } } if (!error) { - for (int i = 0; ftp->pfts.pszFiles[i]; i++) + for (int i = 0; ftp->pfts.pwszFiles[i]; i++) { - FILE *file = fopen(ftp->pfts.pszFiles[i], "rb"); - if (file != NULL) + FILE *file = _wfopen(ftp->pfts.pwszFiles[i], L"rb"); + if (file) { int offset = 0; char *uploadId = new char[32]; - const char *fileName = NULL; + const wchar_t *fileName = NULL; if (!ftp->relativePathStart) - fileName = strrchr(ftp->pfts.pszFiles[i], '\\') + 1; + fileName = wcsrchr(ftp->pfts.pwszFiles[i], L'\\') + 1; else - fileName = &ftp->pfts.pszFiles[i][ftp->relativePathStart]; + fileName = &ftp->pfts.pwszFiles[i][ftp->relativePathStart]; fseek(file, 0, SEEK_END); DWORD fileSize = ftell(file); fseek(file, 0, SEEK_SET); - ftp->pfts.currentFileNumber = i; - ftp->pfts.currentFileSize = fileSize; - ftp->pfts.currentFileProgress = 0; - ftp->pfts.szCurrentFile = strrchr(ftp->pfts.pszFiles[i], '\\') + 1; + if (ftp->withVisualisation) + { + 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); + } while (!feof(file) && !ferror(file)) { @@ -416,7 +247,7 @@ void _cdecl CDropbox::SendFileAsync(void *arg) if (!offset) { - if (ftp->instance->SendFileChunkedFirst(data, count, uploadId, offset)) + if (instance->SendFileChunkedFirst(data, count, uploadId, offset)) { error = true; break; @@ -424,37 +255,43 @@ void _cdecl CDropbox::SendFileAsync(void *arg) } else { - if (ftp->instance->SendFileChunkedNext(data, count, uploadId, offset)) + if (instance->SendFileChunkedNext(data, count, uploadId, offset)) { error = true; break; } } - ftp->pfts.currentFileProgress += count; - ftp->pfts.totalProgress += count; + if (ftp->withVisualisation) + { + 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); if (!error) { - if (ftp->instance->SendFileChunkedLast(fileName, uploadId)) + ptrA utf8_fileName(mir_utf8encodeW(fileName)); + + if (instance->SendFileChunkedLast(utf8_fileName, uploadId)) { error = true; break; } else { - if (!strchr(fileName, '\\')) + if (!wcschr(fileName, L'\\')) { - char url[MAX_PATH]; - if (!ftp->instance->CreateDownloadUrl(fileName, url)) + wchar_t url[MAX_PATH]; + if (!instance->CreateDownloadUrl(utf8_fileName, url)) { + if (!urls.IsEmpty()) + urls += "\r\n"; urls += url; - urls += "\r\n"; } else { @@ -463,60 +300,40 @@ void _cdecl CDropbox::SendFileAsync(void *arg) } } - ftp->pfts.currentFileProgress = ftp->pfts.currentFileSize; + if (ftp->withVisualisation) + { + 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); + } } } } + else + { + error = true; + break; + } } } - if (ftp->instance->hTransferContact) - 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; - dbei.flags |= DBEF_READ; - } - - db_event_add(ftp->hContact, &dbei); - } - - if (db_get_b(NULL, MODULE, "UrlPasteToMessageInputArea", 1)) - CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM)ftp->hContact, (LPARAM)urls.GetBuffer()); + if (ftp->withVisualisation) + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftp->hProcess, 0); - 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(); - } + NotifyEventHooks(instance->hFileSendSuccessedHook, ftp->hContact, (LPARAM)urls.GetBuffer()); } else - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ftp->hProcess, 0); + { + if (ftp->withVisualisation) + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ftp->hProcess, 0); + + NotifyEventHooks(instance->hFileSendFailedHook, ftp->hContact, 0); + } delete ftp; + + return 0; } \ No newline at end of file diff --git a/plugins/Dropbox/src/dropbox_utils.cpp b/plugins/Dropbox/src/dropbox_utils.cpp index 34ac156dc5..925d157dfd 100644 --- a/plugins/Dropbox/src/dropbox_utils.cpp +++ b/plugins/Dropbox/src/dropbox_utils.cpp @@ -1,13 +1,5 @@ #include "common.h" -HANDLE CDropbox::CreateProtoServiceFunctionObj(const char *szService, MIRANDASERVICEOBJ serviceProc, void *obj) -{ - char str[MAXMODULELABELLENGTH]; - mir_snprintf(str, sizeof(str), "%s%s", MODULE, szService); - str[MAXMODULELABELLENGTH - 1] = 0; - return CreateServiceFunctionObj(str, serviceProc, obj); -} - wchar_t *CDropbox::HttpStatusToText(HTTP_STATUS status) { switch (status) @@ -35,27 +27,19 @@ wchar_t *CDropbox::HttpStatusToText(HTTP_STATUS status) return L"Unknown"; } -void CDropbox::ShowNotification(const wchar_t *caption, const wchar_t *message, int flags, MCONTACT hContact) +int CDropbox::HandleHttpResponseError(HANDLE hNetlibUser, NETLIBHTTPREQUEST *response) { - if (Miranda_Terminated()) return; - - if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1)) + if (!response) { - POPUPDATAW ppd = {0}; - ppd.lchContact = hContact; - wcsncpy(ppd.lpwzContactName, caption, MAX_CONTACTNAME); - wcsncpy(ppd.lpwzText, message, MAX_SECONDLINE); - ppd.lchIcon = Skin_GetIcon("Skype_main"); - - if (!PUAddPopupW(&ppd)) - return; - + Netlib_Logf(hNetlibUser, "%s: %s", MODULE, "Server does not respond"); + return ACKRESULT_FAILED; } - MessageBox(NULL, message, caption, MB_OK | flags); -} + if (response->resultCode != HTTP_STATUS_OK) + { + Netlib_Logf(hNetlibUser, "%s: %s", MODULE, HttpStatusToText((HTTP_STATUS)response->resultCode)); + return response->resultCode; + } -void CDropbox::ShowNotification(const wchar_t *message, int flags, MCONTACT hContact) -{ - ShowNotification(TranslateT(MODULE), message, flags, hContact); + return 0; } \ No newline at end of file diff --git a/plugins/Dropbox/src/file_transfer.h b/plugins/Dropbox/src/file_transfer.h index a4d76b548b..9dbaf97073 100644 --- a/plugins/Dropbox/src/file_transfer.h +++ b/plugins/Dropbox/src/file_transfer.h @@ -7,23 +7,22 @@ struct FileTransferParam { HANDLE hProcess; MCONTACT hContact; - CDropbox *instance; PROTOFILETRANSFERSTATUS pfts; int totalFolders; - char **pszFolders; + wchar_t **pwszFolders; int relativePathStart; - FileTransferParam(CDropbox *instance) - { - this->instance = instance; + bool withVisualisation; + FileTransferParam() + { totalFolders = 0; - pszFolders = NULL; + pwszFolders = NULL; relativePathStart = 0; pfts.cbSize = sizeof(this->pfts); - pfts.flags = PFTS_UTF; + pfts.flags = PFTS_UNICODE; pfts.currentFileNumber = 0; pfts.currentFileProgress = 0; pfts.currentFileSize = 0; @@ -43,16 +42,16 @@ struct FileTransferParam { if (pfts.pszFiles[i]) mir_free(pfts.pszFiles[i]); } - delete pfts.pszFiles; + mir_free(pfts.pszFiles); } - if (pszFolders) + if (pwszFolders) { - for (int i = 0; pszFolders[i]; i++) + for (int i = 0; pwszFolders[i]; i++) { - if (pszFolders[i]) mir_free(pszFolders[i]); + if (pwszFolders[i]) mir_free(pwszFolders[i]); } - delete pszFolders; + mir_free(pwszFolders); } } }; diff --git a/plugins/Dropbox/src/version.h b/plugins/Dropbox/src/version.h index 0c0f63219b..567c783738 100644 --- a/plugins/Dropbox/src/version.h +++ b/plugins/Dropbox/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 11 #define __RELEASE_NUM 0 -#define __BUILD_NUM 2 +#define __BUILD_NUM 3 #include diff --git a/plugins/ExternalAPI/m_dropbox.h b/plugins/ExternalAPI/m_dropbox.h index 5077f488af..a4ff665006 100644 --- a/plugins/ExternalAPI/m_dropbox.h +++ b/plugins/ExternalAPI/m_dropbox.h @@ -3,16 +3,19 @@ //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 +//lParam = (LPARAM)(const wchar_t*)path - full path to file +// returns file htansfer handle or NULL on failure +// returns immediately, without waiting for the send #define MS_DROPBOX_SEND_FILE "Dropbox/Send/File" -//upload file on Dropbox -//wParam = (MCONTACT)hContact -//lParam = (LPARAM)(const wchar_t*)wszPath -//returns 0 on success or nonzero on failure -//returns immediately, before the file or folder is uploaded -#define MS_DROPBOX_SEND_FILEW "Dropbox/Send/FileW" +// notifies a caller about file send end +// wParam = (MCONTACT)hContact +// lParam = (LPARAM)(const wchar_t*)url - "\r\n" separated download link to file +#define ME_DROPBOX_SEND_SUCCEEDED "Dropbox/Send/Succeeded" + +// notifies a caller about file send failure +// wParam = (MCONTACT)hContact +// lParam = (LPARAM)(HANDLE)hProcess +#define ME_DROPBOX_SEND_FAILED "Dropbox/Send/Failed" #endif //M_DROPBOX_H_ \ No newline at end of file -- cgit v1.2.3