From 488f93815d3c247376f038377e7bc3731b074231 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Mon, 11 May 2015 20:12:46 +0000 Subject: Dropbox: work commit git-svn-id: http://svn.miranda-ng.org/main/trunk@13556 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dropbox/src/dropbox_transfers.cpp | 334 ++++++++++++++---------------- 1 file changed, 157 insertions(+), 177 deletions(-) (limited to 'plugins/Dropbox/src/dropbox_transfers.cpp') diff --git a/plugins/Dropbox/src/dropbox_transfers.cpp b/plugins/Dropbox/src/dropbox_transfers.cpp index de361d853e..a38a806fe2 100644 --- a/plugins/Dropbox/src/dropbox_transfers.cpp +++ b/plugins/Dropbox/src/dropbox_transfers.cpp @@ -1,26 +1,26 @@ #include "stdafx.h" -int CDropbox::SendFile(const char *fileName, const char *data, int length) +/*void CDropbox::SendFile(const char *fileName, const char *data, int length) { - CMStringA url(FORMAT, DROPBOX_APICONTENT_URL "/files_put/%s/%s", DROPBOX_API_ROOT, ptrA(mir_utf8encode(fileName))); - url.Replace('\\', '/'); +CMStringA url(FORMAT, DROPBOX_APICONTENT_URL "/files_put/%s/%s", DROPBOX_API_ROOT, ptrA(mir_utf8encode(fileName))); +url.Replace('\\', '/'); - 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; +HttpRequest *request = new HttpRequest(hNetlibConnection, 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()); +mir_ptr response(request->Send()); - delete request; +delete request; - return HandleHttpResponseError(hNetlibUser, response); -} +HandleHttpResponseError(hNetlibConnection, response); +}*/ -int CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, size_t &offset) +void CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, size_t &offset) { - HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_PUT, DROPBOX_APICONTENT_URL "/chunked_upload"); + HttpRequest *request = new HttpRequest(hNetlibConnection, 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); @@ -31,26 +31,25 @@ int CDropbox::SendFileChunkedFirst(const char *data, int length, char *uploadId, delete request; - if (response && response->resultCode == HTTP_STATUS_OK) { - JSONROOT root(response->pData); - if (root) { - JSONNODE *node = json_get(root, "upload_id"); - strcpy(uploadId, mir_u2a(json_as_string(node))); + HandleHttpResponseError(response); - node = json_get(root, "offset"); - offset = json_as_int(node); - } - } + JSONROOT root(response->pData); + if (root) + { + JSONNODE *node = json_get(root, "upload_id"); + strcpy(uploadId, mir_u2a(json_as_string(node))); - return HandleHttpResponseError(hNetlibUser, response); + node = json_get(root, "offset"); + offset = json_as_int(node); + } } -int CDropbox::SendFileChunkedNext(const char *data, int length, const char *uploadId, size_t &offset) +void CDropbox::SendFileChunkedNext(const char *data, int length, const char *uploadId, size_t &offset) { CMStringA url(DROPBOX_APICONTENT_URL "/chunked_upload"); url.AppendFormat("?upload_id=%s&offset=%i", uploadId, offset); - HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_PUT, url); + HttpRequest *request = new HttpRequest(hNetlibConnection, 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); @@ -61,25 +60,24 @@ int CDropbox::SendFileChunkedNext(const char *data, int length, const char *uplo delete request; - if (response && response->resultCode == HTTP_STATUS_OK) { - JSONROOT root(response->pData); - if (root) { - JSONNODE *node = json_get(root, "offset"); - offset = json_as_int(node); - } - } + HandleHttpResponseError(response); - return HandleHttpResponseError(hNetlibUser, response); + JSONROOT root(response->pData); + if (root) + { + JSONNODE *node = json_get(root, "offset"); + offset = json_as_int(node); + } } -int CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId) +void CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId) { CMStringA url(FORMAT, "%s/commit_chunked_upload/%s/%s", DROPBOX_APICONTENT_URL, DROPBOX_API_ROOT, fileName); url.Replace('\\', '/'); CMStringA param = CMStringA("upload_id=") + uploadId; - HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, url); + HttpRequest *request = new HttpRequest(hNetlibConnection, REQUEST_POST, url); request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); request->AddHeader("Content-Type", "application/x-www-form-urlencoded"); request->pData = mir_strdup(param); @@ -89,17 +87,17 @@ int CDropbox::SendFileChunkedLast(const char *fileName, const char *uploadId) delete request; - return HandleHttpResponseError(hNetlibUser, response); + HandleHttpResponseError(response); } -int CDropbox::CreateFolder(const char *folderName) +void CDropbox::CreateFolder(const char *folderName) { CMStringA folder(folderName); folder.Replace('\\', '/'); CMStringA param(FORMAT, "root=%s&path=%s", DROPBOX_API_ROOT, folder); - HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, DROPBOX_API_URL "/fileops/create_folder"); + HttpRequest *request = new HttpRequest(hNetlibConnection, REQUEST_POST, DROPBOX_API_URL "/fileops/create_folder"); request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); request->AddHeader("Content-Type", "application/x-www-form-urlencoded"); request->pData = mir_strdup(param); @@ -111,12 +109,12 @@ int CDropbox::CreateFolder(const char *folderName) // forder exists on server if (response->resultCode == HTTP_STATUS_FORBIDDEN) - return 0; + return; - return HandleHttpResponseError(hNetlibUser, response); + HandleHttpResponseError(response); } -int CDropbox::CreateDownloadUrl(const char *path, wchar_t *url) +void CDropbox::CreateDownloadUrl(const char *path, char *url) { CMStringA api_url(DROPBOX_API_URL); api_url.AppendFormat("/shares/%s/%s", DROPBOX_API_ROOT, path); @@ -124,151 +122,124 @@ int CDropbox::CreateDownloadUrl(const char *path, wchar_t *url) if (!db_get_b(NULL, MODULE, "UseSortLinks", 1)) api_url += "?short_url=false"; - HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_POST, api_url); + HttpRequest *request = new HttpRequest(hNetlibConnection, REQUEST_POST, api_url); request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret")); mir_ptr response(request->Send()); delete request; - if (response && response->resultCode == HTTP_STATUS_OK) { - JSONROOT root(response->pData); - if (root) { - JSONNODE *node = json_get(root, "url"); - wcscpy(url, json_as_string(node)); - } - } + HandleHttpResponseError(response); - return HandleHttpResponseError(hNetlibUser, response); + JSONROOT root(response->pData); + if (root) + { + JSONNODE *node = json_get(root, "url"); + mir_strcpy(url, _T2A(json_as_string(node))); + } } UINT CDropbox::SendFilesAsync(void *owner, void *arg) { - bool error = false; CDropbox *instance = (CDropbox*)owner; FileTransferParam *ftp = (FileTransferParam*)arg; ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ftp->hProcess, 0); - if (ftp->pwszFolders) { - for (int i = 0; ftp->pwszFolders[i]; i++) { - ptrA utf8_folderName(mir_utf8encodeW(ftp->pwszFolders[i])); - - if (!instance->CreateFolder(utf8_folderName)) { - if (!strchr(utf8_folderName, '\\')) { - wchar_t url[MAX_PATH]; - if (!instance->CreateDownloadUrl(utf8_folderName, url)) - ftp->AddUrl(url); - else { - error = true; - break; - } + try + { + if (ftp->pwszFolders) + { + for (int i = 0; ftp->pwszFolders[i]; i++) + { + ptrA utf8_folderName(mir_utf8encodeW(ftp->pwszFolders[i])); + + instance->CreateFolder(utf8_folderName); + if (!strchr(utf8_folderName, '\\')) + { + char url[MAX_PATH]; + instance->CreateDownloadUrl(utf8_folderName, url); + ftp->AddUrl(url); } } - else { - error = true; - break; - } } - } - if (!error) { - for (int i = 0; ftp->pfts.pwszFiles[i]; i++) { - FILE *file = _wfopen(ftp->pfts.pwszFiles[i], L"rb"); - if (file) { - const wchar_t *fileName = NULL; - if (!ftp->relativePathStart) - fileName = wcsrchr(ftp->pfts.pwszFiles[i], L'\\') + 1; + for (int i = 0; ftp->pfts.ptszFiles[i]; i++) + { + FILE *hFile = _tfopen(ftp->pfts.ptszFiles[i], _T("rb")); + if (hFile == NULL) + throw TransferException("Unable to open file"); + + const TCHAR *fileName = NULL; + if (!ftp->relativePathStart) + fileName = _tcsrchr(ftp->pfts.ptszFiles[i], L'\\') + 1; + else + fileName = &ftp->pfts.ptszFiles[i][ftp->relativePathStart]; + + _fseeki64(hFile, 0, SEEK_END); + uint64_t fileSize = _ftelli64(hFile); + rewind(hFile); + + ftp->pfts.currentFileNumber = i; + ftp->pfts.currentFileSize = fileSize; + ftp->pfts.currentFileProgress = 0; + ftp->pfts.wszCurrentFile = wcsrchr(ftp->pfts.ptszFiles[i], '\\') + 1; + + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); + + // + size_t offset = 0; + char *uploadId = new char[32]; + + 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; + + while (!feof(hFile) && fileSize != offset) + { + if (ferror(hFile)) + throw TransferException("Error while file sending"); + + char *data = new char[chunkSize + 1]; + int count = (int)fread(data, sizeof(char), chunkSize, hFile); + + if (offset == 0) + instance->SendFileChunkedFirst(data, count, uploadId, offset); else - fileName = &ftp->pfts.pwszFiles[i][ftp->relativePathStart]; - - fseek(file, 0, SEEK_END); - size_t fileSize = ftell(file); - fseek(file, 0, SEEK_SET); + instance->SendFileChunkedNext(data, count, uploadId, offset); - ftp->pfts.currentFileNumber = i; - ftp->pfts.currentFileSize = fileSize; - ftp->pfts.currentFileProgress = 0; - ftp->pfts.wszCurrentFile = wcsrchr(ftp->pfts.pwszFiles[i], '\\') + 1; + ftp->pfts.currentFileProgress += count; + ftp->pfts.totalProgress += count; ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); + } - // - size_t offset = 0; - char *uploadId = new char[32]; - - 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; - - while (!feof(file) && fileSize != offset) { - if (ferror(file)) { - error = true; - break; - } - - 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(hFile); - ftp->pfts.currentFileProgress += count; - ftp->pfts.totalProgress += count; + ptrA utf8_fileName(mir_utf8encodeW(fileName)); - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftp->hProcess, (LPARAM)&ftp->pfts); - } + instance->SendFileChunkedLast(utf8_fileName, uploadId); - fclose(file); + if (!_tcschr(fileName, L'\\')) + { + char url[MAX_PATH]; + instance->CreateDownloadUrl(utf8_fileName, url); + ftp->AddUrl(url); + } - if (!error) { - ptrA utf8_fileName(mir_utf8encodeW(fileName)); + ftp->pfts.currentFileProgress = ftp->pfts.currentFileSize; - if (instance->SendFileChunkedLast(utf8_fileName, uploadId)) { - error = true; - break; - } - else { - if (!wcschr(fileName, L'\\')) { - wchar_t url[MAX_PATH]; - if (!instance->CreateDownloadUrl(utf8_fileName, url)) - ftp->AddUrl(url); - else { - error = true; - break; - } - } - - ftp->pfts.currentFileProgress = ftp->pfts.currentFileSize; - - if (i < ftp->pfts.totalFiles - 1) - ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ftp->hProcess, 0); - } - } - } - else { - error = true; - break; - } + if (i < ftp->pfts.totalFiles - 1) + ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ftp->hProcess, 0); } } - - if (error) { + catch (TransferException &ex) + { + Netlib_Logf(instance->hNetlibConnection, "%s: %s", MODULE, ex.what()); ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ftp->hProcess, 0); - - return 1; + return 0; } ProtoBroadcastAck(MODULE, ftp->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftp->hProcess, 0); @@ -282,53 +253,62 @@ UINT CDropbox::SendFilesAndReportAsync(void *owner, void *arg) FileTransferParam *ftp = (FileTransferParam*)arg; int res = SendFilesAsync(owner, arg); - if (!res) { - 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) { + if (!res) + { + CMStringA urls; + for (int i = 0; ftp->urlList.getCount(); i++) + urls.AppendFormat("%s\r\n", ftp->urlList[i]); + char *data = urls.GetBuffer(); + + if (db_get_b(NULL, MODULE, "UrlAutoSend", 1)) + { + char *message = mir_utf8encode(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 = (int)wcslen(data); + dbei.cbBlob = (int)mir_strlen(data); dbei.pBlob = (PBYTE)message; db_event_add(ftp->hContact, &dbei); } else CallServiceSync(MS_MSG_SENDMESSAGEW, (WPARAM)ftp->hContact, (LPARAM)data); } - else { + else + { DBEVENTINFO dbei = { sizeof(dbei) }; dbei.flags = DBEF_UTF; dbei.szModule = MODULE; dbei.timestamp = time(NULL); dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = (int)wcslen(data); + dbei.cbBlob = (int)mir_strlen(data); dbei.pBlob = (PBYTE)message; db_event_add(ftp->hContact, &dbei); } } if (db_get_b(NULL, MODULE, "UrlPasteToMessageInputArea", 0)) - CallServiceSync(MS_MSG_SENDMESSAGEW, (WPARAM)ftp->hContact, (LPARAM)data); + CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM)ftp->hContact, (LPARAM)data); - if (db_get_b(NULL, MODULE, "UrlCopyToClipboard", 0)) { - if (OpenClipboard(NULL)) { + if (db_get_b(NULL, MODULE, "UrlCopyToClipboard", 0)) + { + if (OpenClipboard(NULL)) + { EmptyClipboard(); - size_t size = sizeof(wchar_t) * (urls.GetLength() + 1); + size_t size = sizeof(TCHAR) * (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); + if (hClipboardData) + { + TCHAR *pchData = (TCHAR*)GlobalLock(hClipboardData); + if (pchData) + { + memcpy(pchData, (TCHAR*)data, size); GlobalUnlock(hClipboardData); - SetClipboardData(CF_UNICODETEXT, hClipboardData); + SetClipboardData(CF_TEXT, hClipboardData); } } CloseClipboard(); @@ -351,7 +331,7 @@ UINT CDropbox::SendFilesAndEventAsync(void *owner, void *arg) TRANSFERINFO ti = { 0 }; ti.hProcess = ftp->hProcess; ti.status = res; - ti.data = ftp->pwszUrls; + ti.data = ftp->urlList.getArray(); NotifyEventHooks(instance->hFileSentEventHook, ftp->hContact, (LPARAM)&ti); -- cgit v1.2.3